1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LLVM_LICENSE_HEADER@
5 */
6
7// TEST_CONFIG rdar://6214670
8// TEST_CFLAGS -framework Foundation
9
10#import <objc/objc-auto.h>
11#import <Foundation/Foundation.h>
12#import <Block.h>
13#import "test.h"
14
15int constructors = 0;
16int destructors = 0;
17
18
19#import <Block_private.h>
20
21void hack(void *block) {
22    printf("Block_dump says: %s\n", _Block_dump(block));
23}
24
25#define CONST const
26
27class TestObject
28{
29public:
30	TestObject(CONST TestObject& inObj);
31	TestObject();
32	~TestObject();
33
34	TestObject& operator=(CONST TestObject& inObj);
35
36	int version() CONST { return _version; }
37private:
38	mutable int _version;
39};
40
41TestObject::TestObject(CONST TestObject& inObj)
42
43{
44        ++constructors;
45        _version = inObj._version;
46	//printf("%p (%d) -- TestObject(const TestObject&) called\n", this, _version);
47}
48
49
50TestObject::TestObject()
51{
52        _version = ++constructors;
53	//printf("%p (%d) -- TestObject() called\n", this, _version);
54}
55
56
57TestObject::~TestObject()
58{
59	//printf("%p -- ~TestObject() called\n", this);
60        ++destructors;
61}
62
63
64TestObject& TestObject::operator=(CONST TestObject& inObj)
65{
66	//printf("%p -- operator= called\n", this);
67        _version = inObj._version;
68	return *this;
69}
70
71
72void testRoutine() {
73    TestObject one;
74
75    void (^b)(void) = [^{ printf("my copy of one is %d\n", one.version()); } copy];
76#if 0
77// just try one copy, one release
78    for (int i = 0; i < 10; ++i)
79        [b retain];
80    for (int i = 0; i < 10; ++i)
81        [b release];
82    for (int i = 0; i < 10; ++i)
83        Block_copy(b);
84    for (int i = 0; i < 10; ++i)
85        Block_release(b);
86#endif
87    //hack(^{ printf("my copy of one is %d\n", one.version()); });
88    //hack(b);
89    [b release];
90}
91
92int main() {
93    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
94    //testGC();
95    for (int i = 0; i < 200; ++i)   // do enough to trigger TLC if GC is on
96        testRoutine();
97    objc_collect(OBJC_EXHAUSTIVE_COLLECTION | OBJC_WAIT_UNTIL_DONE);
98    [pool drain];
99
100    if (constructors != destructors) {
101        fail("didn't recover %d const copies", constructors - destructors);
102    }
103
104    succeed(__FILE__);
105}
106