1/* Test if ObjC++ can distinguish protocol qualifiers from
2   template arguments.  */
3/* Author:  Ziemowit Laski <zlaski@apple.com>.  */
4
5/* { dg-do run } */
6/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
7/* { dg-prune-output ".*ld: warning: direct access in.*" } */
8
9#include "../objc-obj-c++-shared/TestsuiteObject.m"
10#include <stdlib.h>
11
12#define CHECK_IF(expr) if(!(expr)) abort()
13
14@protocol Zone
15+ allocFromZone:(void *)zone;
16- copyFromZone:(void *)zone;
17@end
18
19@protocol Init <Zone>
20+ initialize;
21- init;
22@end
23
24@interface Foo: TestsuiteObject
25{ @public int val; }
26- init;
27@end
28
29template <class T, class U> struct X {
30  T x; U y;
31};
32
33X<int, float> xx;
34
35template <typename T> struct Holder
36{
37  T *obj;
38  static int counter;
39  Holder(void) { obj = [[T alloc] init]; }
40  ~Holder(void) { [obj free]; --counter; }
41  id <Init, Zone> getObjId(void) { return obj; }
42  TestsuiteObject <Zone, Init> *getObj(void) { return obj; }
43};
44
45typedef Holder <Foo <Init, Zone> > FooHolder;
46
47@implementation Foo
48-(id) init {
49  [super init];
50  val = ++FooHolder::counter;
51  return self;
52}
53@end
54
55template <typename T>
56int Holder<T>::counter = 0;
57
58int main (void) {
59  CHECK_IF(FooHolder::counter == 0);
60  {
61    FooHolder holder;
62    CHECK_IF(holder.obj->val == 1);
63    CHECK_IF(FooHolder::counter == 1);
64    FooHolder holder2;
65    CHECK_IF(holder2.obj->val == 2);
66    CHECK_IF(FooHolder::counter == 2);
67  }
68  CHECK_IF(FooHolder::counter == 0);
69  return 0;
70}
71
72