Commit db91d17e authored by Ryan Scott's avatar Ryan Scott
Browse files

Properly introduce CTimer to System.Posix.Types

Summary:
In ffc23270, an attempt was made at
adding a Haskell wrapper around the C `timer_t` type. Unfortunately, GHC's
autoconf macros weren't sophisticated enough at the time to properly detect
that `timer_t` is represented by a `void *` (i.e., a pointer) on most OSes.

This is a second attempt at `CTimer`, this time using `AC_COMPILE_IFELSE` to
detect if a type is a pointer type by compiling the following program:

```
type val;
*val;
```

This also only derives a small subset of class instances for `CTimer` that are
known to be compatible with `Ptr` using a new `OPAQUE_TYPE_WITH_CTYPE` macro.

Test Plan: ./validate

Reviewers: erikd, hvr, austin, bgamari

Reviewed By: bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2952

GHC Trac Issues: #12795, #12998
parent 331f88d0
......@@ -92,13 +92,9 @@ module System.Posix.Types (
#if defined(HTYPE_KEY_T)
CKey(..),
#endif
-- We can't support CTimer (timer_t) yet, as FPTOOLS_CHECK_HTYPE doesn't have
-- the ability to discern pointer types (like void*, which timer_t usually is)
-- from non-pointer types. See GHC Trac #12998.
--
-- #if defined(HTYPE_TIMER_T)
-- CTimer(..),
-- #endif
#if defined(HTYPE_TIMER_T)
CTimer(..),
#endif
Fd(..),
......@@ -213,6 +209,10 @@ INTEGRAL_TYPE_WITH_CTYPE(CId,id_t,HTYPE_ID_T)
-- | @since 4.10.0.0
INTEGRAL_TYPE_WITH_CTYPE(CKey,key_t,HTYPE_KEY_T)
#endif
#if defined(HTYPE_TIMER_T)
-- | @since 4.10.0.0
OPAQUE_TYPE_WITH_CTYPE(CTimer,timer_t,HTYPE_TIMER_T)
#endif
-- Make an Fd type rather than using CInt everywhere
INTEGRAL_TYPE(Fd,CInt)
......
......@@ -131,26 +131,43 @@ AC_DEFUN([FPTOOLS_CHECK_HTYPE_ELSE],[
if test "$HTYPE_IS_INTEGRAL" -eq 0
then
FP_COMPUTE_INT([HTYPE_IS_FLOAT],[sizeof($1) == sizeof(float)],
[FPTOOLS_HTYPE_INCLUDES],
[AC_CV_NAME_supported=no])
FP_COMPUTE_INT([HTYPE_IS_DOUBLE],[sizeof($1) == sizeof(double)],
[FPTOOLS_HTYPE_INCLUDES],
[AC_CV_NAME_supported=no])
FP_COMPUTE_INT([HTYPE_IS_LDOUBLE],[sizeof($1) == sizeof(long double)],
[FPTOOLS_HTYPE_INCLUDES],
[AC_CV_NAME_supported=no])
if test "$HTYPE_IS_FLOAT" -eq 1
then
AC_CV_NAME=Float
elif test "$HTYPE_IS_DOUBLE" -eq 1
then
AC_CV_NAME=Double
elif test "$HTYPE_IS_LDOUBLE" -eq 1
dnl If the C type isn't an integer, we check if it's a pointer type
dnl by trying to dereference one of its values. If that fails to
dnl compile, it's not a pointer, so we check to see if it's a
dnl floating-point type.
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[FPTOOLS_HTYPE_INCLUDES],
[$1 val; *val;]
)],
[HTYPE_IS_POINTER=yes],
[HTYPE_IS_POINTER=no])
if test "$HTYPE_IS_POINTER" = yes
then
AC_CV_NAME=LDouble
AC_CV_NAME="Ptr ()"
else
AC_CV_NAME_supported=no
FP_COMPUTE_INT([HTYPE_IS_FLOAT],[sizeof($1) == sizeof(float)],
[FPTOOLS_HTYPE_INCLUDES],
[AC_CV_NAME_supported=no])
FP_COMPUTE_INT([HTYPE_IS_DOUBLE],[sizeof($1) == sizeof(double)],
[FPTOOLS_HTYPE_INCLUDES],
[AC_CV_NAME_supported=no])
FP_COMPUTE_INT([HTYPE_IS_LDOUBLE],[sizeof($1) == sizeof(long double)],
[FPTOOLS_HTYPE_INCLUDES],
[AC_CV_NAME_supported=no])
if test "$HTYPE_IS_FLOAT" -eq 1
then
AC_CV_NAME=Float
elif test "$HTYPE_IS_DOUBLE" -eq 1
then
AC_CV_NAME=Double
elif test "$HTYPE_IS_LDOUBLE" -eq 1
then
AC_CV_NAME=LDouble
else
AC_CV_NAME_supported=no
fi
fi
else
FP_COMPUTE_INT([HTYPE_IS_SIGNED],[(($1)(-1)) < (($1)0)],
......
......@@ -31,7 +31,7 @@
* Added `Eq1`, `Ord1`, `Read1` and `Show1` instances for `NonEmpty`.
* Add wrappers for `blksize_t`, `blkcnt_t`, `clockid_t`, `fsblkcnt_t`,
`fsfilcnt_t`, `id_t`, and `key_t` to System.Posix.Types (#12795)
`fsfilcnt_t`, `id_t`, `key_t`, and `timer_t` to System.Posix.Types (#12795)
* Raw buffer operations in `GHC.IO.FD` are now strict in the buffer, offset, and length operations (#9696)
......
......@@ -155,6 +155,7 @@ FPTOOLS_CHECK_HTYPE(fsblkcnt_t)
FPTOOLS_CHECK_HTYPE(fsfilcnt_t)
FPTOOLS_CHECK_HTYPE(id_t)
FPTOOLS_CHECK_HTYPE(key_t)
FPTOOLS_CHECK_HTYPE(timer_t)
FPTOOLS_CHECK_HTYPE(intptr_t)
FPTOOLS_CHECK_HTYPE(uintptr_t)
......
......@@ -19,6 +19,7 @@
#define ARITHMETIC_CLASSES Eq,Ord,Num,Enum,Storable,Real
#define INTEGRAL_CLASSES Bounded,Integral,Bits,FiniteBits
#define FLOATING_CLASSES Fractional,Floating,RealFrac,RealFloat
#define OPAQUE_CLASSES Eq,Ord,Storable
#define ARITHMETIC_TYPE(T,B) \
newtype T = T B deriving (ARITHMETIC_CLASSES) \
......@@ -42,4 +43,9 @@ newtype {-# CTYPE "THE_CTYPE" #-} T = T B \
deriving (ARITHMETIC_CLASSES, FLOATING_CLASSES) \
deriving newtype (Read, Show);
#define OPAQUE_TYPE_WITH_CTYPE(T,THE_CTYPE,B) \
newtype {-# CTYPE "THE_CTYPE" #-} T = T (B) \
deriving (OPAQUE_CLASSES) \
deriving newtype Show;
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment