[PATCH] BlocksRuntime updates for Linux

The attached diff cleans up the BlocksRuntime/ directory of compiler-rt for better portability, eliminates compiler warnings, and adds support to the cmake build to install the results.

More specifically, the changes:
1) Remove cmake-specific #define usage from the exported Block.h/Block_private.h headers, since clients won't know what to set. These are moved into runtime.c as appropriate
2) Use cmake checks for CAS builtins, instead of guessing based on GCC #defines (which aren't set by clang and llvm-gcc anyway)
3) "#pragma mark" isn't supported by FSF gcc, so "#if 0" it out. It should still show up in IDEs that support it
4) Fix some compiler warnings. GCC 4.3.3 seems super strict about %p. function pointers can't be cast to void * either.
5) Avoid a warning for apple_versioning.c that "ISO C does not allow empty files"

Tested on Ubuntu Linux 9.04 with clang and llvm-gcc and -fblocks to define and copy some blocks (and invoke them, obviously). Also tested on Mac OS X 10.6 and linking against -lBlocksRuntime ahead of -lSystem.

blocks-linux.diff (10.2 KB)

The attached diff cleans up the BlocksRuntime/ directory of compiler-rt for better portability, eliminates compiler warnings, and adds support to the cmake build to install the results.

More specifically, the changes:
1) Remove cmake-specific #define usage from the exported Block.h/Block_private.h headers, since clients won't know what to set. These are moved into runtime.c as appropriate
2) Use cmake checks for CAS builtins, instead of guessing based on GCC #defines (which aren't set by clang and llvm-gcc anyway)
3) "#pragma mark" isn't supported by FSF gcc, so "#if 0" it out. It should still show up in IDEs that support it

FWIW, Xcode supports the following syntax instead of pragma mark:

// MARK: Your Label
or
// MARK:-
to create a separator.

If there is no other IDE that uses this pragma, it may be cleaner to replace them by this equivalent syntax.

4) Fix some compiler warnings. GCC 4.3.3 seems super strict about %p. function pointers can't be cast to void * either.
5) Avoid a warning for apple_versioning.c that "ISO C does not allow empty files"

Tested on Ubuntu Linux 9.04 with clang and llvm-gcc and -fblocks to define and copy some blocks (and invoke them, obviously). Also tested on Mac OS X 10.6 and linking against -lBlocksRuntime ahead of -lSystem.

<blocks-linux.diff>
Shantonu Sen
ssen@apple.com

Sent from my Mac Pro

-- Jean-Daniel

Breaks Builds on Solaris and AuroraUX with:

bash-3.2$ make
Scanning dependencies of target BlocksRuntime
[ 1%] Building C object BlocksRuntime/CMakeFiles/BlocksRuntime.dir/runtime.c.o
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:77:2:
error: #error unknown atomic compare-and-swap primitive
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:
In function 'latching_incr_int':
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:118:
warning: implicit declaration of function 'OSAtomicCompareAndSwapInt'
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:
In function '_Block_dump':
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:664:
warning: format '%#lx' expects type 'long unsigned int', but argument
3 has type 'unsigned int'
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:672:
warning: format '%#lx' expects type 'long unsigned int', but argument
3 has type 'unsigned int'
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:673:
warning: format '%#lx' expects type 'long unsigned int', but argument
3 has type 'unsigned int'
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:
In function '_Block_byref_dump':
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:688:
warning: format '%#lx' expects type 'long unsigned int', but argument
3 has type 'unsigned int'
/export/home/edward/lab/llvm/build/compiler-rt/BlocksRuntime/runtime.c:689:
warning: format '%#lx' expects type 'long unsigned int', but argument
3 has type 'unsigned int'

Please check these.

Thank you,
Edward O'Callaghan.

Sounds like your system compiler doesn't support gcc-style builtin atomics. Please use a different compiler?

Shantonu

No, As it worked fine before.

I can't see the #if that goes with +#elif defined(__WIN32__) as you
removed -#if TARGET_OS_MAC.
Please go over your #if / #endif blocks and trail the #endif with a
comment. I am willing to bet there is a problem there.

Thanks for your time,
Edward.

Seems pretty clear cut to me.

#if defined(HAVE_OSATOMIC_COMPARE_AND_SWAP_INT) && defined(HAVE_OSATOMIC_COMPARE_AND_SWAP_LONG)
...
#elif defined(__WIN32__)
...
#elif defined(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT) && defined(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG)
...
#else
#error unknown atomic compare-and-swap primitive
#endif

The problem isn't mismatched #if/#endif. The #error says it all, cmake couldn't detect an appropriate atomic built-in implementation.

Please use llvm-gcc or clang to build compiler-rt. Same as how nobody expects to build libgcc with anything other than gcc.

Shantonu

Clang does indeed built it with one warning.

[ 55%] Building C object
lib/CMakeFiles/CompilerRT-Common.dir/gcc_personality_v0.c.o
/export/home/edward/lab/llvm/build/compiler-rt/lib/gcc_personality_v0.c:232:36:
warning: implicit declaration of function
'__builtin_eh_return_data_regno' is invalid in C99
      [-Wimplicit-function-declaration]
            _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
                                   ^
1 diagnostic generated.

I committed a fix for the other warnings and a fix for each of the
#endif, I did not think they where very 'clear/readable' however they
are now.

Thanks for your work on the CMake system btw !

I think we need a 'clean' CMake test for the above problem instead of
the build just blowing up like that.
I guess I will have a look in the morning (its late here) unless you
have already committed something by then.

Cheers,
Edward.

There’s an Apple internal bug for that. I’ve cloned it to Bugzilla as:

<http://llvm.org/bugs/show_bug.cgi?id=5034> Implement __builtin_eh_return_data_regno()

I can probably make the cmake configure stage fail up front if none of the supported mechanisms are found. I’ll look at that. Thanks for the feedback!

Shantonu

Implemented, what a goofy builtin.

-Chris