fpco / inline-c

284 stars 51 forks source link

mixing C and CPP #111

Closed deliciouslytyped closed 4 years ago

deliciouslytyped commented 4 years ago

Can you mix inline-c with inline-c-cpp? Do I have to compile with a separate module configuration in my cabal?

I'm currently getting something like:

$ cabal repl --repl-options="-fobject-code" 
--repl-options="-O0"
Build profile: -w ghc-8.8.3 -O1
In order, the following will be built (use -v for more details):
 - clang-pure-0.2.0.6 (first run)
Preprocessing library for clang-pure-0.2.0.6..
Matcher.hsc: In function ‘main’:
Matcher.hsc:1:5: error: implicit declaration of function ‘hsc_Warning’ [-Werror=implicit-function-declaration]
Matcher.hsc:1:18: error: ‘cpp’ undeclared (first use in this function)
Matcher.hsc:1:18: note: each undeclared identifier is reported only once for each function it appears in
Matcher.hsc:1:21: error: expected ‘)’ before ‘is’
Matcher.hsc:15:5: error: implicit declaration of function ‘hsc_import’ [-Werror=implicit-function-declaration]
Matcher.hsc:15:17: error: ‘qualified’ undeclared (first use in this function)
Matcher.hsc:15:26: error: expected ‘)’ before ‘Language’
Matcher.hsc:16:26: error: expected ‘)’ before ‘Language’
Matcher.hsc:17:26: error: expected ‘)’ before ‘Language’
cc1: all warnings being treated as errors
compiling /bakery2/oven1/personal/projects/hask2/qta

With (sorry if the code is bad but the compiler fails earlier anyway)

import qualified Language.C.Inline.CPP as CPP
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BS

CPP.context cppCtx
CPP.include "<iostream>"
test :: ByteString -> IO CInt
test str = BS.useAsCString str $ \cs -> [CPP.block| void {
          std::cout << "Hello, world!" << $(int x) << std::endl;
        } |]
deliciouslytyped commented 4 years ago

Ok I guess this probably isn't a mixing error? Looking at /nix/store/0ywc4dlk8159rj7q5fhkdvm2xrjkfxy3-ghc-8.8.3/lib/ghc-8.8.3/template-hsc.h, it contains


/* We need stddef to be able to use size_t. Hopefully this won't cause
   any problems along the lines of ghc trac #2897. */
#include <stddef.h>

/* hsc_* are defined in the generated utils.c */
int hsc_printf(const char *format, ...);
int hsc_toupper(int c);
int hsc_tolower(int c);
int hsc_putchar(int c);
/* "void" should really be "FILE", but we aren't able to refer to "FILE"
   as we don't want to include <stdio.h> here */
int hsc_fputs(const char *s, void *stream);
/* "void" should really be "FILE", but we aren't able to refer to "FILE"
   as we don't want to include <stdio.h> here */
void *hsc_stdout(void);

/* For the single-argument macros we make the macros variadic (the
   argument is x... rather than simply x) so that arguments containing
   commas work. See trac #590. */

#ifndef offsetof
#define offsetof(t, f) ((size_t) &((t *)0)->f)
#endif

#if __NHC__
#define hsc_line(line, file) \
    hsc_printf ("# %d \"%s\"\n", line, file);
#define hsc_column(column)
#else
#define hsc_line(line, file) \
    hsc_printf ("{-# LINE %d \"%s\" #-}\n", line, file);
#define hsc_column(column) \
    hsc_printf ("{-# COLUMN %d #-}", column);
#endif

#define hsc_const(x...)                               \
    if ((x) < 0)                                      \
        hsc_printf ("%lld", (long long)(x));          \
    else                                              \
        hsc_printf ("%llu", (unsigned long long)(x));

