[cfe-dev] -rewrite-objc, C and blocks

Pierre Habouzit madcoder at madism.org
Fri Oct 1 03:16:30 PDT 2010


I intended to use clang -rewrite-objc to be able to compile code using
blocks on targets unsupported by clang. I'm totally uninterested in the
ObjC rewriting, only the blocks one.

Sadly, this rewriting module rewrites to C++ even when the source code
in question is just plain old C.

I'm under the impression, that when the source code is C, only the fact
that clang is generating structs with constructors and RAII use of the
defined blocks. For example:

    struct __main_block_impl_0 {
      struct __block_impl impl;
      struct __main_block_desc_0* Desc;
      int a;
      __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
      }
    };

    [...]

    int main(void) {
        int a = 1;
        struct __Block_byref_c_0 c = {(void*)0,(struct __Block_byref_c_0 *)&c, 0, sizeof(struct __Block_byref_c_0), 1};

        int (*f)(int) = (int (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a);
        [...]
    }

I'm under the impression that the following "rewrite" would be correct:

    struct __main_block_impl_0 {
      struct __block_impl impl;
      struct __main_block_desc_0* Desc;
      int a;
    #ifdef __cplusplus
      __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
      }
    #endif
    };
    #ifndef __cplusplus
    #define __main_block_impl_0(fp, desc, _a, flags) \
        ((struct __main_block_impl_0){               \
            .impl = {                                \
                .isa = &_NSConcreteStackBlock,       \
                .Flags = flags,                      \
                .FuncPtr = fp,                       \
            },                                       \
            .Desc = desc,                            \
            .a = (_a),                               \
        })
    #endif

    [...]

    int main(void) {
        int a = 1;
        struct __Block_byref_c_0 c = {(void*)0,(struct __Block_byref_c_0 *)&c, 0, sizeof(struct __Block_byref_c_0), 1};

        int (*f)(int) = (int (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a);
        [...]
    }


Am I correct, or am I missing something obvious ?


-- 
·O·  Pierre Habouzit
··O                                                madcoder at debian.org
OOO                                                http://www.madism.org



More information about the cfe-dev mailing list