X-Git-Url: https://git.draconx.ca/gitweb/dxcommon.git/blobdiff_plain/cba6ab66683d20b46def45f691fa7c750f3f9a2b..14c0c9a9e5eeacc82904f4cc33e0842f5ee9ec44:/m4/align.m4 diff --git a/m4/align.m4 b/m4/align.m4 new file mode 100644 index 0000000..03e18a8 --- /dev/null +++ b/m4/align.m4 @@ -0,0 +1,68 @@ +# Copyright © 2024 Nick Bowler +# +# License WTFPL2: Do What The Fuck You Want To Public License, version 2. +# This is free software: you are free to do what the fuck you want to. +# There is NO WARRANTY, to the extent permitted by law. + +# DX_C_ALIGNOF +# +# Probe whether the C compiler understands _Alignof(T). +# +# If not supported, _Alignof(T) is defined as a function-like macro which +# uses offsetof to guess the alignment of T, which must be a type such that +# T x; is a valid declaration of x as an object of type T. It is therefore +# necessary that the caller includes before using _Alignof. +# +# We skip the test if Autoconf has previously determined that the C compiler +# supports C11 or a newer standard, since the C11 test program checks this. +# +# Annoyingly, autoconf-2.71 removed the assignment of ac_cv_prog_cc_c11, +# even though this was actual documented behaviour... +AC_DEFUN([DX_C_ALIGNOF], +[AS_CASE([${ac_cv_prog_cc_c11-no}/${ac_prog_cc_stdc-no}], + [no/no|*/c89|*/c99], + [AC_CACHE_CHECK([if $CC supports _Alignof], [dx_cv_have_alignof], + [AC_COMPUTE_INT([_dx_tmp], [_Alignof(char)], [@&t@], [_dx_tmp=0]) +AS_CASE([$_dx_tmp], [1], [dx_cv_have_alignof=yes], [dx_cv_have_alignof=no])])], + [dx_cv_have_alignof=yes]) +AS_CASE([$dx_cv_have_alignof], [no], [AC_DEFINE([_Alignof(T)], + [offsetof(struct { char a; T b; }, b)], + [Define _Alignof(T) to a suitable fallback if _Alignof is unsupported.])])]) + +# DX_C_ALIGNAS +# +# Probe whether the C compiler understands _Alignas(X). +# +# If not supported, but the compiler supports the GNU __attribute__ or +# Microsoft __declspec methods to set alignment, _Alignas(X) is defined +# as a function-like macro which expands to such syntax. These only +# work if X is an integer constant (as opposed to a type name). +# +# If there is no known method of declaring a variable with increased +# alignment, then _Alignas(X) is defined as a function-like macro which +# expands to nothing, which will compile but has no runtime effect. +# +# We skip the test if Autoconf has previously determined that the C +# compiler supports C11 or a newer standard, since the C11 test program +# checks this. +AC_DEFUN([DX_C_ALIGNAS], +[AS_CASE([${ac_cv_prog_cc_c11-no}/${ac_prog_cc_stdc-no}], + [no/no|*/c89|*/c99], + [AC_CACHE_CHECK([if $CC supports _Alignas], [dx_cv_have_alignas], +[dx_cv_have_alignas=no +for _dx_alignas +in '_Alignas(X)' '__attribute__((__aligned__(X)))' '__declspec(align(X))' +do +AC_COMPUTE_INT([_dx_tmp], + [sizeof (struct { char a; char ALIGNAS_TEST(4) b; }) >= 8], + [#define ALIGNAS_TEST(X) $_dx_alignas +],[_dx_tmp=0]) +AS_CASE([$_dx_tmp/$_dx_alignas], + [1/_Alignas*], [dx_cv_have_alignas=yes; break], + [1/*], [dx_cv_have_alignas=$_dx_alignas; break]) +done])], + [dx_cv_have_alignas=yes]) +AS_CASE([$dx_cv_have_alignas], + [*'(X)'*], [AC_DEFINE_UNQUOTED([_Alignas(X)], [$dx_cv_have_alignas], + [Define _Alignas(X) to a suitable fallback if _Alignas is unsupported.])], + [no], [AC_DEFINE([_Alignas(X)], [/**/])])])