diff --git a/src/runtime/c/gu/defs.c b/src/runtime/c/gu/defs.c index 2c3772b7c..5e78e797b 100644 --- a/src/runtime/c/gu/defs.c +++ b/src/runtime/c/gu/defs.c @@ -1,4 +1,4 @@ #include void* const gu_null = NULL; -GuStruct* const gu_null_struct = NULL; +GU_API_DATA GuStruct* const gu_null_struct = NULL; diff --git a/src/runtime/c/gu/defs.h b/src/runtime/c/gu/defs.h index 51a2293e3..f302481d6 100644 --- a/src/runtime/c/gu/defs.h +++ b/src/runtime/c/gu/defs.h @@ -25,6 +25,24 @@ #ifndef GU_DEFS_H_ #define GU_DEFS_H_ +// MSVC requires explicit export/import of +// symbols in DLLs. CMake takes care of this +// for functions, but not for data/variables. +#if defined(_MSC_VER) +#if defined(COMPILING_GU) +#define GU_API_DATA_DECL __declspec(dllexport) +#define GU_API_DATA __declspec(dllexport) +#else +#define GU_API_DATA_DECL __declspec(dllimport) +#define GU_API_DATA ERROR_NOT_COMPILING_LIBGU +#endif + +#else +#define GU_API_DATA_DECL extern +#define GU_API_DATA +#endif +// end MSVC workaround + #include #include #include @@ -154,7 +172,7 @@ extern void* const gu_null; // Dummy struct used for generic struct pointers typedef struct GuStruct GuStruct; -extern GuStruct* const gu_null_struct; +GU_API_DATA_DECL GuStruct* const gu_null_struct; typedef uintptr_t GuWord; diff --git a/src/runtime/c/gu/hash.c b/src/runtime/c/gu/hash.c index 1666263e6..0057d0f42 100644 --- a/src/runtime/c/gu/hash.c +++ b/src/runtime/c/gu/hash.c @@ -25,7 +25,7 @@ gu_int_hash_fn(GuHasher* self, const void* p) return (GuHash) *(const int*) p; } -GuHasher gu_int_hasher[1] = { +GU_API_DATA GuHasher gu_int_hasher[1] = { { { gu_int_eq_fn }, gu_int_hash_fn @@ -46,7 +46,7 @@ gu_addr_hash_fn(GuHasher* self, const void* p) return (GuHash) (uintptr_t) p; } -GuHasher gu_addr_hasher[1] = { +GU_API_DATA GuHasher gu_addr_hasher[1] = { { { gu_addr_eq_fn }, gu_addr_hash_fn @@ -69,7 +69,7 @@ gu_word_hash_fn(GuHasher* self, const void* p) return (GuHash) (uintptr_t) p; } -GuHasher gu_word_hasher[1] = { +GU_API_DATA GuHasher gu_word_hasher[1] = { { { gu_word_eq_fn }, gu_word_hash_fn diff --git a/src/runtime/c/gu/hash.h b/src/runtime/c/gu/hash.h index e16c2f454..da612f3f4 100644 --- a/src/runtime/c/gu/hash.h +++ b/src/runtime/c/gu/hash.h @@ -31,10 +31,10 @@ struct GuHasher { }; -extern GuHasher gu_int_hasher[1]; +GU_API_DATA GuHasher gu_int_hasher[1]; -extern GuHasher gu_addr_hasher[1]; +GU_API_DATA GuHasher gu_addr_hasher[1]; -extern GuHasher gu_word_hasher[1]; +GU_API_DATA GuHasher gu_word_hasher[1]; #endif // GU_HASH_H_ diff --git a/src/runtime/c/gu/mem.c b/src/runtime/c/gu/mem.c index 0fc315a4f..325eaea77 100644 --- a/src/runtime/c/gu/mem.c +++ b/src/runtime/c/gu/mem.c @@ -8,7 +8,9 @@ #include #include #endif +#if !defined(_MSC_VER) #include +#endif #include #ifdef USE_VALGRIND diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index 88b762a04..8cf55929b 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -3,7 +3,7 @@ #include #include #include -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) #include #endif diff --git a/src/runtime/c/gu/string.c b/src/runtime/c/gu/string.c index 5a31c8806..3e754a72c 100644 --- a/src/runtime/c/gu/string.c +++ b/src/runtime/c/gu/string.c @@ -5,7 +5,7 @@ #include #include #include -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) #include #endif @@ -273,7 +273,7 @@ gu_string_eq_fn(GuEquality* self, const void* p1, const void* p2) return strcmp((GuString) p1, (GuString) p2) == 0; } -GuEquality gu_string_equality[1] = { { gu_string_eq_fn } }; +GU_API_DATA GuEquality gu_string_equality[1] = { { gu_string_eq_fn } }; static int gu_string_cmp_fn(GuOrder* self, const void* p1, const void* p2) @@ -282,7 +282,7 @@ gu_string_cmp_fn(GuOrder* self, const void* p1, const void* p2) return strcmp((GuString) p1, (GuString) p2); } -GuOrder gu_string_order[1] = { { gu_string_cmp_fn } }; +GU_API_DATA GuOrder gu_string_order[1] = { { gu_string_cmp_fn } }; static GuHash gu_string_hasher_hash(GuHasher* self, const void* p) @@ -291,7 +291,7 @@ gu_string_hasher_hash(GuHasher* self, const void* p) return gu_string_hash(0, (GuString) p); } -GuHasher gu_string_hasher[1] = { +GU_API_DATA GuHasher gu_string_hasher[1] = { { .eq = { gu_string_eq_fn }, .hash = gu_string_hasher_hash diff --git a/src/runtime/c/gu/string.h b/src/runtime/c/gu/string.h index 4064286a9..2bf1aef45 100644 --- a/src/runtime/c/gu/string.h +++ b/src/runtime/c/gu/string.h @@ -58,9 +58,9 @@ gu_string_is_prefix(GuString s1, GuString s2); #if defined(GU_FUN_H_) && !defined(GU_STRING_H_FUN_) #define GU_STRING_H_FUN_ -extern GuEquality gu_string_equality[1]; +GU_API_DATA GuEquality gu_string_equality[1]; -extern GuOrder gu_string_order[1]; +GU_API_DATA GuOrder gu_string_order[1]; #endif #if defined(GU_HASH_H_) && !defined(GU_STRING_H_HASH_) @@ -69,7 +69,7 @@ extern GuOrder gu_string_order[1]; GuHash gu_string_hash(GuHash h, GuString s); -extern GuHasher gu_string_hasher[1]; +GU_API_DATA GuHasher gu_string_hasher[1]; #endif #if defined(GU_SEQ_H_) && !defined(GU_STRING_H_SEQ_) diff --git a/src/runtime/c/gu/variant.c b/src/runtime/c/gu/variant.c index dd4149429..75b75c086 100644 --- a/src/runtime/c/gu/variant.c +++ b/src/runtime/c/gu/variant.c @@ -108,4 +108,4 @@ gu_variant_intval(GuVariant variant) return (variant / GU_VARIANT_ALIGNMENT); } -const GuVariant gu_null_variant = { (GuWord) NULL }; +GU_API_DATA const GuVariant gu_null_variant = { (GuWord) NULL }; diff --git a/src/runtime/c/gu/variant.h b/src/runtime/c/gu/variant.h index a4c24b4af..8e7741694 100644 --- a/src/runtime/c/gu/variant.h +++ b/src/runtime/c/gu/variant.h @@ -97,7 +97,7 @@ gu_variant_from_ptr(const void* p) return (uintptr_t) p; } -extern const GuVariant gu_null_variant; +GU_API_DATA const GuVariant gu_null_variant; static inline bool gu_variant_is_null(GuVariant v) { diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index 5b1842d74..3941580cb 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -56,7 +56,7 @@ typedef struct { PgfPatt patt; } PgfPattAs; -typedef void PgfPattWild; +typedef char PgfPattWild; typedef struct { PgfPatt patt; @@ -241,12 +241,15 @@ typedef struct PgfSymbolKP } PgfSymbolKP; typedef struct { + char nothing[0]; // Empty struct } PgfSymbolNE; typedef struct { + char nothing[0]; // Empty struct } PgfSymbolBIND; typedef struct { + char nothing[0]; // Empty struct } PgfSymbolCAPIT; typedef GuBuf PgfProductionIdx; diff --git a/src/runtime/c/pgf/evaluator.c b/src/runtime/c/pgf/evaluator.c index 457f60896..698601820 100644 --- a/src/runtime/c/pgf/evaluator.c +++ b/src/runtime/c/pgf/evaluator.c @@ -437,7 +437,7 @@ pgf_evaluate_accum_init_flt(PgfReasoner* rs, rs->pool); lit_flt->val = val; accum->enter_stack_ptr = rs->enter_stack_ptr; - rs->enter_stack_ptr = ((void*)accum)-sizeof(void*)*2; + rs->enter_stack_ptr = ((char*)accum)-sizeof(char*)*2; accum->consts = NULL; } diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index 4fe18d181..003fa2630 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -5,7 +5,7 @@ #include #include #include "lightning.h" -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) #include #endif @@ -43,7 +43,7 @@ typedef struct { #define JIT_VSTATE JIT_V1 #define JIT_VCLOS JIT_V2 -#if defined(__MINGW32__) +#if defined(__MINGW32__) || defined(_MSC_VER) #include static int @@ -71,7 +71,7 @@ pgf_jit_alloc_page(PgfReader* rdr) #if defined(ANDROID) if ((page = memalign(page_size, page_size)) == NULL) { -#elif defined(__MINGW32__) +#elif defined(__MINGW32__) || defined(_MSC_VER) if ((page = malloc(page_size)) == NULL) { #else if (posix_memalign(&page, page_size, page_size) != 0) { diff --git a/src/runtime/c/pgf/linearizer.h b/src/runtime/c/pgf/linearizer.h index 8178facdb..08ebfd159 100644 --- a/src/runtime/c/pgf/linearizer.h +++ b/src/runtime/c/pgf/linearizer.h @@ -29,6 +29,7 @@ PgfCncTreeEnum* pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuExn* err, GuPool* pool); typedef struct { + char nothing[0]; // Empty struct } PgfLinNonExist; PgfCncTree diff --git a/src/runtime/c/pgf/literals.c b/src/runtime/c/pgf/literals.c index ac57b150f..b5332b1ec 100644 --- a/src/runtime/c/pgf/literals.c +++ b/src/runtime/c/pgf/literals.c @@ -334,7 +334,7 @@ pgf_match_name_lit(PgfLiteralCallback* self, PgfConcr* concr, return ep; } -PgfLiteralCallback pgf_nerc_literal_callback = +PGF_API_DATA PgfLiteralCallback pgf_nerc_literal_callback = { pgf_match_name_lit, pgf_predict_empty } ; static void @@ -419,7 +419,7 @@ pgf_match_unknown_lit(PgfLiteralCallback* self, PgfConcr* concr, return ep; } -PgfLiteralCallback pgf_unknown_literal_callback = +PGF_API_DATA PgfLiteralCallback pgf_unknown_literal_callback = { pgf_match_unknown_lit, pgf_predict_empty } ; PgfCallbacksMap* diff --git a/src/runtime/c/pgf/literals.h b/src/runtime/c/pgf/literals.h index 7de17b121..624d82f9f 100644 --- a/src/runtime/c/pgf/literals.h +++ b/src/runtime/c/pgf/literals.h @@ -1,13 +1,33 @@ #ifndef PGF_LITERALS_H_ #define PGF_LITERALS_H_ +// MSVC requires explicit export/import of +// symbols in DLLs. CMake takes care of this +// for functions, but not for data/variables. +#if defined(_MSC_VER) +#if defined(COMPILING_PGF) +#define PGF_API_DATA_DECL __declspec(dllexport) +#define PGF_API_DATA __declspec(dllexport) +#else +#define PGF_API_DATA_DECL __declspec(dllimport) +#define PGF_API_DATA ERROR_NOT_COMPILING_LIBPGF +#endif + +#else + +#define PGF_API_DATA_DECL extern +#define PGF_API_DATA +#endif +// end MSVC workaround + + #include // literal for named entities recognition -extern PgfLiteralCallback pgf_nerc_literal_callback; +PGF_API_DATA_DECL PgfLiteralCallback pgf_nerc_literal_callback; // literal for finding unknown words -extern PgfLiteralCallback pgf_unknown_literal_callback; +PGF_API_DATA_DECL PgfLiteralCallback pgf_unknown_literal_callback; PgfCCat* pgf_literal_cat(PgfConcr* concr, PgfLiteral lit); diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c index cb690a353..5d509220a 100644 --- a/src/runtime/c/pgf/reader.c +++ b/src/runtime/c/pgf/reader.c @@ -14,7 +14,7 @@ #include #include #include -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) #include #endif