authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-13 02:42:00-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-13 02:42:00-04:00
log5931a6b1a5b8f4941fc9b78f8960745f81594f17
tree0a9897aab096767288688216aa68d3809e2d77fe
parent373785ae8d49d0ae3785020f05573763268ee9e1
parent57ea6e8c9f204be6d38177024d3b8f1aba4e05b2

Merge branch 'msvc'

Now the supported compilers of Zig are: * GCC * Clang * MSVC * MinGW

18 files changed, 331 insertions(+), 128 deletions(-)

.gitignore+1-7
...@@ -1,9 +1,3 @@...@@ -1,9 +1,3 @@
1zig-cache/1zig-cache/
2build/2build/
3build-release/3build-*/
4build-windows/
5build-llvm4-debug/
6build-llvm5-debug/
7/.cproject
8/.project
9/.settings/
CMakeLists.txt+28-13
...@@ -26,10 +26,8 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)...@@ -26,10 +26,8 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
26# git log -p -- deps/lld26# git log -p -- deps/lld
27option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF)27option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF)
2828
29
30find_package(llvm)29find_package(llvm)
31include_directories(${LLVM_INCLUDE_DIR})30include_directories(${LLVM_INCLUDE_DIRS})
32link_directories(${LLVM_LIBDIRS})
3331
34find_package(clang)32find_package(clang)
35include_directories(${CLANG_INCLUDE_DIRS})33include_directories(${CLANG_INCLUDE_DIRS})
...@@ -130,16 +128,21 @@ else()...@@ -130,16 +128,21 @@ else()
130 add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES})128 add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES})
131 add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES})129 add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES})
132 add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES})130 add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES})
131 if(MSVC)
132 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11")
133 else()
134 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment")
135 endif()
133 set_target_properties(embedded_lld_lib PROPERTIES136 set_target_properties(embedded_lld_lib PROPERTIES
134 COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment"137 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}
135 LINK_FLAGS " "138 LINK_FLAGS " "
136 )139 )
137 set_target_properties(embedded_lld_elf PROPERTIES140 set_target_properties(embedded_lld_elf PROPERTIES
138 COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment"141 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}
139 LINK_FLAGS " "142 LINK_FLAGS " "
140 )143 )
141 set_target_properties(embedded_lld_coff PROPERTIES144 set_target_properties(embedded_lld_coff PROPERTIES
142 COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment"145 COMPILE_FLAGS ${ZIG_LLD_COMPILE_FLAGS}
143 LINK_FLAGS " "146 LINK_FLAGS " "
144 )147 )
145 target_include_directories(embedded_lld_lib PUBLIC148 target_include_directories(embedded_lld_lib PUBLIC
...@@ -211,14 +214,20 @@ include_directories(...@@ -211,14 +214,20 @@ include_directories(
211 "${CMAKE_SOURCE_DIR}/src"214 "${CMAKE_SOURCE_DIR}/src"
212)215)
213216
214set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall")217if(MSVC)
215218 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -W4")
219elseif(MINGW)
220 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args")
221else()
222 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall")
223endif()
216224
217if(MINGW)225if(MSVC)
218 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args")226 set(EXE_CFLAGS "-std=c++11")
227else()
228 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")
219endif()229endif()
220230
221set(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")
222set(EXE_LDFLAGS " ")231set(EXE_LDFLAGS " ")
223if(ZIG_TEST_COVERAGE)232if(ZIG_TEST_COVERAGE)
224 set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage")233 set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage")
...@@ -230,15 +239,20 @@ set_target_properties(zig PROPERTIES...@@ -230,15 +239,20 @@ set_target_properties(zig PROPERTIES
230 COMPILE_FLAGS ${EXE_CFLAGS}239 COMPILE_FLAGS ${EXE_CFLAGS}
231 LINK_FLAGS ${EXE_LDFLAGS}240 LINK_FLAGS ${EXE_LDFLAGS}
232)241)
242
233target_link_libraries(zig LINK_PUBLIC243target_link_libraries(zig LINK_PUBLIC
234 ${CLANG_LIBRARIES}244 ${CLANG_LIBRARIES}
235 ${LLD_LIBRARIES}245 ${LLD_LIBRARIES}
236 ${LLVM_LIBRARIES}246 ${LLVM_LIBRARIES}
237 ${CMAKE_THREAD_LIBS_INIT}247 ${CMAKE_THREAD_LIBS_INIT}
238 quadmath248 ${PLATFORM_LIBRARIES}
239)249)
240if(MINGW)250if(MSVC)
241 target_link_libraries(zig LINK_PUBLIC version)251 target_link_libraries(zig LINK_PUBLIC version)
252elseif(MINGW)
253 target_link_libraries(zig LINK_PUBLIC version quadmath)
254else()
255 target_link_libraries(zig LINK_PUBLIC quadmath)
242endif()256endif()
243install(TARGETS zig DESTINATION bin)257install(TARGETS zig DESTINATION bin)
244258
...@@ -455,3 +469,4 @@ if (ZIG_TEST_COVERAGE)...@@ -455,3 +469,4 @@ if (ZIG_TEST_COVERAGE)
455 COMMAND rm coverage.info coverage.info.cleaned469 COMMAND rm coverage.info coverage.info.cleaned
456 )470 )
457endif()471endif()
472
cmake/Findclang.cmake+50-31
...@@ -6,37 +6,56 @@...@@ -6,37 +6,56 @@
6# CLANG_INCLUDE_DIRS6# CLANG_INCLUDE_DIRS
7# CLANG_LIBRARIES7# CLANG_LIBRARIES
88
9find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h9if(MSVC)
10 PATHS10 find_package(CLANG REQUIRED CONFIG)
11 /usr/lib/llvm/5/include11
12 /usr/lib/llvm-5.0/include12 set(CLANG_LIBRARIES
13 /mingw64/include)13 clangFrontend
1414 clangDriver
15 macro(FIND_AND_ADD_CLANG_LIB _libname_)15 clangSerialization
16 string(TOUPPER ${_libname_} _prettylibname_)16 clangSema
17 find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}17 clangAnalysis
18 PATHS18 clangAST
19 /usr/lib/llvm/5/lib19 clangParse
20 /usr/lib/llvm-5.0/lib20 clangSema
21 /mingw64/lib21 clangBasic
22 /c/msys64/mingw64/lib22 clangEdit
23 c:\\msys64\\mingw64\\lib)23 clangLex
24 if(CLANG_${_prettylibname_}_LIB)24 )
25 set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB})25
26 endif()26else()
27endmacro(FIND_AND_ADD_CLANG_LIB)27 find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
2828 PATHS
29FIND_AND_ADD_CLANG_LIB(clangFrontend)29 /usr/lib/llvm/5/include
30FIND_AND_ADD_CLANG_LIB(clangDriver)30 /usr/lib/llvm-5.0/include
31FIND_AND_ADD_CLANG_LIB(clangSerialization)31 /mingw64/include)
32FIND_AND_ADD_CLANG_LIB(clangSema)32
33FIND_AND_ADD_CLANG_LIB(clangAnalysis)33 macro(FIND_AND_ADD_CLANG_LIB _libname_)
34FIND_AND_ADD_CLANG_LIB(clangAST)34 string(TOUPPER ${_libname_} _prettylibname_)
35FIND_AND_ADD_CLANG_LIB(clangParse)35 find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}
36FIND_AND_ADD_CLANG_LIB(clangSema)36 PATHS
37FIND_AND_ADD_CLANG_LIB(clangBasic)37 /usr/lib/llvm/5/lib
38FIND_AND_ADD_CLANG_LIB(clangEdit)38 /usr/lib/llvm-5.0/lib
39FIND_AND_ADD_CLANG_LIB(clangLex)39 /mingw64/lib
40 /c/msys64/mingw64/lib
41 c:\\msys64\\mingw64\\lib)
42 if(CLANG_${_prettylibname_}_LIB)
43 set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB})
44 endif()
45 endmacro(FIND_AND_ADD_CLANG_LIB)
46
47 FIND_AND_ADD_CLANG_LIB(clangFrontend)
48 FIND_AND_ADD_CLANG_LIB(clangDriver)
49 FIND_AND_ADD_CLANG_LIB(clangSerialization)
50 FIND_AND_ADD_CLANG_LIB(clangSema)
51 FIND_AND_ADD_CLANG_LIB(clangAnalysis)
52 FIND_AND_ADD_CLANG_LIB(clangAST)
53 FIND_AND_ADD_CLANG_LIB(clangParse)
54 FIND_AND_ADD_CLANG_LIB(clangSema)
55 FIND_AND_ADD_CLANG_LIB(clangBasic)
56 FIND_AND_ADD_CLANG_LIB(clangEdit)
57 FIND_AND_ADD_CLANG_LIB(clangLex)
58endif()
4059
41include(FindPackageHandleStandardArgs)60include(FindPackageHandleStandardArgs)
42find_package_handle_standard_args(CLANG DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS)61find_package_handle_standard_args(CLANG DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS)
cmake/Findllvm.cmake+96-30
...@@ -3,48 +3,114 @@...@@ -3,48 +3,114 @@
3# See http://opensource.org/licenses/MIT3# See http://opensource.org/licenses/MIT
44
5# LLVM_FOUND5# LLVM_FOUND
6# LLVM_INCLUDE_DIR6# LLVM_INCLUDE_DIRS
7# LLVM_LIBRARIES7# LLVM_LIBRARIES
8# LLVM_LIBDIRS8# LLVM_LIBDIRS
99
10find_program(LLVM_CONFIG_EXE10if(MSVC)
11 NAMES llvm-config-5.0 llvm-config11 find_package(LLVM REQUIRED CONFIG)
12 PATHS
13 "/mingw64/bin"
14 "/c/msys64/mingw64/bin"
15 "c:/msys64/mingw64/bin"
16 "C:/Libraries/llvm-5.0.0/bin")
1712
18execute_process(13 # TODO: this currently doesn't work, it currently defines UNICODE but zig
19 COMMAND ${LLVM_CONFIG_EXE} --libs14 # uses MBCS
20 OUTPUT_VARIABLE LLVM_LIBRARIES15 #add_definitions(${LLVM_DEFINITIONS})
21 OUTPUT_STRIP_TRAILING_WHITESPACE)
2216
23execute_process(17 link_directories(${LLVM_LIBRARY_DIRS})
24 COMMAND ${LLVM_CONFIG_EXE} --system-libs18 llvm_map_components_to_libnames(LLVM_LIBRARIES
25 OUTPUT_VARIABLE LLVM_SYSTEM_LIBS19 LTO
26 OUTPUT_STRIP_TRAILING_WHITESPACE)20 Symbolize
21 XCoreDisassembler
22 XCoreCodeGen
23 XCoreAsmPrinter
24 SystemZDisassembler
25 SystemZCodeGen
26 SystemZAsmParser
27 SystemZAsmPrinter
28 SparcDisassembler
29 SparcCodeGen
30 SparcAsmParser
31 SparcAsmPrinter
32 PowerPCDisassembler
33 PowerPCCodeGen
34 PowerPCAsmParser
35 PowerPCAsmPrinter
36 NVPTXCodeGen
37 NVPTXAsmPrinter
38 MSP430CodeGen
39 MSP430AsmPrinter
40 MipsDisassembler
41 MipsCodeGen
42 MipsAsmParser
43 MipsAsmPrinter
44 LanaiDisassembler
45 LanaiCodeGen
46 LanaiAsmParser
47 LanaiAsmPrinter
48 HexagonDisassembler
49 HexagonCodeGen
50 HexagonAsmParser
51 BPFDisassembler
52 BPFCodeGen
53 BPFAsmPrinter
54 ARMDisassembler
55 ARMCodeGen
56 ARMAsmParser
57 ARMAsmPrinter
58 AMDGPUDisassembler
59 AMDGPUCodeGen
60 AMDGPUAsmParser
61 AMDGPUAsmPrinter
62 AArch64Disassembler
63 AArch64CodeGen
64 AArch64AsmParser
65 AArch64AsmPrinter
66 LibDriver
67 X86Disassembler
68 X86AsmParser
69 X86CodeGen
70 X86AsmPrinter
71 Core
72 )
2773
28execute_process(74else()
29 COMMAND ${LLVM_CONFIG_EXE} --libdir75 find_program(LLVM_CONFIG_EXE
30 OUTPUT_VARIABLE LLVM_LIBDIRS76 NAMES llvm-config-5.0 llvm-config
31 OUTPUT_STRIP_TRAILING_WHITESPACE)77 PATHS
78 "/mingw64/bin"
79 "/c/msys64/mingw64/bin"
80 "c:/msys64/mingw64/bin"
81 "C:/Libraries/llvm-5.0.0/bin")
3282
33execute_process(83 execute_process(
34 COMMAND ${LLVM_CONFIG_EXE} --includedir84 COMMAND ${LLVM_CONFIG_EXE} --libs
35 OUTPUT_VARIABLE LLVM_INCLUDE_DIR85 OUTPUT_VARIABLE LLVM_LIBRARIES
36 OUTPUT_STRIP_TRAILING_WHITESPACE)86 OUTPUT_STRIP_TRAILING_WHITESPACE)
3787
38find_library(LLVM_LIBRARY NAMES LLVM)88 execute_process(
89 COMMAND ${LLVM_CONFIG_EXE} --system-libs
90 OUTPUT_VARIABLE LLVM_SYSTEM_LIBS
91 OUTPUT_STRIP_TRAILING_WHITESPACE)
3992
40set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS})93 execute_process(
94 COMMAND ${LLVM_CONFIG_EXE} --libdir
95 OUTPUT_VARIABLE LLVM_LIBDIRS
96 OUTPUT_STRIP_TRAILING_WHITESPACE)
4197
42if(LLVM_LIBRARY)98 execute_process(
43 set(LLVM_LIBRARIES ${LLVM_LIBRARY})99 COMMAND ${LLVM_CONFIG_EXE} --includedir
100 OUTPUT_VARIABLE LLVM_INCLUDE_DIRS
101 OUTPUT_STRIP_TRAILING_WHITESPACE)
102
103 find_library(LLVM_LIBRARY NAMES LLVM)
104
105 set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS})
106
107 if(LLVM_LIBRARY)
108 set(LLVM_LIBRARIES ${LLVM_LIBRARY})
109 endif()
44endif()110endif()
45111
46112
47include(FindPackageHandleStandardArgs)113include(FindPackageHandleStandardArgs)
48find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIR)114find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIRS)
49115
50mark_as_advanced(LLVM_INCLUDE_DIR LLVM_LIBRARIES LLVM_LIBDIRS)116mark_as_advanced(LLVM_INCLUDE_DIRS LLVM_LIBRARIES LLVM_LIBDIRS)
src/analyze.cpp+1-1
...@@ -163,7 +163,7 @@ static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *so...@@ -163,7 +163,7 @@ static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *so
163}163}
164164
165static uint8_t log2_u64(uint64_t x) {165static uint8_t log2_u64(uint64_t x) {
166 return (63 - __builtin_clzll(x));166 return (63 - clzll(x));
167}167}
168168
169static uint8_t bits_needed_for_unsigned(uint64_t x) {169static uint8_t bits_needed_for_unsigned(uint64_t x) {
src/bigfloat.hpp+5
...@@ -13,6 +13,11 @@...@@ -13,6 +13,11 @@
13#include <stdint.h>13#include <stdint.h>
14#include <stddef.h>14#include <stddef.h>
1515
16#if defined(_MSC_VER)
17// TODO support 128 bit floats with msvc
18typedef long double __float128;
19#endif
20
16struct BigFloat {21struct BigFloat {
17 __float128 value;22 __float128 value;
18};23};
src/bigint.cpp+35-8
...@@ -141,7 +141,7 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {...@@ -141,7 +141,7 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {
141 dest->is_negative = false;141 dest->is_negative = false;
142}142}
143143
144void bigint_init_u128(BigInt *dest, unsigned __int128 x) {144void bigint_init_u128(BigInt *dest, uint128_t x) {
145 uint64_t low = (uint64_t)(x & UINT64_MAX);145 uint64_t low = (uint64_t)(x & UINT64_MAX);
146 uint64_t high = (uint64_t)(x >> 64);146 uint64_t high = (uint64_t)(x >> 64);
147147
...@@ -201,9 +201,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {...@@ -201,9 +201,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {
201201
202void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {202void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
203 if (op->value >= 0) {203 if (op->value >= 0) {
204 bigint_init_u128(dest, (unsigned __int128)(op->value));204 bigint_init_u128(dest, (uint128_t)(op->value));
205 } else {205 } else {
206 bigint_init_u128(dest, (unsigned __int128)(-op->value));206 bigint_init_u128(dest, (uint128_t)(-op->value));
207 dest->is_negative = true;207 dest->is_negative = true;
208 }208 }
209}209}
...@@ -377,6 +377,32 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co...@@ -377,6 +377,32 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co
377 }377 }
378}378}
379379
380#if defined(_MSC_VER)
381static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
382 *result = op1 + op2;
383 return *result < op1 || *result < op2;
384}
385
386static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
387 *result = op1 - op2;
388 return *result > op1;
389}
390
391bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
392 *result = op1 * op2;
393
394 if (op1 == 0 || op2 == 0)
395 return false;
396
397 if (op1 > UINT64_MAX / op2)
398 return true;
399
400 if (op2 > UINT64_MAX / op1)
401 return true;
402
403 return false;
404}
405#else
380static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {406static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
381 return __builtin_uaddll_overflow((unsigned long long)op1, (unsigned long long)op2,407 return __builtin_uaddll_overflow((unsigned long long)op1, (unsigned long long)op2,
382 (unsigned long long *)result);408 (unsigned long long *)result);
...@@ -387,10 +413,11 @@ static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {...@@ -387,10 +413,11 @@ static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
387 (unsigned long long *)result);413 (unsigned long long *)result);
388}414}
389415
390static bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {416bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) {
391 return __builtin_umulll_overflow((unsigned long long)op1, (unsigned long long)op2,417 return __builtin_umulll_overflow((unsigned long long)op1, (unsigned long long)op2,
392 (unsigned long long *)result);418 (unsigned long long *)result);
393}419}
420#endif
394421
395void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {422void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {
396 if (op1->digit_count == 0) {423 if (op1->digit_count == 0) {
...@@ -404,7 +431,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -404,7 +431,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) {
404431
405 const uint64_t *op1_digits = bigint_ptr(op1);432 const uint64_t *op1_digits = bigint_ptr(op1);
406 const uint64_t *op2_digits = bigint_ptr(op2);433 const uint64_t *op2_digits = bigint_ptr(op2);
407 uint64_t overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit);434 bool overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit);
408 if (overflow == 0 && op1->digit_count == 1 && op2->digit_count == 1) {435 if (overflow == 0 && op1->digit_count == 1 && op2->digit_count == 1) {
409 dest->digit_count = 1;436 dest->digit_count = 1;
410 bigint_normalize(dest);437 bigint_normalize(dest);
...@@ -534,9 +561,9 @@ static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *car...@@ -534,9 +561,9 @@ static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *car
534 return;561 return;
535 }562 }
536563
537 unsigned __int128 big_x = x;564 uint128_t big_x = x;
538 unsigned __int128 big_y = y;565 uint128_t big_y = y;
539 unsigned __int128 big_result = big_x * big_y;566 uint128_t big_result = big_x * big_y;
540 *carry = big_result >> 64;567 *carry = big_result >> 64;
541}568}
542569
src/bigint.hpp+12-1
...@@ -11,6 +11,15 @@...@@ -11,6 +11,15 @@
11#include <stdint.h>11#include <stdint.h>
12#include <stddef.h>12#include <stddef.h>
1313
14#if defined(_MSC_VER)
15 // TEMPORARY WORKAROUND FOR MSVC NOT SUPPORTING __int128
16 typedef long long int128_t;
17 typedef unsigned long long uint128_t;
18#else
19 typedef __int128 int128_t;
20 typedef unsigned __int128 uint128_t;
21#endif
22
14struct BigInt {23struct BigInt {
15 size_t digit_count;24 size_t digit_count;
16 union {25 union {
...@@ -30,7 +39,7 @@ enum Cmp {...@@ -30,7 +39,7 @@ enum Cmp {
30};39};
3140
32void bigint_init_unsigned(BigInt *dest, uint64_t x);41void bigint_init_unsigned(BigInt *dest, uint64_t x);
33void bigint_init_u128(BigInt *dest, unsigned __int128 x);42void bigint_init_u128(BigInt *dest, uint128_t x);
34void bigint_init_signed(BigInt *dest, int64_t x);43void bigint_init_signed(BigInt *dest, int64_t x);
35void bigint_init_bigint(BigInt *dest, const BigInt *src);44void bigint_init_bigint(BigInt *dest, const BigInt *src);
36void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);45void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);
...@@ -89,4 +98,6 @@ size_t bigint_bits_needed(const BigInt *op);...@@ -89,4 +98,6 @@ size_t bigint_bits_needed(const BigInt *op);
89// convenience functions98// convenience functions
90Cmp bigint_cmp_zero(const BigInt *op);99Cmp bigint_cmp_zero(const BigInt *op);
91100
101bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);
102
92#endif103#endif
src/buffer.hpp+2-2
...@@ -24,7 +24,7 @@ struct Buf {...@@ -24,7 +24,7 @@ struct Buf {
24};24};
2525
26Buf *buf_sprintf(const char *format, ...)26Buf *buf_sprintf(const char *format, ...)
27 __attribute__ ((format (printf, 1, 2)));27 ATTRIBUTE_PRINTF(1, 2);
28Buf *buf_vprintf(const char *format, va_list ap);28Buf *buf_vprintf(const char *format, va_list ap);
2929
30static inline size_t buf_len(Buf *buf) {30static inline size_t buf_len(Buf *buf) {
...@@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) {...@@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) {
124}124}
125125
126void buf_appendf(Buf *buf, const char *format, ...)126void buf_appendf(Buf *buf, const char *format, ...)
127 __attribute__ ((format (printf, 2, 3)));127 ATTRIBUTE_PRINTF(2, 3);
128128
129static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) {129static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) {
130 assert(buf->list.length);130 assert(buf->list.length);
src/codegen.cpp+9-9
...@@ -5194,16 +5194,16 @@ void codegen_add_object(CodeGen *g, Buf *object_path) {...@@ -5194,16 +5194,16 @@ void codegen_add_object(CodeGen *g, Buf *object_path) {
5194 g->link_objects.append(object_path);5194 g->link_objects.append(object_path);
5195}5195}
51965196
51975197// Must be coordinated with with CIntType enum
5198static const char *c_int_type_names[] = {5198static const char *c_int_type_names[] = {
5199 [CIntTypeShort] = "short",5199 "short",
5200 [CIntTypeUShort] = "unsigned short",5200 "unsigned short",
5201 [CIntTypeInt] = "int",5201 "int",
5202 [CIntTypeUInt] = "unsigned int",5202 "unsigned int",
5203 [CIntTypeLong] = "long",5203 "long",
5204 [CIntTypeULong] = "unsigned long",5204 "unsigned long",
5205 [CIntTypeLongLong] = "long long",5205 "long long",
5206 [CIntTypeULongLong] = "unsigned long long",5206 "unsigned long long",
5207};5207};
52085208
5209static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {5209static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
src/ir.cpp+3-4
...@@ -6500,9 +6500,9 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {...@@ -6500,9 +6500,9 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {
6500 break;6500 break;
6501 case 128:6501 case 128:
6502 if (const_val->data.x_f128 >= 0) {6502 if (const_val->data.x_f128 >= 0) {
6503 bigint_init_u128(bigint, (unsigned __int128)(const_val->data.x_f128));6503 bigint_init_u128(bigint, (uint128_t)(const_val->data.x_f128));
6504 } else {6504 } else {
6505 bigint_init_u128(bigint, (unsigned __int128)(-const_val->data.x_f128));6505 bigint_init_u128(bigint, (uint128_t)(-const_val->data.x_f128));
6506 bigint->is_negative = true;6506 bigint->is_negative = true;
6507 }6507 }
6508 break;6508 break;
...@@ -9731,8 +9731,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp...@@ -9731,8 +9731,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp
9731 uint64_t old_array_len = array_type->data.array.len;9731 uint64_t old_array_len = array_type->data.array.len;
9732 uint64_t new_array_len;9732 uint64_t new_array_len;
97339733
9734 if (__builtin_umulll_overflow((unsigned long long)old_array_len, (unsigned long long)mult_amt,9734 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len))
9735 (unsigned long long*)&new_array_len))
9736 {9735 {
9737 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow"));9736 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow"));
9738 return ira->codegen->builtin_types.entry_invalid;9737 return ira->codegen->builtin_types.entry_invalid;
src/os.cpp+7-5
...@@ -25,6 +25,8 @@...@@ -25,6 +25,8 @@
2525
26#include <windows.h>26#include <windows.h>
27#include <io.h>27#include <io.h>
28
29typedef SSIZE_T ssize_t;
28#else30#else
29#define ZIG_OS_POSIX31#define ZIG_OS_POSIX
3032
...@@ -620,7 +622,7 @@ int os_get_cwd(Buf *out_cwd) {...@@ -620,7 +622,7 @@ int os_get_cwd(Buf *out_cwd) {
620622
621bool os_stderr_tty(void) {623bool os_stderr_tty(void) {
622#if defined(ZIG_OS_WINDOWS)624#if defined(ZIG_OS_WINDOWS)
623 return _isatty(STDERR_FILENO) != 0;625 return _isatty(_fileno(stderr)) != 0;
624#elif defined(ZIG_OS_POSIX)626#elif defined(ZIG_OS_POSIX)
625 return isatty(STDERR_FILENO) != 0;627 return isatty(STDERR_FILENO) != 0;
626#else628#else
...@@ -777,12 +779,12 @@ int os_make_path(Buf *path) {...@@ -777,12 +779,12 @@ int os_make_path(Buf *path) {
777779
778int os_make_dir(Buf *path) {780int os_make_dir(Buf *path) {
779#if defined(ZIG_OS_WINDOWS)781#if defined(ZIG_OS_WINDOWS)
780 if (mkdir(buf_ptr(path)) == -1) {782 if (!CreateDirectory(buf_ptr(path), NULL)) {
781 if (errno == EEXIST)783 if (GetLastError() == ERROR_ALREADY_EXISTS)
782 return ErrorPathAlreadyExists;784 return ErrorPathAlreadyExists;
783 if (errno == ENOENT)785 if (GetLastError() == ERROR_PATH_NOT_FOUND)
784 return ErrorFileNotFound;786 return ErrorFileNotFound;
785 if (errno == EACCES)787 if (GetLastError() == ERROR_ACCESS_DENIED)
786 return ErrorAccess;788 return ErrorAccess;
787 return ErrorUnexpected;789 return ErrorUnexpected;
788 }790 }
src/parsec.cpp+1-1
...@@ -56,7 +56,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);...@@ -56,7 +56,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
56static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);56static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
5757
5858
59__attribute__ ((format (printf, 3, 4)))59ATTRIBUTE_PRINTF(3, 4)
60static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {60static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
61 if (!c->warnings_on) {61 if (!c->warnings_on) {
62 return;62 return;
src/parser.cpp+5-5
...@@ -24,8 +24,8 @@ struct ParseContext {...@@ -24,8 +24,8 @@ struct ParseContext {
24 Buf *void_buf;24 Buf *void_buf;
25};25};
2626
27__attribute__ ((format (printf, 4, 5)))27ATTRIBUTE_PRINTF(4, 5)
28__attribute__ ((noreturn))28ATTRIBUTE_NORETURN
29static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) {29static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) {
30 assert(node->type == NodeTypeAsmExpr);30 assert(node->type == NodeTypeAsmExpr);
3131
...@@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const...@@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const
46 exit(EXIT_FAILURE);46 exit(EXIT_FAILURE);
47}47}
4848
49__attribute__ ((format (printf, 3, 4)))49ATTRIBUTE_PRINTF(3, 4)
50__attribute__ ((noreturn))50ATTRIBUTE_NORETURN
51static void ast_error(ParseContext *pc, Token *token, const char *format, ...) {51static void ast_error(ParseContext *pc, Token *token, const char *format, ...) {
52 va_list ap;52 va_list ap;
53 va_start(ap, format);53 va_start(ap, format);
...@@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) {...@@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) {
205 }205 }
206}206}
207207
208__attribute__ ((noreturn))208ATTRIBUTE_NORETURN
209static void ast_invalid_token_error(ParseContext *pc, Token *token) {209static void ast_invalid_token_error(ParseContext *pc, Token *token) {
210 Buf token_value = BUF_INIT;210 Buf token_value = BUF_INIT;
211 ast_buf_from_token(pc, token, &token_value);211 ast_buf_from_token(pc, token, &token_value);
src/parser.hpp+1-1
...@@ -12,7 +12,7 @@...@@ -12,7 +12,7 @@
12#include "tokenizer.hpp"12#include "tokenizer.hpp"
13#include "errmsg.hpp"13#include "errmsg.hpp"
1414
15__attribute__ ((format (printf, 2, 3)))15ATTRIBUTE_PRINTF(2, 3)
16void ast_token_error(Token *token, const char *format, ...);16void ast_token_error(Token *token, const char *format, ...);
1717
1818
src/quadmath.hpp+32
...@@ -8,6 +8,37 @@...@@ -8,6 +8,37 @@
8#ifndef ZIG_QUADMATH_HPP8#ifndef ZIG_QUADMATH_HPP
9#define ZIG_QUADMATH_HPP9#define ZIG_QUADMATH_HPP
1010
11#if defined(_MSC_VER)
12#include <stdlib.h>
13#include <stdio.h>
14#include <stdarg.h>
15#include <cmath>
16
17static inline __float128 fmodq(__float128 a, __float128 b) {
18 return fmodl(a, b);
19}
20
21static inline __float128 ceilq(__float128 a) {
22 return ceill(a);
23}
24
25static inline __float128 floorq(__float128 a) {
26 return floorl(a);
27}
28
29static inline __float128 strtoflt128(const char *s, char **sp) {
30 return strtold(s, sp);
31}
32
33static inline int quadmath_snprintf(char *s, size_t size, const char *format, ...) {
34 va_list args;
35 va_start(format, args);
36 int result = vsnprintf(s, size, format, args);
37 va_end(args);
38 return result;
39}
40
41#else
11extern "C" {42extern "C" {
12 __float128 fmodq(__float128 a, __float128 b);43 __float128 fmodq(__float128 a, __float128 b);
13 __float128 ceilq(__float128 a);44 __float128 ceilq(__float128 a);
...@@ -15,5 +46,6 @@ extern "C" {...@@ -15,5 +46,6 @@ extern "C" {
15 __float128 strtoflt128 (const char *s, char **sp);46 __float128 strtoflt128 (const char *s, char **sp);
16 int quadmath_snprintf (char *s, size_t size, const char *format, ...);47 int quadmath_snprintf (char *s, size_t size, const char *format, ...);
17}48}
49#endif
1850
19#endif51#endif
src/tokenizer.cpp+2-2
...@@ -234,7 +234,7 @@ struct Tokenize {...@@ -234,7 +234,7 @@ struct Tokenize {
234 BigInt significand;234 BigInt significand;
235};235};
236236
237__attribute__ ((format (printf, 2, 3)))237ATTRIBUTE_PRINTF(2, 3)
238static void tokenize_error(Tokenize *t, const char *format, ...) {238static void tokenize_error(Tokenize *t, const char *format, ...) {
239 t->state = TokenizeStateError;239 t->state = TokenizeStateError;
240240
...@@ -331,7 +331,7 @@ static void end_float_token(Tokenize *t) {...@@ -331,7 +331,7 @@ static void end_float_token(Tokenize *t) {
331 if (t->radix == 10) {331 if (t->radix == 10) {
332 zig_panic("TODO: decimal floats");332 zig_panic("TODO: decimal floats");
333 } else {333 } else {
334 int significand_magnitude_in_bin = __builtin_clzll(1) - __builtin_clzll(significand);334 int significand_magnitude_in_bin = clzll(1) - clzll(significand);
335 t->exponent_in_bin_or_dec += significand_magnitude_in_bin;335 t->exponent_in_bin_or_dec += significand_magnitude_in_bin;
336 if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) {336 if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) {
337 t->cur_tok->data.float_lit.overflow = true;337 t->cur_tok->data.float_lit.overflow = true;
src/util.hpp+41-8
...@@ -15,21 +15,54 @@...@@ -15,21 +15,54 @@
1515
16#include <new>16#include <new>
1717
18#if defined(_MSC_VER)
19
20#include <intrin.h>
21
22#define ATTRIBUTE_COLD __declspec(noinline)
23#define ATTRIBUTE_PRINTF(a, b)
24#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
25#define ATTRIBUTE_NORETURN __declspec(noreturn)
26
27static inline int clzll(unsigned long long mask) {
28 unsigned long lz;
29#if defined(_WIN64)
30 if (_BitScanReverse64(&lz, mask))
31 return static_cast<int>(63-lz);
32 zig_unreachable();
33#else
34 if (_BitScanReverse(&lz, mask >> 32))
35 lz += 32;
36 else
37 _BitScanReverse(&lz, mask & 0xffffffff);
38 return 63 - lz;
39#endif
40}
41#else
42
43#define ATTRIBUTE_COLD __attribute__((cold))
44#define ATTRIBUTE_PRINTF(a, b) __attribute__((format(printf, a, b)))
45#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
46#define ATTRIBUTE_NORETURN __attribute__((noreturn))
47#define clzll(x) __builtin_clzll(x)
48
49#endif
50
18#define BREAKPOINT __asm("int $0x03")51#define BREAKPOINT __asm("int $0x03")
1952
20void zig_panic(const char *format, ...)53ATTRIBUTE_COLD
21 __attribute__((cold))54ATTRIBUTE_NORETURN
22 __attribute__ ((noreturn))55ATTRIBUTE_PRINTF(1, 2)
23 __attribute__ ((format (printf, 1, 2)));56void zig_panic(const char *format, ...);
2457
25__attribute__((cold))58ATTRIBUTE_COLD
26__attribute__ ((noreturn))59ATTRIBUTE_NORETURN
27static inline void zig_unreachable(void) {60static inline void zig_unreachable(void) {
28 zig_panic("unreachable");61 zig_panic("unreachable");
29}62}
3063
31template<typename T>64template<typename T>
32__attribute__((malloc)) static inline T *allocate_nonzero(size_t count) {65ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
33 T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));66 T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
34 if (!ptr)67 if (!ptr)
35 zig_panic("allocation failed");68 zig_panic("allocation failed");
...@@ -37,7 +70,7 @@ __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) {...@@ -37,7 +70,7 @@ __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) {
37}70}
3871
39template<typename T>72template<typename T>
40__attribute__((malloc)) static inline T *allocate(size_t count) {73ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) {
41 T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));74 T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
42 if (!ptr)75 if (!ptr)
43 zig_panic("allocation failed");76 zig_panic("allocation failed");