/* APPLE LOCAL file radar 5932809 */
/* Test the __byreg runtime features. */
/* { dg-options "-mmacosx-version-min=10.5 -ObjC++ -framework Foundation" { target i?86-*-darwin*  } } */
/* { dg-do run { target i?86-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */

#include <objc/Object.h>
#import <Foundation/Foundation.h>

void * _NSConcreteStackBlock;

int CalledRetain = 0;

extern "C" id objc_msgSend(id target, SEL cmd, ...) {
    printf("[%p %s] called\n", target, sel_getName(cmd));
    if (!strcmp(sel_getName(cmd), "retain")) {
        CalledRetain = 1;
    }
    return target;
}

@interface DumbObject : NSObject {
}
@end
id newDumbObject() {
    DumbObject *result = (DumbObject *)calloc(sizeof(DumbObject), 1);
    result->isa = objc_getClass("DumbObject"); /* {  dg-warning "instance variable" } */
    return result;
}

@implementation DumbObject
+ new {
    return newDumbObject();
}
+ (void) initialize { }
- forward:(SEL)msg :(long *)params {
    printf("forward:: with %s called\n", sel_getName(msg));
    return self;
}
@end

//#include <Block_private.h>

enum {
    BLOCK_NEEDS_FREE =        (1 << 24),
    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
    BLOCK_NO_COPY =           (1 << 26), // interim byref: no copies allowed
    BLOCK_IS_GC =             (1 << 27),
};

/* APPLE LOCAL begin radar 5847213 - radar 6329245 */
struct Block_basic {
    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
    int Block_flags;
    int reserved;
    void (*Block_invoke)(void *);

    struct Block_descriptor_1 {
        unsigned long int reserved;     // NULL
        unsigned long int Block_size;  // sizeof(struct Block_literal_1)

        // optional helper functions
        void (*Block_copy)(void *dst, void *src);
        void (*Block_dispose)(void *src);
    } *descriptor;

    // imported variables
};
/* APPLE LOCAL end radar 5847213 - radar 6329245 */

struct Block_byref {
    void* isa;
    struct Block_byref *forwarding;
    int flags;//refcount;
    int size;
    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
    void (*byref_destroy)(struct Block_byref *);
    // long shared[0];
};


int ByrefAssignCopy = 0;

void _Block_byref_assign_copy(void *destp, void *source) {
    struct Block_byref *src = (struct Block_byref *)source;
    ByrefAssignCopy = 1;
    // lets look at the Block_byref
    if ((src->flags & BLOCK_HAS_COPY_DISPOSE) == 0) {
        printf("byref data block does not have bit saying that copy/dispose helper routines are present\n");
        return;
    }
    printf("calling out to byref copy helper at %p\n", src->byref_keep);
    int junk[100];
    src->byref_keep((struct Block_byref *)junk, src);
}

void _Block_byref_release(void *source) {
    struct Block_byref *src = (struct Block_byref *)source;
    src->byref_destroy(src);
}

int main(int argc, char *argv[]) {
    id __block dumbo = newDumbObject(); //[DumbObject new];
    void (^dummy)(void) = ^{ 
        [dumbo self];
    };

    struct Block_basic *aBlock = (struct Block_basic *)(void *)dummy;
    if ((aBlock->Block_flags & BLOCK_HAS_COPY_DISPOSE) == 0) {
        printf("Block should have a NON_POD copy/destroy helpers and flags to say so, but doesn't\n");
        return 1;
    }

    char result[200];
    printf("calling out to copy support helper at %p\n", aBlock->descriptor->Block_copy);
    (*aBlock->descriptor->Block_copy)(result, aBlock); // do fixup

    // The copy/destroy helper should have had a callout  to _Block_byref_assign_copy for its byref block
    if (! ByrefAssignCopy) {
        printf("_Block_copy_assign not called\n");
        return 1;
    }

    // the copy/destroy helper of the byref should have done dst->object = [src->object retain]
    if (! CalledRetain) {
        printf("byref block support helper did not call retain\n");
        return 1;
    }

    (*aBlock->descriptor->Block_dispose)(aBlock);

    return 0;
}
