From 7c81cd30de876f8bc56a4c689372e4d388b8608c Mon Sep 17 00:00:00 2001 From: Jonathan Marler Date: Sun, 10 Sep 2017 14:05:18 -0600 Subject: [PATCH 1/3] Add support for MSVC --- CMakeLists.txt | 36 +++++++++++++++++++++--------- cmake/Findclang.cmake | 8 ++++++- cmake/Findllvm.cmake | 45 ++++++++++++++++++++++++++++--------- src/analyze.cpp | 2 +- src/bigfloat.hpp | 8 +++++++ src/bigint.cpp | 52 ++++++++++++++++++++++++++++++++++++------- src/bigint.hpp | 13 ++++++++++- src/buffer.hpp | 4 ++-- src/codegen.cpp | 15 ++++++++++++- src/ir.cpp | 7 +++--- src/os.cpp | 12 +++++----- src/parsec.cpp | 2 +- src/parser.cpp | 10 ++++----- src/parser.hpp | 2 +- src/quadmath.hpp | 34 ++++++++++++++++++++++++++++ src/tokenizer.cpp | 4 ++-- src/util.hpp | 44 +++++++++++++++++++++++++++++------- 17 files changed, 238 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9524411e85..5f8d4580f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,16 +130,21 @@ else() add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES}) add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES}) add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES}) + if(MINGW) + set(UNIQUE_COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-comment") + elseif(MSVC) + set(UNIQUE_COMPILE_FLAGS "-D_MSVC") + endif() set_target_properties(embedded_lld_lib PROPERTIES - COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment" + COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" LINK_FLAGS " " ) set_target_properties(embedded_lld_elf PROPERTIES - COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment" + COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" LINK_FLAGS " " ) set_target_properties(embedded_lld_coff PROPERTIES - COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment" + COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" LINK_FLAGS " " ) target_include_directories(embedded_lld_lib PUBLIC @@ -211,14 +216,17 @@ include_directories( "${CMAKE_SOURCE_DIR}/src" ) -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall") - - +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") if(MINGW) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") endif() -set(EXE_CFLAGS "-std=c++11 -fno-exceptions -fno-rtti -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") +set(EXE_CFLAGS "-std=c++11") +if(MINGW) + set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") +elseif(MSVC) + set(EXE_CFLAGS "${EXE_CFLAGS} -D_MSVC") +endif() set(EXE_LDFLAGS " ") if(ZIG_TEST_COVERAGE) set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage") @@ -230,16 +238,23 @@ set_target_properties(zig PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} ) + +if(MINGW) + set(PLATFORM_LIBRARIES quadmath) +endif() target_link_libraries(zig LINK_PUBLIC ${CLANG_LIBRARIES} ${LLD_LIBRARIES} ${LLVM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - quadmath + ${PLATFORM_LIBRARIES} ) -if(MINGW) +if(MINGW OR MSVC) target_link_libraries(zig LINK_PUBLIC version) endif() +if(MSVC) + target_link_libraries(zig LINK_PUBLIC "C:/Program Files (x86)/Microsoft Visual Studio 14.0/DIA SDK/lib/diaguids.lib") +endif() install(TARGETS zig DESTINATION bin) install(FILES "${CMAKE_SOURCE_DIR}/c_headers/__clang_cuda_builtin_vars.h" DESTINATION "${C_HEADERS_DEST}") @@ -455,3 +470,4 @@ if (ZIG_TEST_COVERAGE) COMMAND rm coverage.info coverage.info.cleaned ) endif() + diff --git a/cmake/Findclang.cmake b/cmake/Findclang.cmake index 04d3fb0201..486999b530 100644 --- a/cmake/Findclang.cmake +++ b/cmake/Findclang.cmake @@ -8,14 +8,20 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h PATHS + ${LLVM_INSTALL_PREFIX}/include /usr/lib/llvm/5/include /usr/lib/llvm-5.0/include /mingw64/include) - macro(FIND_AND_ADD_CLANG_LIB _libname_) +if(NOT CLANG_INCLUDE_DIRS) + message(FATAL_ERROR "Failed to find CLANG header files") +endif() + +macro(FIND_AND_ADD_CLANG_LIB _libname_) string(TOUPPER ${_libname_} _prettylibname_) find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} PATHS + ${LLVM_INSTALL_PREFIX}/lib /usr/lib/llvm/5/lib /usr/lib/llvm-5.0/lib /mingw64/lib diff --git a/cmake/Findllvm.cmake b/cmake/Findllvm.cmake index 97e0a9a672..480bd17ce8 100644 --- a/cmake/Findllvm.cmake +++ b/cmake/Findllvm.cmake @@ -2,28 +2,53 @@ # This file is MIT licensed. # See http://opensource.org/licenses/MIT -# LLVM_FOUND # LLVM_INCLUDE_DIR # LLVM_LIBRARIES # LLVM_LIBDIRS -find_program(LLVM_CONFIG_EXE - NAMES llvm-config-5.0 llvm-config - PATHS - "/mingw64/bin" - "/c/msys64/mingw64/bin" - "c:/msys64/mingw64/bin" - "C:/Libraries/llvm-5.0.0/bin") +if(LLVM_INSTALL_PREFIX) + find_program(LLVM_CONFIG_EXE + NAMES llvm-config-5.0 llvm-config + PATHS ${LLVM_INSTALL_PREFIX}/bin + NO_DEFAULT_PATH) + if(NOT LLVM_CONFIG_EXE) + message(FATAL_ERROR "Invalid LLVM_INSTALL_PREFIX \"${LLVM_INSTALL_PREFIX}\", could not find llvm-config") + endif() +else() + find_program(LLVM_CONFIG_EXE + NAMES llvm-config-5.0 llvm-config + PATHS + "/mingw64/bin" + "/c/msys64/mingw64/bin" + "c:/msys64/mingw64/bin" + "C:/Libraries/llvm-5.0.0/bin") + if(NOT LLVM_CONFIG_EXE) + message(FATAL_ERROR "Could not find llvm-config, use -DLLVM_INSTALL_PREFIX to specify the install path") + endif() + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --prefix + OUTPUT_VARIABLE LLVM_INSTALL_PREFIX + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +if(${LLVM_INSTALL_PREFIX} MATCHES "^.* ") + # NOTE: this is a limitation due to llvm-config. If the path contains spaces then there's + # no way to tell from the output of llvm-config whether a space is seperating a filename, or + # just a space in the path name. + message(FATAL_ERROR "The LLVM install path \"${LLVM_INSTALL_PREFIX}\" cannot contain spaces") +endif() execute_process( COMMAND ${LLVM_CONFIG_EXE} --libs - OUTPUT_VARIABLE LLVM_LIBRARIES + OUTPUT_VARIABLE LLVM_LIBRARIES_STRING OUTPUT_STRIP_TRAILING_WHITESPACE) +string(REPLACE " " ";" LLVM_LIBRARIES ${LLVM_LIBRARIES_STRING}) execute_process( COMMAND ${LLVM_CONFIG_EXE} --system-libs - OUTPUT_VARIABLE LLVM_SYSTEM_LIBS + OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_STRING OUTPUT_STRIP_TRAILING_WHITESPACE) +string(REPLACE " " ";" LLVM_SYSTEM_LIBS ${LLVM_SYSTEM_LIBS_STRING}) execute_process( COMMAND ${LLVM_CONFIG_EXE} --libdir diff --git a/src/analyze.cpp b/src/analyze.cpp index bfc3bbfa71..5606e25bbf 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -163,7 +163,7 @@ static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *so } static uint8_t log2_u64(uint64_t x) { - return (63 - __builtin_clzll(x)); + return (63 - clzll(x)); } static uint8_t bits_needed_for_unsigned(uint64_t x) { diff --git a/src/bigfloat.hpp b/src/bigfloat.hpp index 1923bade0c..7355b0d5c9 100644 --- a/src/bigfloat.hpp +++ b/src/bigfloat.hpp @@ -13,6 +13,14 @@ #include #include +#if defined(_MSVC) +/* + * For now this is a placeholder until a better solution comes along to + * support 128-bit floats with MSVC. + */ +typedef long double __float128; +#endif + struct BigFloat { __float128 value; }; diff --git a/src/bigint.cpp b/src/bigint.cpp index 395d9fce80..66d4068d7a 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -141,7 +141,7 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) { dest->is_negative = false; } -void bigint_init_u128(BigInt *dest, unsigned __int128 x) { +void bigint_init_u128(BigInt *dest, uint128_t x) { uint64_t low = (uint64_t)(x & UINT64_MAX); uint64_t high = (uint64_t)(x >> 64); @@ -201,9 +201,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) { void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) { if (op->value >= 0) { - bigint_init_u128(dest, (unsigned __int128)(op->value)); + bigint_init_u128(dest, (uint128_t)(op->value)); } else { - bigint_init_u128(dest, (unsigned __int128)(-op->value)); + bigint_init_u128(dest, (uint128_t)(-op->value)); dest->is_negative = true; } } @@ -377,6 +377,41 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co } } +#if defined(_MSVC) +/* + * Inneficient implmentations for now + */ +static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { + *result = op1 + op2; + if(*result - op2 != op1) { + return true; // overflow + } + return false; // no overflow +} + +static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { + *result = op1 - op2; + if(*result > op1) + { + return true; // overflow + } + return false; // no overflow +} + +bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { + *result = op1 * op2; + if(op1 <= op2) { + if(*result / op1 != op2) { + return true; // overflow + } + } else { + if(*result / op2 != op1) { + return true; // overflow + } + } + return false; // no overflow +} +#else static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { return __builtin_uaddll_overflow((unsigned long long)op1, (unsigned long long)op2, (unsigned long long *)result); @@ -387,10 +422,11 @@ static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { (unsigned long long *)result); } -static bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { +bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { return __builtin_umulll_overflow((unsigned long long)op1, (unsigned long long)op2, (unsigned long long *)result); } +#endif void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { if (op1->digit_count == 0) { @@ -404,7 +440,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { const uint64_t *op1_digits = bigint_ptr(op1); const uint64_t *op2_digits = bigint_ptr(op2); - uint64_t overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit); + bool overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit); if (overflow == 0 && op1->digit_count == 1 && op2->digit_count == 1) { dest->digit_count = 1; bigint_normalize(dest); @@ -534,9 +570,9 @@ static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *car return; } - unsigned __int128 big_x = x; - unsigned __int128 big_y = y; - unsigned __int128 big_result = big_x * big_y; + uint128_t big_x = x; + uint128_t big_y = y; + uint128_t big_result = big_x * big_y; *carry = big_result >> 64; } diff --git a/src/bigint.hpp b/src/bigint.hpp index c77fb52245..242b640524 100644 --- a/src/bigint.hpp +++ b/src/bigint.hpp @@ -11,6 +11,15 @@ #include #include +#if defined(_MSVC) + // TEMPORARY WORKAROUND FOR MSVC NOT SUPPORTING __int128 + typedef long long int128_t; + typedef unsigned long long uint128_t; +#else + typedef __int128 int128_t; + typedef unsigned __int128 uint128_t; +#endif + struct BigInt { size_t digit_count; union { @@ -30,7 +39,7 @@ enum Cmp { }; void bigint_init_unsigned(BigInt *dest, uint64_t x); -void bigint_init_u128(BigInt *dest, unsigned __int128 x); +void bigint_init_u128(BigInt *dest, uint128_t x); void bigint_init_signed(BigInt *dest, int64_t x); void bigint_init_bigint(BigInt *dest, const BigInt *src); void bigint_init_bigfloat(BigInt *dest, const BigFloat *op); @@ -89,4 +98,6 @@ size_t bigint_bits_needed(const BigInt *op); // convenience functions Cmp bigint_cmp_zero(const BigInt *op); +bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result); + #endif diff --git a/src/buffer.hpp b/src/buffer.hpp index 8c732f93e2..67f7ab7588 100644 --- a/src/buffer.hpp +++ b/src/buffer.hpp @@ -24,7 +24,7 @@ struct Buf { }; Buf *buf_sprintf(const char *format, ...) - __attribute__ ((format (printf, 1, 2))); + ATTRIBUTE_FORMAT(printf, 1, 2); Buf *buf_vprintf(const char *format, va_list ap); static inline size_t buf_len(Buf *buf) { @@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) { } void buf_appendf(Buf *buf, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); + ATTRIBUTE_FORMAT(printf, 2, 3); static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) { assert(buf->list.length); diff --git a/src/codegen.cpp b/src/codegen.cpp index 15eac33683..5a273375f5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5194,7 +5194,19 @@ void codegen_add_object(CodeGen *g, Buf *object_path) { g->link_objects.append(object_path); } - +#if defined(_MSVC) +// MSVC doesn't seem to support "designators" for array initialization +static const char *c_int_type_names[] = { + "short", + "unsigned short", + "int", + "unsigned int", + "long", + "unsigned long", + "long long", + "unsigned long long", +}; +#else static const char *c_int_type_names[] = { [CIntTypeShort] = "short", [CIntTypeUShort] = "unsigned short", @@ -5205,6 +5217,7 @@ static const char *c_int_type_names[] = { [CIntTypeLongLong] = "long long", [CIntTypeULongLong] = "unsigned long long", }; +#endif static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { assert(type_entry); diff --git a/src/ir.cpp b/src/ir.cpp index 73f7b1df1e..a06fc261c4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6500,9 +6500,9 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { break; case 128: if (const_val->data.x_f128 >= 0) { - bigint_init_u128(bigint, (unsigned __int128)(const_val->data.x_f128)); + bigint_init_u128(bigint, (uint128_t)(const_val->data.x_f128)); } else { - bigint_init_u128(bigint, (unsigned __int128)(-const_val->data.x_f128)); + bigint_init_u128(bigint, (uint128_t)(-const_val->data.x_f128)); bigint->is_negative = true; } break; @@ -9731,8 +9731,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp uint64_t old_array_len = array_type->data.array.len; uint64_t new_array_len; - if (__builtin_umulll_overflow((unsigned long long)old_array_len, (unsigned long long)mult_amt, - (unsigned long long*)&new_array_len)) + if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) { ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); return ira->codegen->builtin_types.entry_invalid; diff --git a/src/os.cpp b/src/os.cpp index 363d6fbf32..65ca9d8cbe 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -25,6 +25,8 @@ #include #include + +typedef SSIZE_T ssize_t; #else #define ZIG_OS_POSIX @@ -620,7 +622,7 @@ int os_get_cwd(Buf *out_cwd) { bool os_stderr_tty(void) { #if defined(ZIG_OS_WINDOWS) - return _isatty(STDERR_FILENO) != 0; + return _isatty(_fileno(stderr)) != 0; #elif defined(ZIG_OS_POSIX) return isatty(STDERR_FILENO) != 0; #else @@ -777,12 +779,12 @@ int os_make_path(Buf *path) { int os_make_dir(Buf *path) { #if defined(ZIG_OS_WINDOWS) - if (mkdir(buf_ptr(path)) == -1) { - if (errno == EEXIST) + if (!CreateDirectory(buf_ptr(path), NULL)) { + if (GetLastError() == ERROR_ALREADY_EXISTS) return ErrorPathAlreadyExists; - if (errno == ENOENT) + if (GetLastError() == ERROR_PATH_NOT_FOUND) return ErrorFileNotFound; - if (errno == EACCES) + if (GetLastError() == ERROR_ACCESS_DENIED) return ErrorAccess; return ErrorUnexpected; } diff --git a/src/parsec.cpp b/src/parsec.cpp index 32462407ee..9bfb34ce76 100644 --- a/src/parsec.cpp +++ b/src/parsec.cpp @@ -56,7 +56,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); -__attribute__ ((format (printf, 3, 4))) +ATTRIBUTE_FORMAT(printf, 3, 4) static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { if (!c->warnings_on) { return; diff --git a/src/parser.cpp b/src/parser.cpp index c47d6a4789..9e63911a2a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -24,8 +24,8 @@ struct ParseContext { Buf *void_buf; }; -__attribute__ ((format (printf, 4, 5))) -__attribute__ ((noreturn)) +ATTRIBUTE_FORMAT(printf, 4, 5) +LLVM_ATTRIBUTE_NORETURN static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) { assert(node->type == NodeTypeAsmExpr); @@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const exit(EXIT_FAILURE); } -__attribute__ ((format (printf, 3, 4))) -__attribute__ ((noreturn)) +ATTRIBUTE_FORMAT(printf, 3, 4) +LLVM_ATTRIBUTE_NORETURN static void ast_error(ParseContext *pc, Token *token, const char *format, ...) { va_list ap; va_start(ap, format); @@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) { } } -__attribute__ ((noreturn)) +LLVM_ATTRIBUTE_NORETURN static void ast_invalid_token_error(ParseContext *pc, Token *token) { Buf token_value = BUF_INIT; ast_buf_from_token(pc, token, &token_value); diff --git a/src/parser.hpp b/src/parser.hpp index c95413309f..1434871adb 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -12,7 +12,7 @@ #include "tokenizer.hpp" #include "errmsg.hpp" -__attribute__ ((format (printf, 2, 3))) +ATTRIBUTE_FORMAT(printf, 2, 3) void ast_token_error(Token *token, const char *format, ...); diff --git a/src/quadmath.hpp b/src/quadmath.hpp index 7343a11e34..1c5621cbd8 100644 --- a/src/quadmath.hpp +++ b/src/quadmath.hpp @@ -8,12 +8,46 @@ #ifndef ZIG_QUADMATH_HPP #define ZIG_QUADMATH_HPP +#if defined(_MSVC) + #include + #include + #include + #include +#endif + extern "C" { +#if defined(_MSVC) + static __float128 fmodq(__float128 a, __float128 b) + { + return fmod(a, b); + } + static __float128 ceilq(__float128 a) + { + return ceil(a); + } + static __float128 floorq(__float128 a) + { + return floor(a); + } + static __float128 strtoflt128(const char *s, char **sp) + { + return strtold(s, sp); + } + static int quadmath_snprintf(char *s, size_t size, const char *format, ...) + { + va_list args; + va_start(format, args); + int result = vsnprintf(s, size, format, args); + va_end(args); + return result; + } +#else __float128 fmodq(__float128 a, __float128 b); __float128 ceilq(__float128 a); __float128 floorq(__float128 a); __float128 strtoflt128 (const char *s, char **sp); int quadmath_snprintf (char *s, size_t size, const char *format, ...); +#endif } #endif diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index c0c78c15f9..e99ad43f89 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -234,7 +234,7 @@ struct Tokenize { BigInt significand; }; -__attribute__ ((format (printf, 2, 3))) +ATTRIBUTE_FORMAT(printf, 2, 3) static void tokenize_error(Tokenize *t, const char *format, ...) { t->state = TokenizeStateError; @@ -331,7 +331,7 @@ static void end_float_token(Tokenize *t) { if (t->radix == 10) { zig_panic("TODO: decimal floats"); } else { - int significand_magnitude_in_bin = __builtin_clzll(1) - __builtin_clzll(significand); + int significand_magnitude_in_bin = clzll(1) - clzll(significand); t->exponent_in_bin_or_dec += significand_magnitude_in_bin; if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) { t->cur_tok->data.float_lit.overflow = true; diff --git a/src/util.hpp b/src/util.hpp index c57680138e..338170ce96 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -12,24 +12,52 @@ #include #include #include +#include #include +#if defined(_MSVC) + #define ATTRIBUTE_COLD + #define ATTRIBUTE_FORMAT(args) + static inline uint32_t popcnt(unsigned long long x) + { + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return x & 0x0000003f; + } + static inline uint32_t clzll(unsigned long long x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return 32 - popcnt(x); + } +#else + #define ATTRIBUTE_COLD __attribute__((cold)) + #define ATTRIBUTE_FORMAT(args) __attribute__((format (args))) + #define clzll(x) __builtin_clzll(x) +#endif + #define BREAKPOINT __asm("int $0x03") -void zig_panic(const char *format, ...) - __attribute__((cold)) - __attribute__ ((noreturn)) - __attribute__ ((format (printf, 1, 2))); +LLVM_ATTRIBUTE_NOINLINE +ATTRIBUTE_COLD +ATTRIBUTE_FORMAT(printf, 1, 2) +void zig_panic(const char *format, ...); -__attribute__((cold)) -__attribute__ ((noreturn)) +ATTRIBUTE_COLD +LLVM_ATTRIBUTE_NOINLINE static inline void zig_unreachable(void) { zig_panic("unreachable"); } template -__attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { +LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { T *ptr = reinterpret_cast(malloc(count * sizeof(T))); if (!ptr) zig_panic("allocation failed"); @@ -37,7 +65,7 @@ __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { } template -__attribute__((malloc)) static inline T *allocate(size_t count) { +LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { T *ptr = reinterpret_cast(calloc(count, sizeof(T))); if (!ptr) zig_panic("allocation failed"); From 67021e2bfff0b9caea432fd996031ab880afdbc5 Mon Sep 17 00:00:00 2001 From: Jonathan Marler Date: Mon, 11 Sep 2017 18:27:41 -0600 Subject: [PATCH 2/3] Modified cmake to use LLVM imported packages. --- CMakeLists.txt | 81 ++++++++++++++++++++++++++++++++++++++++--- cmake/Findclang.cmake | 50 -------------------------- cmake/Findllvm.cmake | 75 --------------------------------------- 3 files changed, 77 insertions(+), 129 deletions(-) delete mode 100644 cmake/Findclang.cmake delete mode 100644 cmake/Findllvm.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f8d4580f7..613fc5e0f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,13 +26,86 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) # git log -p -- deps/lld option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF) +find_package(LLVM REQUIRED CONFIG) +include_directories(${LLVM_INCLUDE_DIRS}) -find_package(llvm) -include_directories(${LLVM_INCLUDE_DIR}) -link_directories(${LLVM_LIBDIRS}) +# TODO: this currently doesn't work, it currently defines UNICODE but zig +# uses MBCS +#add_definitions(${LLVM_DEFINITIONS}) -find_package(clang) +link_directories(${LLVM_LIBRARY_DIRS}) +llvm_map_components_to_libnames(LLVM_LIBRARIES + LTO + Symbolize + XCoreDisassembler + XCoreCodeGen + XCoreAsmPrinter + SystemZDisassembler + SystemZCodeGen + SystemZAsmParser + SystemZAsmPrinter + SparcDisassembler + SparcCodeGen + SparcAsmParser + SparcAsmPrinter + PowerPCDisassembler + PowerPCCodeGen + PowerPCAsmParser + PowerPCAsmPrinter + NVPTXCodeGen + NVPTXAsmPrinter + MSP430CodeGen + MSP430AsmPrinter + MipsDisassembler + MipsCodeGen + MipsAsmParser + MipsAsmPrinter + LanaiDisassembler + LanaiCodeGen + LanaiAsmParser + LanaiAsmPrinter + HexagonDisassembler + HexagonCodeGen + HexagonAsmParser + BPFDisassembler + BPFCodeGen + BPFAsmPrinter + ARMDisassembler + ARMCodeGen + ARMAsmParser + ARMAsmPrinter + AMDGPUDisassembler + AMDGPUCodeGen + AMDGPUAsmParser + AMDGPUAsmPrinter + AArch64Disassembler + AArch64CodeGen + AArch64AsmParser + AArch64AsmPrinter + LibDriver + X86Disassembler + X86AsmParser + X86CodeGen + X86AsmPrinter + Core +) + +find_package(CLANG REQUIRED CONFIG) include_directories(${CLANG_INCLUDE_DIRS}) +set(CLANG_LIBRARIES + clangFrontend + clangDriver + clangSerialization + clangSema + clangAnalysis + clangAST + clangParse + clangSema + clangBasic + clangEdit + clangLex +) + if(ZIG_FORCE_EXTERNAL_LLD) find_package(lld) diff --git a/cmake/Findclang.cmake b/cmake/Findclang.cmake deleted file mode 100644 index 486999b530..0000000000 --- a/cmake/Findclang.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2016 Andrew Kelley -# This file is MIT licensed. -# See http://opensource.org/licenses/MIT - -# CLANG_FOUND -# CLANG_INCLUDE_DIRS -# CLANG_LIBRARIES - -find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h - PATHS - ${LLVM_INSTALL_PREFIX}/include - /usr/lib/llvm/5/include - /usr/lib/llvm-5.0/include - /mingw64/include) - -if(NOT CLANG_INCLUDE_DIRS) - message(FATAL_ERROR "Failed to find CLANG header files") -endif() - -macro(FIND_AND_ADD_CLANG_LIB _libname_) - string(TOUPPER ${_libname_} _prettylibname_) - find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} - PATHS - ${LLVM_INSTALL_PREFIX}/lib - /usr/lib/llvm/5/lib - /usr/lib/llvm-5.0/lib - /mingw64/lib - /c/msys64/mingw64/lib - c:\\msys64\\mingw64\\lib) - if(CLANG_${_prettylibname_}_LIB) - set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB}) - endif() -endmacro(FIND_AND_ADD_CLANG_LIB) - -FIND_AND_ADD_CLANG_LIB(clangFrontend) -FIND_AND_ADD_CLANG_LIB(clangDriver) -FIND_AND_ADD_CLANG_LIB(clangSerialization) -FIND_AND_ADD_CLANG_LIB(clangSema) -FIND_AND_ADD_CLANG_LIB(clangAnalysis) -FIND_AND_ADD_CLANG_LIB(clangAST) -FIND_AND_ADD_CLANG_LIB(clangParse) -FIND_AND_ADD_CLANG_LIB(clangSema) -FIND_AND_ADD_CLANG_LIB(clangBasic) -FIND_AND_ADD_CLANG_LIB(clangEdit) -FIND_AND_ADD_CLANG_LIB(clangLex) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(CLANG DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS) - -mark_as_advanced(CLANG_INCLUDE_DIRS CLANG_LIBRARIES) diff --git a/cmake/Findllvm.cmake b/cmake/Findllvm.cmake deleted file mode 100644 index 480bd17ce8..0000000000 --- a/cmake/Findllvm.cmake +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2014 Andrew Kelley -# This file is MIT licensed. -# See http://opensource.org/licenses/MIT - -# LLVM_INCLUDE_DIR -# LLVM_LIBRARIES -# LLVM_LIBDIRS - -if(LLVM_INSTALL_PREFIX) - find_program(LLVM_CONFIG_EXE - NAMES llvm-config-5.0 llvm-config - PATHS ${LLVM_INSTALL_PREFIX}/bin - NO_DEFAULT_PATH) - if(NOT LLVM_CONFIG_EXE) - message(FATAL_ERROR "Invalid LLVM_INSTALL_PREFIX \"${LLVM_INSTALL_PREFIX}\", could not find llvm-config") - endif() -else() - find_program(LLVM_CONFIG_EXE - NAMES llvm-config-5.0 llvm-config - PATHS - "/mingw64/bin" - "/c/msys64/mingw64/bin" - "c:/msys64/mingw64/bin" - "C:/Libraries/llvm-5.0.0/bin") - if(NOT LLVM_CONFIG_EXE) - message(FATAL_ERROR "Could not find llvm-config, use -DLLVM_INSTALL_PREFIX to specify the install path") - endif() - execute_process( - COMMAND ${LLVM_CONFIG_EXE} --prefix - OUTPUT_VARIABLE LLVM_INSTALL_PREFIX - OUTPUT_STRIP_TRAILING_WHITESPACE) -endif() - -if(${LLVM_INSTALL_PREFIX} MATCHES "^.* ") - # NOTE: this is a limitation due to llvm-config. If the path contains spaces then there's - # no way to tell from the output of llvm-config whether a space is seperating a filename, or - # just a space in the path name. - message(FATAL_ERROR "The LLVM install path \"${LLVM_INSTALL_PREFIX}\" cannot contain spaces") -endif() - -execute_process( - COMMAND ${LLVM_CONFIG_EXE} --libs - OUTPUT_VARIABLE LLVM_LIBRARIES_STRING - OUTPUT_STRIP_TRAILING_WHITESPACE) -string(REPLACE " " ";" LLVM_LIBRARIES ${LLVM_LIBRARIES_STRING}) - -execute_process( - COMMAND ${LLVM_CONFIG_EXE} --system-libs - OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_STRING - OUTPUT_STRIP_TRAILING_WHITESPACE) -string(REPLACE " " ";" LLVM_SYSTEM_LIBS ${LLVM_SYSTEM_LIBS_STRING}) - -execute_process( - COMMAND ${LLVM_CONFIG_EXE} --libdir - OUTPUT_VARIABLE LLVM_LIBDIRS - OUTPUT_STRIP_TRAILING_WHITESPACE) - -execute_process( - COMMAND ${LLVM_CONFIG_EXE} --includedir - OUTPUT_VARIABLE LLVM_INCLUDE_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - -find_library(LLVM_LIBRARY NAMES LLVM) - -set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS}) - -if(LLVM_LIBRARY) - set(LLVM_LIBRARIES ${LLVM_LIBRARY}) -endif() - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIR) - -mark_as_advanced(LLVM_INCLUDE_DIR LLVM_LIBRARIES LLVM_LIBDIRS) From 57ea6e8c9f204be6d38177024d3b8f1aba4e05b2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 13 Sep 2017 00:17:19 -0400 Subject: [PATCH 3/3] fix up msvc stuff to make it work on linux and macos too --- .gitignore | 8 +-- CMakeLists.txt | 124 +++++++++--------------------------------- cmake/Findclang.cmake | 63 +++++++++++++++++++++ cmake/Findllvm.cmake | 116 +++++++++++++++++++++++++++++++++++++++ src/bigfloat.hpp | 7 +-- src/bigint.cpp | 37 +++++-------- src/bigint.hpp | 2 +- src/buffer.hpp | 4 +- src/codegen.cpp | 15 +---- src/parsec.cpp | 2 +- src/parser.cpp | 10 ++-- src/parser.hpp | 2 +- src/quadmath.hpp | 64 +++++++++++----------- src/tokenizer.cpp | 2 +- src/util.hpp | 65 ++++++++++++---------- 15 files changed, 299 insertions(+), 222 deletions(-) create mode 100644 cmake/Findclang.cmake create mode 100644 cmake/Findllvm.cmake diff --git a/.gitignore b/.gitignore index 02980cf05c..20b208975a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,3 @@ zig-cache/ build/ -build-release/ -build-windows/ -build-llvm4-debug/ -build-llvm5-debug/ -/.cproject -/.project -/.settings/ +build-*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 613fc5e0f4..ccb6b9583f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,86 +26,11 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) # git log -p -- deps/lld option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF) -find_package(LLVM REQUIRED CONFIG) +find_package(llvm) include_directories(${LLVM_INCLUDE_DIRS}) -# TODO: this currently doesn't work, it currently defines UNICODE but zig -# uses MBCS -#add_definitions(${LLVM_DEFINITIONS}) - -link_directories(${LLVM_LIBRARY_DIRS}) -llvm_map_components_to_libnames(LLVM_LIBRARIES - LTO - Symbolize - XCoreDisassembler - XCoreCodeGen - XCoreAsmPrinter - SystemZDisassembler - SystemZCodeGen - SystemZAsmParser - SystemZAsmPrinter - SparcDisassembler - SparcCodeGen - SparcAsmParser - SparcAsmPrinter - PowerPCDisassembler - PowerPCCodeGen - PowerPCAsmParser - PowerPCAsmPrinter - NVPTXCodeGen - NVPTXAsmPrinter - MSP430CodeGen - MSP430AsmPrinter - MipsDisassembler - MipsCodeGen - MipsAsmParser - MipsAsmPrinter - LanaiDisassembler - LanaiCodeGen - LanaiAsmParser - LanaiAsmPrinter - HexagonDisassembler - HexagonCodeGen - HexagonAsmParser - BPFDisassembler - BPFCodeGen - BPFAsmPrinter - ARMDisassembler - ARMCodeGen - ARMAsmParser - ARMAsmPrinter - AMDGPUDisassembler - AMDGPUCodeGen - AMDGPUAsmParser - AMDGPUAsmPrinter - AArch64Disassembler - AArch64CodeGen - AArch64AsmParser - AArch64AsmPrinter - LibDriver - X86Disassembler - X86AsmParser - X86CodeGen - X86AsmPrinter - Core -) - -find_package(CLANG REQUIRED CONFIG) +find_package(clang) include_directories(${CLANG_INCLUDE_DIRS}) -set(CLANG_LIBRARIES - clangFrontend - clangDriver - clangSerialization - clangSema - clangAnalysis - clangAST - clangParse - clangSema - clangBasic - clangEdit - clangLex -) - if(ZIG_FORCE_EXTERNAL_LLD) find_package(lld) @@ -203,21 +128,21 @@ else() add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES}) add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES}) add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES}) - if(MINGW) - set(UNIQUE_COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-comment") - elseif(MSVC) - set(UNIQUE_COMPILE_FLAGS "-D_MSVC") + if(MSVC) + set(ZIG_LLD_COMPILE_FLAGS "-std=c++11") + else() + set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment") endif() set_target_properties(embedded_lld_lib PROPERTIES - COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" + COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} LINK_FLAGS " " ) set_target_properties(embedded_lld_elf PROPERTIES - COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" + COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} LINK_FLAGS " " ) set_target_properties(embedded_lld_coff PROPERTIES - COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" + COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS} LINK_FLAGS " " ) target_include_directories(embedded_lld_lib PUBLIC @@ -289,17 +214,20 @@ include_directories( "${CMAKE_SOURCE_DIR}/src" ) -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") -if(MINGW) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") +if(MSVC) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -W4") +elseif(MINGW) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") +else() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall") endif() -set(EXE_CFLAGS "-std=c++11") -if(MINGW) - set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") -elseif(MSVC) - set(EXE_CFLAGS "${EXE_CFLAGS} -D_MSVC") +if(MSVC) + set(EXE_CFLAGS "-std=c++11") +else() + set(EXE_CFLAGS "-std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") endif() + set(EXE_LDFLAGS " ") if(ZIG_TEST_COVERAGE) set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage") @@ -312,9 +240,6 @@ set_target_properties(zig PROPERTIES LINK_FLAGS ${EXE_LDFLAGS} ) -if(MINGW) - set(PLATFORM_LIBRARIES quadmath) -endif() target_link_libraries(zig LINK_PUBLIC ${CLANG_LIBRARIES} ${LLD_LIBRARIES} @@ -322,11 +247,12 @@ target_link_libraries(zig LINK_PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${PLATFORM_LIBRARIES} ) -if(MINGW OR MSVC) - target_link_libraries(zig LINK_PUBLIC version) -endif() if(MSVC) - target_link_libraries(zig LINK_PUBLIC "C:/Program Files (x86)/Microsoft Visual Studio 14.0/DIA SDK/lib/diaguids.lib") + target_link_libraries(zig LINK_PUBLIC version) +elseif(MINGW) + target_link_libraries(zig LINK_PUBLIC version quadmath) +else() + target_link_libraries(zig LINK_PUBLIC quadmath) endif() install(TARGETS zig DESTINATION bin) diff --git a/cmake/Findclang.cmake b/cmake/Findclang.cmake new file mode 100644 index 0000000000..4c4a13e6ce --- /dev/null +++ b/cmake/Findclang.cmake @@ -0,0 +1,63 @@ +# Copyright (c) 2016 Andrew Kelley +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# CLANG_FOUND +# CLANG_INCLUDE_DIRS +# CLANG_LIBRARIES + +if(MSVC) + find_package(CLANG REQUIRED CONFIG) + + set(CLANG_LIBRARIES + clangFrontend + clangDriver + clangSerialization + clangSema + clangAnalysis + clangAST + clangParse + clangSema + clangBasic + clangEdit + clangLex + ) + +else() + find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h + PATHS + /usr/lib/llvm/5/include + /usr/lib/llvm-5.0/include + /mingw64/include) + + macro(FIND_AND_ADD_CLANG_LIB _libname_) + string(TOUPPER ${_libname_} _prettylibname_) + find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} + PATHS + /usr/lib/llvm/5/lib + /usr/lib/llvm-5.0/lib + /mingw64/lib + /c/msys64/mingw64/lib + c:\\msys64\\mingw64\\lib) + if(CLANG_${_prettylibname_}_LIB) + set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB}) + endif() + endmacro(FIND_AND_ADD_CLANG_LIB) + + FIND_AND_ADD_CLANG_LIB(clangFrontend) + FIND_AND_ADD_CLANG_LIB(clangDriver) + FIND_AND_ADD_CLANG_LIB(clangSerialization) + FIND_AND_ADD_CLANG_LIB(clangSema) + FIND_AND_ADD_CLANG_LIB(clangAnalysis) + FIND_AND_ADD_CLANG_LIB(clangAST) + FIND_AND_ADD_CLANG_LIB(clangParse) + FIND_AND_ADD_CLANG_LIB(clangSema) + FIND_AND_ADD_CLANG_LIB(clangBasic) + FIND_AND_ADD_CLANG_LIB(clangEdit) + FIND_AND_ADD_CLANG_LIB(clangLex) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CLANG DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS) + +mark_as_advanced(CLANG_INCLUDE_DIRS CLANG_LIBRARIES) diff --git a/cmake/Findllvm.cmake b/cmake/Findllvm.cmake new file mode 100644 index 0000000000..b57107ca3a --- /dev/null +++ b/cmake/Findllvm.cmake @@ -0,0 +1,116 @@ +# Copyright (c) 2014 Andrew Kelley +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# LLVM_FOUND +# LLVM_INCLUDE_DIRS +# LLVM_LIBRARIES +# LLVM_LIBDIRS + +if(MSVC) + find_package(LLVM REQUIRED CONFIG) + + # TODO: this currently doesn't work, it currently defines UNICODE but zig + # uses MBCS + #add_definitions(${LLVM_DEFINITIONS}) + + link_directories(${LLVM_LIBRARY_DIRS}) + llvm_map_components_to_libnames(LLVM_LIBRARIES + LTO + Symbolize + XCoreDisassembler + XCoreCodeGen + XCoreAsmPrinter + SystemZDisassembler + SystemZCodeGen + SystemZAsmParser + SystemZAsmPrinter + SparcDisassembler + SparcCodeGen + SparcAsmParser + SparcAsmPrinter + PowerPCDisassembler + PowerPCCodeGen + PowerPCAsmParser + PowerPCAsmPrinter + NVPTXCodeGen + NVPTXAsmPrinter + MSP430CodeGen + MSP430AsmPrinter + MipsDisassembler + MipsCodeGen + MipsAsmParser + MipsAsmPrinter + LanaiDisassembler + LanaiCodeGen + LanaiAsmParser + LanaiAsmPrinter + HexagonDisassembler + HexagonCodeGen + HexagonAsmParser + BPFDisassembler + BPFCodeGen + BPFAsmPrinter + ARMDisassembler + ARMCodeGen + ARMAsmParser + ARMAsmPrinter + AMDGPUDisassembler + AMDGPUCodeGen + AMDGPUAsmParser + AMDGPUAsmPrinter + AArch64Disassembler + AArch64CodeGen + AArch64AsmParser + AArch64AsmPrinter + LibDriver + X86Disassembler + X86AsmParser + X86CodeGen + X86AsmPrinter + Core + ) + +else() + find_program(LLVM_CONFIG_EXE + NAMES llvm-config-5.0 llvm-config + PATHS + "/mingw64/bin" + "/c/msys64/mingw64/bin" + "c:/msys64/mingw64/bin" + "C:/Libraries/llvm-5.0.0/bin") + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --libs + OUTPUT_VARIABLE LLVM_LIBRARIES + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --system-libs + OUTPUT_VARIABLE LLVM_SYSTEM_LIBS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --libdir + OUTPUT_VARIABLE LLVM_LIBDIRS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + execute_process( + COMMAND ${LLVM_CONFIG_EXE} --includedir + OUTPUT_VARIABLE LLVM_INCLUDE_DIRS + OUTPUT_STRIP_TRAILING_WHITESPACE) + + find_library(LLVM_LIBRARY NAMES LLVM) + + set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS}) + + if(LLVM_LIBRARY) + set(LLVM_LIBRARIES ${LLVM_LIBRARY}) + endif() +endif() + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIRS) + +mark_as_advanced(LLVM_INCLUDE_DIRS LLVM_LIBRARIES LLVM_LIBDIRS) diff --git a/src/bigfloat.hpp b/src/bigfloat.hpp index 7355b0d5c9..0dba7cf155 100644 --- a/src/bigfloat.hpp +++ b/src/bigfloat.hpp @@ -13,11 +13,8 @@ #include #include -#if defined(_MSVC) -/* - * For now this is a placeholder until a better solution comes along to - * support 128-bit floats with MSVC. - */ +#if defined(_MSC_VER) +// TODO support 128 bit floats with msvc typedef long double __float128; #endif diff --git a/src/bigint.cpp b/src/bigint.cpp index 66d4068d7a..4da9ec2c71 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -377,39 +377,30 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co } } -#if defined(_MSVC) -/* - * Inneficient implmentations for now - */ +#if defined(_MSC_VER) static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { *result = op1 + op2; - if(*result - op2 != op1) { - return true; // overflow - } - return false; // no overflow + return *result < op1 || *result < op2; } static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { *result = op1 - op2; - if(*result > op1) - { - return true; // overflow - } - return false; // no overflow + return *result > op1; } bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { *result = op1 * op2; - if(op1 <= op2) { - if(*result / op1 != op2) { - return true; // overflow - } - } else { - if(*result / op2 != op1) { - return true; // overflow - } - } - return false; // no overflow + + if (op1 == 0 || op2 == 0) + return false; + + if (op1 > UINT64_MAX / op2) + return true; + + if (op2 > UINT64_MAX / op1) + return true; + + return false; } #else static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { diff --git a/src/bigint.hpp b/src/bigint.hpp index 242b640524..bb55506348 100644 --- a/src/bigint.hpp +++ b/src/bigint.hpp @@ -11,7 +11,7 @@ #include #include -#if defined(_MSVC) +#if defined(_MSC_VER) // TEMPORARY WORKAROUND FOR MSVC NOT SUPPORTING __int128 typedef long long int128_t; typedef unsigned long long uint128_t; diff --git a/src/buffer.hpp b/src/buffer.hpp index 67f7ab7588..c12d71956f 100644 --- a/src/buffer.hpp +++ b/src/buffer.hpp @@ -24,7 +24,7 @@ struct Buf { }; Buf *buf_sprintf(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); + ATTRIBUTE_PRINTF(1, 2); Buf *buf_vprintf(const char *format, va_list ap); static inline size_t buf_len(Buf *buf) { @@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) { } void buf_appendf(Buf *buf, const char *format, ...) - ATTRIBUTE_FORMAT(printf, 2, 3); + ATTRIBUTE_PRINTF(2, 3); static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) { assert(buf->list.length); diff --git a/src/codegen.cpp b/src/codegen.cpp index 5a273375f5..3d34eaacbf 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5194,8 +5194,7 @@ void codegen_add_object(CodeGen *g, Buf *object_path) { g->link_objects.append(object_path); } -#if defined(_MSVC) -// MSVC doesn't seem to support "designators" for array initialization +// Must be coordinated with with CIntType enum static const char *c_int_type_names[] = { "short", "unsigned short", @@ -5206,18 +5205,6 @@ static const char *c_int_type_names[] = { "long long", "unsigned long long", }; -#else -static const char *c_int_type_names[] = { - [CIntTypeShort] = "short", - [CIntTypeUShort] = "unsigned short", - [CIntTypeInt] = "int", - [CIntTypeUInt] = "unsigned int", - [CIntTypeLong] = "long", - [CIntTypeULong] = "unsigned long", - [CIntTypeLongLong] = "long long", - [CIntTypeULongLong] = "unsigned long long", -}; -#endif static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { assert(type_entry); diff --git a/src/parsec.cpp b/src/parsec.cpp index 9bfb34ce76..22f6136138 100644 --- a/src/parsec.cpp +++ b/src/parsec.cpp @@ -56,7 +56,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); -ATTRIBUTE_FORMAT(printf, 3, 4) +ATTRIBUTE_PRINTF(3, 4) static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { if (!c->warnings_on) { return; diff --git a/src/parser.cpp b/src/parser.cpp index 9e63911a2a..ba1fd99e57 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -24,8 +24,8 @@ struct ParseContext { Buf *void_buf; }; -ATTRIBUTE_FORMAT(printf, 4, 5) -LLVM_ATTRIBUTE_NORETURN +ATTRIBUTE_PRINTF(4, 5) +ATTRIBUTE_NORETURN static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) { assert(node->type == NodeTypeAsmExpr); @@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const exit(EXIT_FAILURE); } -ATTRIBUTE_FORMAT(printf, 3, 4) -LLVM_ATTRIBUTE_NORETURN +ATTRIBUTE_PRINTF(3, 4) +ATTRIBUTE_NORETURN static void ast_error(ParseContext *pc, Token *token, const char *format, ...) { va_list ap; va_start(ap, format); @@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) { } } -LLVM_ATTRIBUTE_NORETURN +ATTRIBUTE_NORETURN static void ast_invalid_token_error(ParseContext *pc, Token *token) { Buf token_value = BUF_INIT; ast_buf_from_token(pc, token, &token_value); diff --git a/src/parser.hpp b/src/parser.hpp index 1434871adb..6e9f002997 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -12,7 +12,7 @@ #include "tokenizer.hpp" #include "errmsg.hpp" -ATTRIBUTE_FORMAT(printf, 2, 3) +ATTRIBUTE_PRINTF(2, 3) void ast_token_error(Token *token, const char *format, ...); diff --git a/src/quadmath.hpp b/src/quadmath.hpp index 1c5621cbd8..4fefda2280 100644 --- a/src/quadmath.hpp +++ b/src/quadmath.hpp @@ -8,46 +8,44 @@ #ifndef ZIG_QUADMATH_HPP #define ZIG_QUADMATH_HPP -#if defined(_MSVC) - #include - #include - #include - #include -#endif +#if defined(_MSC_VER) +#include +#include +#include +#include + +static inline __float128 fmodq(__float128 a, __float128 b) { + return fmodl(a, b); +} + +static inline __float128 ceilq(__float128 a) { + return ceill(a); +} + +static inline __float128 floorq(__float128 a) { + return floorl(a); +} + +static inline __float128 strtoflt128(const char *s, char **sp) { + return strtold(s, sp); +} + +static inline int quadmath_snprintf(char *s, size_t size, const char *format, ...) { + va_list args; + va_start(format, args); + int result = vsnprintf(s, size, format, args); + va_end(args); + return result; +} -extern "C" { -#if defined(_MSVC) - static __float128 fmodq(__float128 a, __float128 b) - { - return fmod(a, b); - } - static __float128 ceilq(__float128 a) - { - return ceil(a); - } - static __float128 floorq(__float128 a) - { - return floor(a); - } - static __float128 strtoflt128(const char *s, char **sp) - { - return strtold(s, sp); - } - static int quadmath_snprintf(char *s, size_t size, const char *format, ...) - { - va_list args; - va_start(format, args); - int result = vsnprintf(s, size, format, args); - va_end(args); - return result; - } #else +extern "C" { __float128 fmodq(__float128 a, __float128 b); __float128 ceilq(__float128 a); __float128 floorq(__float128 a); __float128 strtoflt128 (const char *s, char **sp); int quadmath_snprintf (char *s, size_t size, const char *format, ...); -#endif } +#endif #endif diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index e99ad43f89..a7820678de 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -234,7 +234,7 @@ struct Tokenize { BigInt significand; }; -ATTRIBUTE_FORMAT(printf, 2, 3) +ATTRIBUTE_PRINTF(2, 3) static void tokenize_error(Tokenize *t, const char *format, ...) { t->state = TokenizeStateError; diff --git a/src/util.hpp b/src/util.hpp index 338170ce96..5ef63bed46 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -12,52 +12,57 @@ #include #include #include -#include #include -#if defined(_MSVC) - #define ATTRIBUTE_COLD - #define ATTRIBUTE_FORMAT(args) - static inline uint32_t popcnt(unsigned long long x) - { - x -= ((x >> 1) & 0x55555555); - x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); - x = (((x >> 4) + x) & 0x0f0f0f0f); - x += (x >> 8); - x += (x >> 16); - return x & 0x0000003f; - } - static inline uint32_t clzll(unsigned long long x) - { - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - return 32 - popcnt(x); - } +#if defined(_MSC_VER) + +#include + +#define ATTRIBUTE_COLD __declspec(noinline) +#define ATTRIBUTE_PRINTF(a, b) +#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict) +#define ATTRIBUTE_NORETURN __declspec(noreturn) + +static inline int clzll(unsigned long long mask) { + unsigned long lz; +#if defined(_WIN64) + if (_BitScanReverse64(&lz, mask)) + return static_cast(63-lz); + zig_unreachable(); #else - #define ATTRIBUTE_COLD __attribute__((cold)) - #define ATTRIBUTE_FORMAT(args) __attribute__((format (args))) - #define clzll(x) __builtin_clzll(x) + if (_BitScanReverse(&lz, mask >> 32)) + lz += 32; + else + _BitScanReverse(&lz, mask & 0xffffffff); + return 63 - lz; +#endif +} +#else + +#define ATTRIBUTE_COLD __attribute__((cold)) +#define ATTRIBUTE_PRINTF(a, b) __attribute__((format(printf, a, b))) +#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) +#define ATTRIBUTE_NORETURN __attribute__((noreturn)) +#define clzll(x) __builtin_clzll(x) + #endif #define BREAKPOINT __asm("int $0x03") -LLVM_ATTRIBUTE_NOINLINE ATTRIBUTE_COLD -ATTRIBUTE_FORMAT(printf, 1, 2) +ATTRIBUTE_NORETURN +ATTRIBUTE_PRINTF(1, 2) void zig_panic(const char *format, ...); ATTRIBUTE_COLD -LLVM_ATTRIBUTE_NOINLINE +ATTRIBUTE_NORETURN static inline void zig_unreachable(void) { zig_panic("unreachable"); } template -LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { +ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { T *ptr = reinterpret_cast(malloc(count * sizeof(T))); if (!ptr) zig_panic("allocation failed"); @@ -65,7 +70,7 @@ LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { } template -LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { +ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { T *ptr = reinterpret_cast(calloc(count, sizeof(T))); if (!ptr) zig_panic("allocation failed");