#define hsc_const_str(x...)                                       \
    {                                                             \
        const char *s = (x);                                      \
        hsc_printf ("\"");                                        \
        while (*s != '\0')                                        \
        {                                                         \
            if (*s == '"' || *s == '\\')                          \
                hsc_printf ("\\%c", *s);                          \
            else if (*s >= 0x20 && *s <= 0x7E)                    \
                hsc_printf ("%c", *s);                            \
            else                                                  \
                hsc_printf ("\\%d%s",                             \
                        (unsigned char) *s,                       \
                        s[1] >= '0' && s[1] <= '9' ? "\\&" : ""); \
            ++s;                                                  \
        }                                                         \
        hsc_printf ("\"");                                        \
    }

#define hsc_type(t...)                                      \
    if ((t)(int)(t)1.4 == (t)1.4)                           \
        hsc_printf ("%s%lu",                                \
                (t)(-1) < (t)0 ? "Int" : "Word",            \
                (unsigned long)sizeof (t) * 8);             \
    else                                                    \
        hsc_printf ("%s",                                   \
                sizeof (t) >  sizeof (double) ? "LDouble" : \
                sizeof (t) == sizeof (double) ? "Double"  : \
                "Float");

#define hsc_peek(t, f) \
    hsc_printf ("(\\hsc_ptr -> peekByteOff hsc_ptr %ld)", \
                (long) offsetof (t, f));

#define hsc_poke(t, f) \
    hsc_printf ("(\\hsc_ptr -> pokeByteOff hsc_ptr %ld)", \
                (long) offsetof (t, f));

#define hsc_ptr(t, f) \
    hsc_printf ("(\\hsc_ptr -> hsc_ptr `plusPtr` %ld)", \
                (long) offsetof (t, f));

#define hsc_offset(t, f) \
    hsc_printf("(%ld)", (long) offsetof (t, f));

#define hsc_size(t...) \
    hsc_printf("(%ld)", (long) sizeof(t));

#define hsc_alignment(x...)                                           \
  do {                                                                \
    struct __anon_x__ {                                               \
      char a;                                                         \
      x b;                                                            \
    };                                                                \
    hsc_printf("%lu", (unsigned long)offsetof(struct __anon_x__, b)); \
  } while (0)

#define hsc_enum(t, f, print_name, x)                   \
    print_name;                                         \
    hsc_printf (" :: %s\n", #t);                        \
    print_name;                                         \
    hsc_printf (" = %s ", #f);                          \
    if ((x) < 0)                                        \
        hsc_printf ("(%lld)\n", (long long)(x));        \
    else                                                \
        hsc_printf ("%llu\n", (unsigned long long)(x));

#define hsc_haskellize(x...)                                       \
    {                                                              \
        const char *s = (x);                                       \
        int upper = 0;                                             \
        if (*s != '\0')                                            \
        {                                                          \
            hsc_putchar (hsc_tolower (*s));                        \
            ++s;                                                   \
            while (*s != '\0')                                     \
            {                                                      \
                if (*s == '_')                                     \
                    upper = 1;                                     \
                else                                               \
                {                                                  \
                    hsc_putchar (upper ? hsc_toupper (*s)          \
                                       : hsc_tolower (*s));        \
                    upper = 0;                                     \
                }                                                  \
                ++s;                                               \
            }                                                      \
        }                                                          \
    }

Which indeed does not contain an hsc_Warning.

It's pulled in via dist-newstyle/build/x86_64-linux/ghc-8.8.3/clang-pure-0.2.0.6/build/Language/C/Clang/Internal/Matcher_hsc_make.c

#include "/nix/store/0ywc4dlk8159rj7q5fhkdvm2xrjkfxy3-ghc-8.8.3/lib/ghc-8.8.3/template-hsc.h"

int main (void)
{
    hsc_line (1, "src/Language/C/Clang/Internal/Matcher.hsc");
#line 1 "Matcher.hsc"
    hsc_Warning (cpp is experimental?);
...
}
deliciouslytyped commented 4 years ago

Nevermind, this is probably invalid and user error. I had #Warning cpp is experimental? at the top of the file because I keep trying to use scripting language comments everywhere...