+case $finally_flavour,$GCC in
+ undecided,yes)
+ dnl That didn't work. I guess it's not really GCC after all. Maybe it's
+ dnl Clang wearing a false moustache.
+
+ AC_CACHE_CHECK([whether the impostor GNU C compiler is really Clang],
+ [finally_cv_gcc_really_clang_p], [
+ AC_COMPILE_IFELSE([FINALLY_GCC_REALLY_CLANG_TEST_PROGRAM],
+ [finally_cv_gcc_really_clang_p=yes],
+ [finally_cv_gcc_really_clang_p=no])])
+ finally_clang_p=$finally_cv_gcc_really_clang_p
+ ;;
+ *)
+ finally_clang_p=no
+ ;;
+esac
+
+case $finally_flavour,$finally_clang_p in
+ undecided,yes)
+ dnl Yup. Not a particularly convincing disguise, really. Well, at least
+ dnl Clang has a thing which looks a bit like nested functions, and a bit
+ dnl like closures, only with a terrible syntax, which it calls `blocks'.
+ dnl Unfortunately, we may or may not require varying levels of ceremony
+ dnl to make this work.
+
+ AC_CACHE_CHECK([which hacks are needed to persuade Clang to work with simple blocks],
+ [finally_cv_clang_blocks_hacks], [
+
+ dnl We'll need to mess with the compiler flags and libraries,
+ dnl so make sure we can put them back again afterwards.
+ finally_original_CFLAGS=$CFLAGS finally_original_LIBS=$LIBS
+
+ dnl Maintain a list of things that we did. This is the thing
+ dnl we'll cache.
+ unset hacks; win=t
+
+ case $win in
+ t)
+ dnl OK. First thing, we need to get the compiler proper to accept
+ dnl the `blocks' syntax. I guess the syntax is so hideous that
+ dnl Clang is sometimes ashamed to admit to parsing it unless we
+ dnl twist its arm. Apparently `-fblocks' is unnecessary on some
+ dnl targets, so let's see if we can manage without.
+
+ for pass in nil -fblocks; do
+ case $pass in -*) CFLAGS="$CFLAGS -fblocks" ;; esac
+ AC_COMPILE_IFELSE([FINALLY_CLANG_BLOCKS_TEST_PROGRAM],
+ [win=t], [win=nil])
+ case $win in t) break ;; esac
+ done
+ case $win,$pass in
+ *,nil | nil,*) ;;
+ *) hacks=${hacks+$hacks }$pass
+ esac
+ ;;
+ esac
+
+ case $win in
+ t)
+ dnl We got the compiler to accept the unpleasant syntax. The next
+ dnl problem is that, technically, the generated code depends on a
+ dnl runtime support library; only our use for these things is so
+ dnl simple that, at reasonable optimization settings, we can do
+ dnl without. So let's see if we're in that situation.
+
+ for pass in nil -lBlocksRuntime; do
+ case $pass in -l*) LIBS="$LIBS $pass" ;; esac
+ AC_LINK_IFELSE([FINALLY_CLANG_BLOCKS_TEST_PROGRAM],
+ [win=t], [win=nil])
+ case $win in t) break ;; esac
+ done
+ case $win,$pass in
+ *,nil | nil,*) ;;
+ *) hacks=${hacks+$hacks }$pass
+ esac
+ ;;
+ esac
+
+ dnl We've finished probing, and it's time to report our findings.
+ case $win in
+ t) finally_cv_clang_blocks_hacks=${hacks-none} ;;
+ *) finally_cv_clang_blocks_hacks=failed ;;
+ esac
+
+ dnl Oh! And don't forget to undo our fiddling with the compiler and
+ dnl linker settings.
+ CFLAGS=$finally_original_CFLAGS LIBS=$finally_original_LIBS])
+
+ dnl That was fun. Now we know how to persuade Clang to support these
+ dnl block thingummies (or not). Report our findings.
+ case $finally_cv_clang_blocks_hacks in
+ failed)
+ finally_flavour=NIL
+ ;;
+ *)
+ finally_flavour=CLANG_BLOCKS FINALLY_CFLAGS= FINALLY_LIBS=
+ finally_result="Clang blocks"
+ for hack in $finally_cv_clang_blocks_hacks; do
+ case $hack in
+ none) ;;
+ -l* | -L*) FINALLY_LIBS=${FINALLY_LIBS:+ $FINALLY_LIBS}$hack ;;
+ -*) FINALLY_CFLAGS=${FINALLY_CFLAGS:+ $FINALLY_CFLAGS}$hack ;;
+ *) AC_MSG_ERROR([confused by unexpected hack $hack]) ;;
+ esac
+ done
+ ;;
+ esac
+ ;;
+esac
+