summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2015-07-07 03:57:35 +0000
committerDouglas Gregor <dgregor@apple.com>2015-07-07 03:57:35 +0000
commite9d95f1ecc98ced831cace8b4b78cb7cc380f4aa (patch)
tree73962adb18c3f8c191701021f69a14b4121676e6 /clang/test
parent85f3f9513dbc88b9898d022a1a55a03d55612721 (diff)
downloadbcm5719-llvm-e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa.tar.gz
bcm5719-llvm-e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa.zip
Handle Objective-C type arguments.
Objective-C type arguments can be provided in angle brackets following an Objective-C interface type. Syntactically, this is the same position as one would provide protocol qualifiers (e.g., id<NSCopying>), so parse both together and let Sema sort out the ambiguous cases. This applies both when parsing types and when parsing the superclass of an Objective-C class, which can now be a specialized type (e.g., NSMutableArray<T> inherits from NSArray<T>). Check Objective-C type arguments against the type parameters of the corresponding class. Verify the length of the type argument list and that each type argument satisfies the corresponding bound. Specializations of parameterized Objective-C classes are represented in the type system as distinct types. Both specialized types (e.g., NSArray<NSString *> *) and unspecialized types (NSArray *) are represented, separately. llvm-svn: 241542
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Index/annotate-parameterized-classes.m42
-rw-r--r--clang/test/Index/complete-method-decls.m3
-rw-r--r--clang/test/PCH/objc_parameterized_classes.m4
-rw-r--r--clang/test/Parser/objcxx11-protocol-in-template.mm7
-rw-r--r--clang/test/SemaObjC/interface-1.m2
-rw-r--r--clang/test/SemaObjC/parameterized_classes.m147
-rw-r--r--clang/test/SemaObjCXX/parameterized_classes.mm26
7 files changed, 215 insertions, 16 deletions
diff --git a/clang/test/Index/annotate-parameterized-classes.m b/clang/test/Index/annotate-parameterized-classes.m
new file mode 100644
index 00000000000..6a53fed4bd7
--- /dev/null
+++ b/clang/test/Index/annotate-parameterized-classes.m
@@ -0,0 +1,42 @@
+@protocol NSObject
+@end
+
+@interface NSObject
+@end
+
+@interface A<T : id, U : NSObject *> : NSObject
+@end
+
+@interface A<T : id, U : NSObject *> (Cat1)
+@end
+
+typedef A<id<NSObject>, NSObject *> ASpecialization1;
+
+@interface B<T : id, U : NSObject *> : A<T, U>
+@end
+
+// 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
+// CHECK-INTERFACE-DECL: Identifier: "T" [7:14 - 7:15] TemplateTypeParameter=T:7:14
+// FIXME: Should be a type reference
+// CHECK-INTERFACE-DECL: Identifier: "id" [7:18 - 7:20] TemplateTypeParameter=T:7:14
+// CHECK-INTERFACE-DECL: Identifier: "U" [7:22 - 7:23] TemplateTypeParameter=U:7:22
+// FIXME: Should be a class reference
+// CHECK-INTERFACE-DECL: Identifier: "NSObject" [7:26 - 7:34] TemplateTypeParameter=U:7:22
+
+// 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
+// CHECK-CATEGORY-DECL: Identifier: "T" [10:14 - 10:15] TemplateTypeParameter=T:10:14
+// FIXME: Should be a type reference
+// CHECK-CATEGORY-DECL: Identifier: "id" [10:18 - 10:20] TemplateTypeParameter=T:10:14
+// CHECK-CATEGORY-DECL: Identifier: "U" [10:22 - 10:23] TemplateTypeParameter=U:10:22
+// FIXME: Should be a class reference
+// CHECK-CATEGORY-DECL: Identifier: "NSObject" [10:26 - 10:34] TemplateTypeParameter=U:10:22
+
+// 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
+// CHECK-SPECIALIZATION: Identifier: "id" [13:11 - 13:13] TypeRef=id:0:0
+// CHECK-SPECIALIZATION: Identifier: "NSObject" [13:14 - 13:22] ObjCProtocolRef=NSObject:1:11
+// CHECK-SPECIALIZATION: Identifier: "NSObject" [13:25 - 13:33] ObjCClassRef=NSObject:4:12
+
+// 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
+// CHECK-SUPER: Identifier: "A" [15:40 - 15:41] ObjCSuperClassRef=A:7:12
+// CHECK-SUPER: Identifier: "T" [15:42 - 15:43] TypeRef=T:15:14
+// CHECK-SUPER: Identifier: "U" [15:45 - 15:46] TypeRef=U:15:22
diff --git a/clang/test/Index/complete-method-decls.m b/clang/test/Index/complete-method-decls.m
index 0e3780ba3d5..a74020a5ed8 100644
--- a/clang/test/Index/complete-method-decls.m
+++ b/clang/test/Index/complete-method-decls.m
@@ -208,8 +208,7 @@ typedef A *MyObjectRef;
// RUN: c-index-test -code-completion-at=%s:85:2 %s | FileCheck -check-prefix=CHECK-CLASSTY %s
// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text Class<P1>}{RightParen )}{TypedText meth}
-// FIXME: It should be "MyObject <P1> *""
-// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text A<P1> *}{RightParen )}{TypedText meth2}
+// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text MyObject<P1> *}{RightParen )}{TypedText meth2}
// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text MyObjectRef}{RightParen )}{TypedText meth3}
// RUN: c-index-test -code-completion-at=%s:93:2 %s | FileCheck -check-prefix=CHECK-NULLABILITY %s
diff --git a/clang/test/PCH/objc_parameterized_classes.m b/clang/test/PCH/objc_parameterized_classes.m
index a541c33fbf2..f4fd0926be3 100644
--- a/clang/test/PCH/objc_parameterized_classes.m
+++ b/clang/test/PCH/objc_parameterized_classes.m
@@ -19,6 +19,8 @@ __attribute__((objc_root_class))
@interface PC1<T, U : NSObject *> (Cat1)
@end
+typedef PC1<id, NSObject *> PC1Specialization1;
+
#else
@interface PC1<T : NSObject *, // expected-error{{type bound 'NSObject *' for type parameter 'T' conflicts with implicit bound 'id}}
@@ -27,4 +29,6 @@ __attribute__((objc_root_class))
// expected-note@15{{type parameter 'U' declared here}}
@end
+typedef PC1Specialization1<id, NSObject *> PC1Specialization2; // expected-error{{type arguments cannot be applied to already-specialized class type 'PC1Specialization1' (aka 'PC1<id,NSObject *>')}}
+
#endif
diff --git a/clang/test/Parser/objcxx11-protocol-in-template.mm b/clang/test/Parser/objcxx11-protocol-in-template.mm
index 8cb499396d4..c5c3b6c75a4 100644
--- a/clang/test/Parser/objcxx11-protocol-in-template.mm
+++ b/clang/test/Parser/objcxx11-protocol-in-template.mm
@@ -4,12 +4,7 @@
template<class T> class vector {};
@protocol P @end
-#if __cplusplus >= 201103L
- // expected-no-diagnostics
-#else
- // expected-error@14{{a space is required between consecutive right angle brackets}}
- // expected-error@15{{a space is required between consecutive right angle brackets}}
-#endif
+// expected-no-diagnostics
vector<id<P>> v;
vector<vector<id<P>>> v2;
diff --git a/clang/test/SemaObjC/interface-1.m b/clang/test/SemaObjC/interface-1.m
index 79fbad8ba4b..0e47fa08bd7 100644
--- a/clang/test/SemaObjC/interface-1.m
+++ b/clang/test/SemaObjC/interface-1.m
@@ -3,7 +3,7 @@
@interface NSWhatever :
NSObject // expected-error {{cannot find interface declaration for 'NSObject'}}
-<NSCopying> // expected-error {{cannot find protocol declaration for 'NSCopying'}}
+<NSCopying> // expected-error {{no type or protocol named 'NSCopying'}}
@end
diff --git a/clang/test/SemaObjC/parameterized_classes.m b/clang/test/SemaObjC/parameterized_classes.m
index e6eae442142..bf81ad9a078 100644
--- a/clang/test/SemaObjC/parameterized_classes.m
+++ b/clang/test/SemaObjC/parameterized_classes.m
@@ -1,13 +1,16 @@
-// RUN: %clang_cc1 %s -verify
+// RUN: %clang_cc1 -fblocks %s -verify
-@protocol NSObject
+@protocol NSObject // expected-note{{'NSObject' declared here}}
+@end
+
+@protocol NSCopying // expected-note{{'NSCopying' declared here}}
@end
__attribute__((objc_root_class))
@interface NSObject <NSObject> // expected-note{{'NSObject' defined here}}
@end
-@interface NSString : NSObject
+@interface NSString : NSObject <NSCopying>
@end
// --------------------------------------------------------------------------
@@ -15,13 +18,14 @@ __attribute__((objc_root_class))
// --------------------------------------------------------------------------
// Parse type parameters with a bound
-@interface PC1<T, U : NSObject*> : NSObject
+@interface PC1<T, U : NSObject*> : NSObject // expected-note{{'PC1' declared here}}
// expected-note@-1{{type parameter 'T' declared here}}
// expected-note@-2{{type parameter 'U' declared here}}
+// expected-note@-3{{type parameter 'U' declared here}}
@end
// Parse a type parameter with a bound that terminates in '>>'.
-@interface PC2<T : id<NSObject>> : NSObject // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+@interface PC2<T : id<NSObject>> : NSObject
@end
// Parse multiple type parameters.
@@ -29,11 +33,11 @@ __attribute__((objc_root_class))
@end
// Parse multiple type parameters--grammatically ambiguous with protocol refs.
-@interface PC4<T, U, V> : NSObject
+@interface PC4<T, U, V> : NSObject // expected-note 2{{'PC4' declared here}}
@end
// Parse a type parameter list without a superclass.
-@interface PC5<T : id> // expected-error{{parameterized Objective-C class 'PC5' must have a superclass}}
+@interface PC5<T : id>
@end
// Parse a type parameter with name conflicts.
@@ -92,6 +96,7 @@ __attribute__((objc_root_class))
// Parameterized forward declaration a class that is not parameterized.
@class NSObject<T>; // expected-error{{forward declaration of non-parameterized class 'NSObject' cannot have type parameters}}
+// expected-note@-1{{'NSObject' declared here}}
// Parameterized forward declaration preceding the definition (that is
// not parameterized).
@@ -190,3 +195,131 @@ void test_PC20_unspecialized(PC20 *pc20) {
ip = [pc20 extMethod: 0]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'X' (aka 'id')}}
[pc20 extMethod: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'Y' (aka 'NSObject *')}}
}
+
+// --------------------------------------------------------------------------
+// Parsing type arguments.
+// --------------------------------------------------------------------------
+
+typedef NSString * ObjCStringRef; // expected-note{{'ObjCStringRef' declared here}}
+
+// Type arguments with a mix of identifiers and type-names.
+typedef PC4<id, NSObject *, NSString *> typeArgs1;
+
+// Type arguments with only identifiers.
+typedef PC4<id, id, id> typeArgs2;
+
+// Type arguments with only identifiers; one is ambiguous (resolved as
+// types).
+typedef PC4<NSObject, id, id> typeArgs3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}}
+
+// Type arguments with only identifiers; one is ambiguous (resolved as
+// protocol qualifiers).
+typedef PC4<NSObject, NSCopying> protocolQuals1;
+
+// Type arguments and protocol qualifiers.
+typedef PC4<id, NSObject *, id><NSObject, NSCopying> typeArgsAndProtocolQuals1;
+
+// Type arguments and protocol qualifiers in the wrong order.
+typedef PC4<NSObject, NSCopying><id, NSObject *, id> typeArgsAndProtocolQuals2; // expected-error{{protocol qualifiers must precede type arguments}}
+
+// Type arguments and protocol qualifiers (identifiers).
+typedef PC4<id, NSObject, id><NSObject, NSCopying> typeArgsAndProtocolQuals3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}}
+
+// Typo correction: protocol bias.
+typedef PC4<NSCopying, NSObjec> protocolQuals2; // expected-error{{cannot find protocol declaration for 'NSObjec'; did you mean 'NSObject'?}}
+
+// Typo correction: type bias.
+typedef PC4<id, id, NSObjec> typeArgs4; // expected-error{{unknown class name 'NSObjec'; did you mean 'NSObject'?}}
+// expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}}
+
+// Typo correction: bias set by correction itself to a protocol.
+typedef PC4<NSObject, NSObject, NSCopyin> protocolQuals3; // expected-error{{cannot find protocol declaration for 'NSCopyin'; did you mean 'NSCopying'?}}
+
+// Typo correction: bias set by correction itself to a type.
+typedef PC4<NSObject, NSObject, ObjCStringref> typeArgs5; // expected-error{{unknown type name 'ObjCStringref'; did you mean 'ObjCStringRef'?}}
+// expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}}
+// expected-error@-2{{type argument 'NSObject' must be a pointer (requires a '*')}}
+
+// Type/protocol conflict.
+typedef PC4<NSCopying, ObjCStringRef> typeArgsProtocolQualsConflict1; // expected-error{{angle brackets contain both a type ('ObjCStringRef') and a protocol ('NSCopying')}}
+
+// Handling the '>>' in type argument lists.
+typedef PC4<id<NSCopying>, NSObject *, id<NSObject>> typeArgs6;
+
+// --------------------------------------------------------------------------
+// Checking type arguments.
+// --------------------------------------------------------------------------
+
+@interface PC15<T : id, U : NSObject *, V : id<NSCopying>> : NSObject
+// expected-note@-1{{type parameter 'V' declared here}}
+// expected-note@-2{{type parameter 'V' declared here}}
+// expected-note@-3{{type parameter 'U' declared here}}
+@end
+
+typedef PC4<NSString *> tooFewTypeArgs1; // expected-error{{too few type arguments for class 'PC4' (have 1, expected 3)}}
+
+typedef PC4<NSString *, NSString *, NSString *, NSString *> tooManyTypeArgs1; // expected-error{{too many type arguments for class 'PC4' (have 4, expected 3)}}
+
+typedef PC15<int (^)(int, int), // block pointers as 'id'
+ NSString *, // subclass
+ NSString *> typeArgs7; // class that conforms to the protocol
+
+typedef PC15<NSObject *, NSObject *, id<NSCopying>> typeArgs8;
+
+typedef PC15<NSObject *, NSObject *,
+ NSObject *> typeArgs8b; // expected-error{{type argument 'NSObject *' does not satisy the bound ('id<NSCopying>') of type parameter 'V'}}
+
+typedef PC15<id,
+ id, // expected-error{{type argument 'id' does not satisy the bound ('NSObject *') of type parameter 'U'}}
+ id> typeArgs9;
+
+typedef PC15<id, NSObject *,
+ id> typeArgs10; // expected-error{{type argument 'id' does not satisy the bound ('id<NSCopying>') of type parameter 'V'}}
+
+typedef PC15<id,
+ int (^)(int, int), // okay
+ id<NSCopying, NSObject>> typeArgs11;
+
+typedef PC15<id, NSString *, int (^)(int, int)> typeArgs12; // okay
+
+typedef NSObject<id, id> typeArgs13; // expected-error{{type arguments cannot be applied to non-parameterized class 'NSObject'}}
+
+typedef id<id, id> typeArgs14; // expected-error{{type arguments cannot be applied to non-class type 'id'}}
+
+typedef PC1<NSObject *, NSString *> typeArgs15;
+
+typedef PC1<NSObject *, NSString *><NSCopying> typeArgsAndProtocolQuals4;
+
+typedef typeArgs15<NSCopying> typeArgsAndProtocolQuals5;
+
+typedef typeArgs15<NSObject *, NSString *> typeArgs16; // expected-error{{type arguments cannot be applied to already-specialized class type 'typeArgs15' (aka 'PC1<NSObject *,NSString *>')}}
+
+typedef typeArgs15<NSObject> typeArgsAndProtocolQuals6;
+
+void testSpecializedTypePrinting() {
+ int *ip;
+
+ ip = (typeArgs15*)0; // expected-warning{{'typeArgs15 *' (aka 'PC1<NSObject *,NSString *> *')}}
+ ip = (typeArgsAndProtocolQuals4*)0; // expected-warning{{'typeArgsAndProtocolQuals4 *' (aka 'PC1<NSObject *,NSString *><NSCopying> *')}}
+ ip = (typeArgsAndProtocolQuals5*)0; // expected-warning{{'typeArgsAndProtocolQuals5 *' (aka 'typeArgs15<NSCopying> *')}}
+ ip = (typeArgsAndProtocolQuals6)0; // expected-error{{used type 'typeArgsAndProtocolQuals6' (aka 'typeArgs15<NSObject>')}}
+ ip = (typeArgsAndProtocolQuals6*)0;// expected-warning{{'typeArgsAndProtocolQuals6 *' (aka 'typeArgs15<NSObject> *')}}
+}
+
+// --------------------------------------------------------------------------
+// Specialized superclasses
+// --------------------------------------------------------------------------
+@interface PC21<T : NSObject *> : PC1<T, T>
+@end
+
+@interface PC22<T : NSObject *> : PC1<T> // expected-error{{too few type arguments for class 'PC1' (have 1, expected 2)}}
+@end
+
+@interface PC23<T : NSObject *> : PC1<T, U> // expected-error{{unknown type name 'U'}}
+@end
+
+@interface PC24<T> : PC1<T, T> // expected-error{{type argument 'T' (aka 'id') does not satisy the bound ('NSObject *') of type parameter 'U'}}
+@end
+
+@interface NSFoo : PC1<NSObject *, NSObject *> // okay
+@end
diff --git a/clang/test/SemaObjCXX/parameterized_classes.mm b/clang/test/SemaObjCXX/parameterized_classes.mm
new file mode 100644
index 00000000000..48542634bdd
--- /dev/null
+++ b/clang/test/SemaObjCXX/parameterized_classes.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify
+
+// expected-no-diagnostics
+@protocol NSObject
+@end
+
+@protocol NSCopying
+@end
+
+__attribute__((objc_root_class))
+@interface NSObject <NSObject>
+@end
+
+@interface NSString : NSObject
+@end
+
+// --------------------------------------------------------------------------
+// Parsing parameterized classes.
+// --------------------------------------------------------------------------
+@interface PC1<T, U, V> : NSObject
+@end
+
+// --------------------------------------------------------------------------
+// Parsing type arguments.
+// --------------------------------------------------------------------------
+typedef PC1<::NSString *, NSString *, id<NSCopying>> typeArgs1;
OpenPOWER on IntegriCloud