the controlling plans so that they don't lose control. Also change "ThreadPlanStepThrough" to take the return StackID for its backstop breakpoint as an argument to the constructor rather than having it try to figure it out itself, since it might get it wrong whereas the caller always knows where it is coming from. rdar://problem/11402287 llvm-svn: 156529
139 lines
3.1 KiB
Objective-C
139 lines
3.1 KiB
Objective-C
#import <Foundation/Foundation.h>
|
|
#include <stdio.h>
|
|
|
|
struct return_me
|
|
{
|
|
int first;
|
|
int second;
|
|
};
|
|
|
|
@interface SourceBase: NSObject
|
|
{
|
|
struct return_me my_return;
|
|
}
|
|
- (SourceBase *) initWithFirst: (int) first andSecond: (int) second;
|
|
- (void) randomMethod;
|
|
- (struct return_me) returnsStruct;
|
|
@end
|
|
|
|
@implementation SourceBase
|
|
- (void) randomMethod
|
|
{
|
|
printf ("Called in SourceBase version of randomMethod.\n"); // SourceBase randomMethod start line.
|
|
}
|
|
|
|
- (struct return_me) returnsStruct
|
|
{
|
|
return my_return; // SourceBase returnsStruct start line.
|
|
}
|
|
|
|
- (SourceBase *) initWithFirst: (int) first andSecond: (int) second
|
|
{
|
|
my_return.first = first;
|
|
my_return.second = second;
|
|
|
|
return self;
|
|
}
|
|
@end
|
|
|
|
@interface Source : SourceBase
|
|
{
|
|
int _property;
|
|
}
|
|
- (void) setProperty: (int) newValue;
|
|
- (void) randomMethod;
|
|
- (struct return_me) returnsStruct;
|
|
@end
|
|
|
|
@implementation Source
|
|
- (void) setProperty: (int) newValue
|
|
{
|
|
_property = newValue;
|
|
}
|
|
|
|
- (void) randomMethod
|
|
{
|
|
[super randomMethod]; // Source randomMethod start line.
|
|
printf ("Called in Source version of random method.");
|
|
}
|
|
|
|
- (struct return_me) returnsStruct
|
|
{
|
|
printf ("Called in Source version of returnsStruct.\n"); // Source returnsStruct start line.
|
|
return [super returnsStruct]; // Source returnsStruct call line.
|
|
}
|
|
|
|
@end
|
|
|
|
@interface Observer : NSObject
|
|
{
|
|
Source *_source;
|
|
}
|
|
+ (Observer *) observerWithSource: (Source *) source;
|
|
- (Observer *) initWithASource: (Source *) source;
|
|
- (void) observeValueForKeyPath: (NSString *) path
|
|
ofObject: (id) object
|
|
change: (NSDictionary *) change
|
|
context: (void *) context;
|
|
@end
|
|
|
|
@implementation Observer
|
|
|
|
+ (Observer *) observerWithSource: (Source *) inSource;
|
|
{
|
|
Observer *retval;
|
|
|
|
retval = [[Observer alloc] initWithASource: inSource];
|
|
return retval;
|
|
}
|
|
|
|
- (Observer *) initWithASource: (Source *) source
|
|
{
|
|
[super init];
|
|
_source = source;
|
|
[_source addObserver: self
|
|
forKeyPath: @"property"
|
|
options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
|
|
context: NULL];
|
|
return self;
|
|
}
|
|
|
|
- (void) observeValueForKeyPath: (NSString *) path
|
|
ofObject: (id) object
|
|
change: (NSDictionary *) change
|
|
context: (void *) context
|
|
{
|
|
printf ("Observer function called.\n");
|
|
return;
|
|
}
|
|
@end
|
|
|
|
int main ()
|
|
{
|
|
Source *mySource;
|
|
Observer *myObserver;
|
|
struct return_me ret_val;
|
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
mySource = [[Source alloc] init];
|
|
|
|
[mySource randomMethod]; // Set first breakpoint here.
|
|
ret_val = [mySource returnsStruct]; // Set second breakpoint here.
|
|
|
|
myObserver = [Observer observerWithSource: mySource];
|
|
|
|
[mySource randomMethod]; // Set third breakpoint here.
|
|
ret_val = [mySource returnsStruct]; // Set fourth breakpoint here.
|
|
[mySource setProperty: 5]; // Set fifth breakpoint here.
|
|
|
|
// We also had a bug where stepping into a method dispatch to nil turned
|
|
// into continue. So make sure that works here:
|
|
|
|
mySource = nil;
|
|
[mySource randomMethod]; // Set nil step breakpoint here.
|
|
[pool release]; // Step over nil should stop here.
|
|
return 0;
|
|
|
|
}
|