| author | |
| committer | |
| log | 5931a6b1a5b8f4941fc9b78f8960745f81594f17 |
| tree | 0a9897aab096767288688216aa68d3809e2d77fe |
| parent | 373785ae8d49d0ae3785020f05573763268ee9e1 |
| parent | 57ea6e8c9f204be6d38177024d3b8f1aba4e05b2 |
Now the supported compilers of Zig are:
* GCC
* Clang
* MSVC
* MinGW18 files changed, 331 insertions(+), 128 deletions(-)
.gitignore+1-7| ... | ... | @@ -1,9 +1,3 @@ |
| 1 | 1 | zig-cache/ |
| 2 | 2 | build/ |
| 3 | build-release/ | |
| 4 | build-windows/ | |
| 5 | build-llvm4-debug/ | |
| 6 | build-llvm5-debug/ | |
| 7 | /.cproject | |
| 8 | /.project | |
| 9 | /.settings/ | |
| 3 | build-*/ |
CMakeLists.txt+28-13| ... | ... | @@ -26,10 +26,8 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) |
| 26 | 26 | # git log -p -- deps/lld |
| 27 | 27 | option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF) |
| 28 | 28 | |
| 29 | ||
| 30 | 29 | find_package(llvm) |
| 31 | include_directories(${LLVM_INCLUDE_DIR}) | |
| 32 | link_directories(${LLVM_LIBDIRS}) | |
| 30 | include_directories(${LLVM_INCLUDE_DIRS}) | |
| 33 | 31 | |
| 34 | 32 | find_package(clang) |
| 35 | 33 | include_directories(${CLANG_INCLUDE_DIRS}) |
| ... | ... | @@ -130,16 +128,21 @@ else() |
| 130 | 128 | add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES}) |
| 131 | 129 | add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES}) |
| 132 | 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 | 136 | 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 | 138 | LINK_FLAGS " " |
| 136 | 139 | ) |
| 137 | 140 | 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 | 142 | LINK_FLAGS " " |
| 140 | 143 | ) |
| 141 | 144 | 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 | 146 | LINK_FLAGS " " |
| 144 | 147 | ) |
| 145 | 148 | target_include_directories(embedded_lld_lib PUBLIC |
| ... | ... | @@ -211,14 +214,20 @@ include_directories( |
| 211 | 214 | "${CMAKE_SOURCE_DIR}/src" |
| 212 | 215 | ) |
| 213 | 216 | |
| 214 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall") | |
| 215 | ||
| 217 | if(MSVC) | |
| 218 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -W4") | |
| 219 | elseif(MINGW) | |
| 220 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") | |
| 221 | else() | |
| 222 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall") | |
| 223 | endif() | |
| 216 | 224 | |
| 217 | if(MINGW) | |
| 218 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") | |
| 225 | if(MSVC) | |
| 226 | set(EXE_CFLAGS "-std=c++11") | |
| 227 | else() | |
| 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") | |
| 219 | 229 | endif() |
| 220 | 230 | |
| 221 | 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") | |
| 222 | 231 | set(EXE_LDFLAGS " ") |
| 223 | 232 | if(ZIG_TEST_COVERAGE) |
| 224 | 233 | set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage") |
| ... | ... | @@ -230,15 +239,20 @@ set_target_properties(zig PROPERTIES |
| 230 | 239 | COMPILE_FLAGS ${EXE_CFLAGS} |
| 231 | 240 | LINK_FLAGS ${EXE_LDFLAGS} |
| 232 | 241 | ) |
| 242 | ||
| 233 | 243 | target_link_libraries(zig LINK_PUBLIC |
| 234 | 244 | ${CLANG_LIBRARIES} |
| 235 | 245 | ${LLD_LIBRARIES} |
| 236 | 246 | ${LLVM_LIBRARIES} |
| 237 | 247 | ${CMAKE_THREAD_LIBS_INIT} |
| 238 | quadmath | |
| 248 | ${PLATFORM_LIBRARIES} | |
| 239 | 249 | ) |
| 240 | if(MINGW) | |
| 250 | if(MSVC) | |
| 241 | 251 | target_link_libraries(zig LINK_PUBLIC version) |
| 252 | elseif(MINGW) | |
| 253 | target_link_libraries(zig LINK_PUBLIC version quadmath) | |
| 254 | else() | |
| 255 | target_link_libraries(zig LINK_PUBLIC quadmath) | |
| 242 | 256 | endif() |
| 243 | 257 | install(TARGETS zig DESTINATION bin) |
| 244 | 258 | |
| ... | ... | @@ -455,3 +469,4 @@ if (ZIG_TEST_COVERAGE) |
| 455 | 469 | COMMAND rm coverage.info coverage.info.cleaned |
| 456 | 470 | ) |
| 457 | 471 | endif() |
| 472 |
cmake/Findclang.cmake+50-31| ... | ... | @@ -6,37 +6,56 @@ |
| 6 | 6 | # CLANG_INCLUDE_DIRS |
| 7 | 7 | # CLANG_LIBRARIES |
| 8 | 8 | |
| 9 | find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h | |
| 10 | PATHS | |
| 11 | /usr/lib/llvm/5/include | |
| 12 | /usr/lib/llvm-5.0/include | |
| 13 | /mingw64/include) | |
| 14 | ||
| 15 | macro(FIND_AND_ADD_CLANG_LIB _libname_) | |
| 16 | string(TOUPPER ${_libname_} _prettylibname_) | |
| 17 | find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} | |
| 18 | PATHS | |
| 19 | /usr/lib/llvm/5/lib | |
| 20 | /usr/lib/llvm-5.0/lib | |
| 21 | /mingw64/lib | |
| 22 | /c/msys64/mingw64/lib | |
| 23 | c:\\msys64\\mingw64\\lib) | |
| 24 | if(CLANG_${_prettylibname_}_LIB) | |
| 25 | set(CLANG_LIBRARIES ${CLANG_LIBRARIES} ${CLANG_${_prettylibname_}_LIB}) | |
| 26 | endif() | |
| 27 | endmacro(FIND_AND_ADD_CLANG_LIB) | |
| 28 | ||
| 29 | FIND_AND_ADD_CLANG_LIB(clangFrontend) | |
| 30 | FIND_AND_ADD_CLANG_LIB(clangDriver) | |
| 31 | FIND_AND_ADD_CLANG_LIB(clangSerialization) | |
| 32 | FIND_AND_ADD_CLANG_LIB(clangSema) | |
| 33 | FIND_AND_ADD_CLANG_LIB(clangAnalysis) | |
| 34 | FIND_AND_ADD_CLANG_LIB(clangAST) | |
| 35 | FIND_AND_ADD_CLANG_LIB(clangParse) | |
| 36 | FIND_AND_ADD_CLANG_LIB(clangSema) | |
| 37 | FIND_AND_ADD_CLANG_LIB(clangBasic) | |
| 38 | FIND_AND_ADD_CLANG_LIB(clangEdit) | |
| 39 | FIND_AND_ADD_CLANG_LIB(clangLex) | |
| 9 | if(MSVC) | |
| 10 | find_package(CLANG REQUIRED CONFIG) | |
| 11 | ||
| 12 | set(CLANG_LIBRARIES | |
| 13 | clangFrontend | |
| 14 | clangDriver | |
| 15 | clangSerialization | |
| 16 | clangSema | |
| 17 | clangAnalysis | |
| 18 | clangAST | |
| 19 | clangParse | |
| 20 | clangSema | |
| 21 | clangBasic | |
| 22 | clangEdit | |
| 23 | clangLex | |
| 24 | ) | |
| 25 | ||
| 26 | else() | |
| 27 | find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h | |
| 28 | PATHS | |
| 29 | /usr/lib/llvm/5/include | |
| 30 | /usr/lib/llvm-5.0/include | |
| 31 | /mingw64/include) | |
| 32 | ||
| 33 | macro(FIND_AND_ADD_CLANG_LIB _libname_) | |
| 34 | string(TOUPPER ${_libname_} _prettylibname_) | |
| 35 | find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} | |
| 36 | PATHS | |
| 37 | /usr/lib/llvm/5/lib | |
| 38 | /usr/lib/llvm-5.0/lib | |
| 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) | |
| 58 | endif() | |
| 40 | 59 | |
| 41 | 60 | include(FindPackageHandleStandardArgs) |
| 42 | 61 | find_package_handle_standard_args(CLANG DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS) |
cmake/Findllvm.cmake+96-30| ... | ... | @@ -3,48 +3,114 @@ |
| 3 | 3 | # See http://opensource.org/licenses/MIT |
| 4 | 4 | |
| 5 | 5 | # LLVM_FOUND |
| 6 | # LLVM_INCLUDE_DIR | |
| 6 | # LLVM_INCLUDE_DIRS | |
| 7 | 7 | # LLVM_LIBRARIES |
| 8 | 8 | # LLVM_LIBDIRS |
| 9 | 9 | |
| 10 | find_program(LLVM_CONFIG_EXE | |
| 11 | NAMES llvm-config-5.0 llvm-config | |
| 12 | PATHS | |
| 13 | "/mingw64/bin" | |
| 14 | "/c/msys64/mingw64/bin" | |
| 15 | "c:/msys64/mingw64/bin" | |
| 16 | "C:/Libraries/llvm-5.0.0/bin") | |
| 10 | if(MSVC) | |
| 11 | find_package(LLVM REQUIRED CONFIG) | |
| 17 | 12 | |
| 18 | execute_process( | |
| 19 | COMMAND ${LLVM_CONFIG_EXE} --libs | |
| 20 | OUTPUT_VARIABLE LLVM_LIBRARIES | |
| 21 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| 13 | # TODO: this currently doesn't work, it currently defines UNICODE but zig | |
| 14 | # uses MBCS | |
| 15 | #add_definitions(${LLVM_DEFINITIONS}) | |
| 22 | 16 | |
| 23 | execute_process( | |
| 24 | COMMAND ${LLVM_CONFIG_EXE} --system-libs | |
| 25 | OUTPUT_VARIABLE LLVM_SYSTEM_LIBS | |
| 26 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| 17 | link_directories(${LLVM_LIBRARY_DIRS}) | |
| 18 | llvm_map_components_to_libnames(LLVM_LIBRARIES | |
| 19 | LTO | |
| 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 | ) | |
| 27 | 73 | |
| 28 | execute_process( | |
| 29 | COMMAND ${LLVM_CONFIG_EXE} --libdir | |
| 30 | OUTPUT_VARIABLE LLVM_LIBDIRS | |
| 31 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| 74 | else() | |
| 75 | find_program(LLVM_CONFIG_EXE | |
| 76 | NAMES llvm-config-5.0 llvm-config | |
| 77 | PATHS | |
| 78 | "/mingw64/bin" | |
| 79 | "/c/msys64/mingw64/bin" | |
| 80 | "c:/msys64/mingw64/bin" | |
| 81 | "C:/Libraries/llvm-5.0.0/bin") | |
| 32 | 82 | |
| 33 | execute_process( | |
| 34 | COMMAND ${LLVM_CONFIG_EXE} --includedir | |
| 35 | OUTPUT_VARIABLE LLVM_INCLUDE_DIR | |
| 36 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| 83 | execute_process( | |
| 84 | COMMAND ${LLVM_CONFIG_EXE} --libs | |
| 85 | OUTPUT_VARIABLE LLVM_LIBRARIES | |
| 86 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| 37 | 87 | |
| 38 | find_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) | |
| 39 | 92 | |
| 40 | set(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) | |
| 41 | 97 | |
| 42 | if(LLVM_LIBRARY) | |
| 43 | set(LLVM_LIBRARIES ${LLVM_LIBRARY}) | |
| 98 | execute_process( | |
| 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() | |
| 44 | 110 | endif() |
| 45 | 111 | |
| 46 | 112 | |
| 47 | 113 | include(FindPackageHandleStandardArgs) |
| 48 | find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIR) | |
| 114 | find_package_handle_standard_args(LLVM DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIRS) | |
| 49 | 115 | |
| 50 | mark_as_advanced(LLVM_INCLUDE_DIR LLVM_LIBRARIES LLVM_LIBDIRS) | |
| 116 | mark_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 | 163 | } |
| 164 | 164 | |
| 165 | 165 | static uint8_t log2_u64(uint64_t x) { |
| 166 | return (63 - __builtin_clzll(x)); | |
| 166 | return (63 - clzll(x)); | |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | static uint8_t bits_needed_for_unsigned(uint64_t x) { |
src/bigfloat.hpp+5| ... | ... | @@ -13,6 +13,11 @@ |
| 13 | 13 | #include <stdint.h> |
| 14 | 14 | #include <stddef.h> |
| 15 | 15 | |
| 16 | #if defined(_MSC_VER) | |
| 17 | // TODO support 128 bit floats with msvc | |
| 18 | typedef long double __float128; | |
| 19 | #endif | |
| 20 | ||
| 16 | 21 | struct BigFloat { |
| 17 | 22 | __float128 value; |
| 18 | 23 | }; |
src/bigint.cpp+35-8| ... | ... | @@ -141,7 +141,7 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) { |
| 141 | 141 | dest->is_negative = false; |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | void bigint_init_u128(BigInt *dest, unsigned __int128 x) { | |
| 144 | void bigint_init_u128(BigInt *dest, uint128_t x) { | |
| 145 | 145 | uint64_t low = (uint64_t)(x & UINT64_MAX); |
| 146 | 146 | uint64_t high = (uint64_t)(x >> 64); |
| 147 | 147 | |
| ... | ... | @@ -201,9 +201,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) { |
| 201 | 201 | |
| 202 | 202 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) { |
| 203 | 203 | if (op->value >= 0) { |
| 204 | bigint_init_u128(dest, (unsigned __int128)(op->value)); | |
| 204 | bigint_init_u128(dest, (uint128_t)(op->value)); | |
| 205 | 205 | } else { |
| 206 | bigint_init_u128(dest, (unsigned __int128)(-op->value)); | |
| 206 | bigint_init_u128(dest, (uint128_t)(-op->value)); | |
| 207 | 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 | 377 | } |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | #if defined(_MSC_VER) | |
| 381 | static 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 | ||
| 386 | static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 387 | *result = op1 - op2; | |
| 388 | return *result > op1; | |
| 389 | } | |
| 390 | ||
| 391 | bool 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 | |
| 380 | 406 | static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { |
| 381 | 407 | return __builtin_uaddll_overflow((unsigned long long)op1, (unsigned long long)op2, |
| 382 | 408 | (unsigned long long *)result); |
| ... | ... | @@ -387,10 +413,11 @@ static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { |
| 387 | 413 | (unsigned long long *)result); |
| 388 | 414 | } |
| 389 | 415 | |
| 390 | static bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 416 | bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 391 | 417 | return __builtin_umulll_overflow((unsigned long long)op1, (unsigned long long)op2, |
| 392 | 418 | (unsigned long long *)result); |
| 393 | 419 | } |
| 420 | #endif | |
| 394 | 421 | |
| 395 | 422 | void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 396 | 423 | if (op1->digit_count == 0) { |
| ... | ... | @@ -404,7 +431,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 404 | 431 | |
| 405 | 432 | const uint64_t *op1_digits = bigint_ptr(op1); |
| 406 | 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 | 435 | if (overflow == 0 && op1->digit_count == 1 && op2->digit_count == 1) { |
| 409 | 436 | dest->digit_count = 1; |
| 410 | 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 | 561 | return; |
| 535 | 562 | } |
| 536 | 563 | |
| 537 | unsigned __int128 big_x = x; | |
| 538 | unsigned __int128 big_y = y; | |
| 539 | unsigned __int128 big_result = big_x * big_y; | |
| 564 | uint128_t big_x = x; | |
| 565 | uint128_t big_y = y; | |
| 566 | uint128_t big_result = big_x * big_y; | |
| 540 | 567 | *carry = big_result >> 64; |
| 541 | 568 | } |
| 542 | 569 |
src/bigint.hpp+12-1| ... | ... | @@ -11,6 +11,15 @@ |
| 11 | 11 | #include <stdint.h> |
| 12 | 12 | #include <stddef.h> |
| 13 | 13 | |
| 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 | ||
| 14 | 23 | struct BigInt { |
| 15 | 24 | size_t digit_count; |
| 16 | 25 | union { |
| ... | ... | @@ -30,7 +39,7 @@ enum Cmp { |
| 30 | 39 | }; |
| 31 | 40 | |
| 32 | 41 | void bigint_init_unsigned(BigInt *dest, uint64_t x); |
| 33 | void bigint_init_u128(BigInt *dest, unsigned __int128 x); | |
| 42 | void bigint_init_u128(BigInt *dest, uint128_t x); | |
| 34 | 43 | void bigint_init_signed(BigInt *dest, int64_t x); |
| 35 | 44 | void bigint_init_bigint(BigInt *dest, const BigInt *src); |
| 36 | 45 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op); |
| ... | ... | @@ -89,4 +98,6 @@ size_t bigint_bits_needed(const BigInt *op); |
| 89 | 98 | // convenience functions |
| 90 | 99 | Cmp bigint_cmp_zero(const BigInt *op); |
| 91 | 100 | |
| 101 | bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result); | |
| 102 | ||
| 92 | 103 | #endif |
src/buffer.hpp+2-2| ... | ... | @@ -24,7 +24,7 @@ struct Buf { |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | Buf *buf_sprintf(const char *format, ...) |
| 27 | __attribute__ ((format (printf, 1, 2))); | |
| 27 | ATTRIBUTE_PRINTF(1, 2); | |
| 28 | 28 | Buf *buf_vprintf(const char *format, va_list ap); |
| 29 | 29 | |
| 30 | 30 | static inline size_t buf_len(Buf *buf) { |
| ... | ... | @@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) { |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | void buf_appendf(Buf *buf, const char *format, ...) |
| 127 | __attribute__ ((format (printf, 2, 3))); | |
| 127 | ATTRIBUTE_PRINTF(2, 3); | |
| 128 | 128 | |
| 129 | 129 | static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) { |
| 130 | 130 | assert(buf->list.length); |
src/codegen.cpp+9-9| ... | ... | @@ -5194,16 +5194,16 @@ void codegen_add_object(CodeGen *g, Buf *object_path) { |
| 5194 | 5194 | g->link_objects.append(object_path); |
| 5195 | 5195 | } |
| 5196 | 5196 | |
| 5197 | ||
| 5197 | // Must be coordinated with with CIntType enum | |
| 5198 | 5198 | static const char *c_int_type_names[] = { |
| 5199 | [CIntTypeShort] = "short", | |
| 5200 | [CIntTypeUShort] = "unsigned short", | |
| 5201 | [CIntTypeInt] = "int", | |
| 5202 | [CIntTypeUInt] = "unsigned int", | |
| 5203 | [CIntTypeLong] = "long", | |
| 5204 | [CIntTypeULong] = "unsigned long", | |
| 5205 | [CIntTypeLongLong] = "long long", | |
| 5206 | [CIntTypeULongLong] = "unsigned long long", | |
| 5199 | "short", | |
| 5200 | "unsigned short", | |
| 5201 | "int", | |
| 5202 | "unsigned int", | |
| 5203 | "long", | |
| 5204 | "unsigned long", | |
| 5205 | "long long", | |
| 5206 | "unsigned long long", | |
| 5207 | 5207 | }; |
| 5208 | 5208 | |
| 5209 | 5209 | static 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 | 6500 | break; |
| 6501 | 6501 | case 128: |
| 6502 | 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 | 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 | 6506 | bigint->is_negative = true; |
| 6507 | 6507 | } |
| 6508 | 6508 | break; |
| ... | ... | @@ -9731,8 +9731,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp |
| 9731 | 9731 | uint64_t old_array_len = array_type->data.array.len; |
| 9732 | 9732 | uint64_t new_array_len; |
| 9733 | 9733 | |
| 9734 | if (__builtin_umulll_overflow((unsigned long long)old_array_len, (unsigned long long)mult_amt, | |
| 9735 | (unsigned long long*)&new_array_len)) | |
| 9734 | if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) | |
| 9736 | 9735 | { |
| 9737 | 9736 | ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); |
| 9738 | 9737 | return ira->codegen->builtin_types.entry_invalid; |
src/os.cpp+7-5| ... | ... | @@ -25,6 +25,8 @@ |
| 25 | 25 | |
| 26 | 26 | #include <windows.h> |
| 27 | 27 | #include <io.h> |
| 28 | ||
| 29 | typedef SSIZE_T ssize_t; | |
| 28 | 30 | #else |
| 29 | 31 | #define ZIG_OS_POSIX |
| 30 | 32 | |
| ... | ... | @@ -620,7 +622,7 @@ int os_get_cwd(Buf *out_cwd) { |
| 620 | 622 | |
| 621 | 623 | bool os_stderr_tty(void) { |
| 622 | 624 | #if defined(ZIG_OS_WINDOWS) |
| 623 | return _isatty(STDERR_FILENO) != 0; | |
| 625 | return _isatty(_fileno(stderr)) != 0; | |
| 624 | 626 | #elif defined(ZIG_OS_POSIX) |
| 625 | 627 | return isatty(STDERR_FILENO) != 0; |
| 626 | 628 | #else |
| ... | ... | @@ -777,12 +779,12 @@ int os_make_path(Buf *path) { |
| 777 | 779 | |
| 778 | 780 | int os_make_dir(Buf *path) { |
| 779 | 781 | #if defined(ZIG_OS_WINDOWS) |
| 780 | if (mkdir(buf_ptr(path)) == -1) { | |
| 781 | if (errno == EEXIST) | |
| 782 | if (!CreateDirectory(buf_ptr(path), NULL)) { | |
| 783 | if (GetLastError() == ERROR_ALREADY_EXISTS) | |
| 782 | 784 | return ErrorPathAlreadyExists; |
| 783 | if (errno == ENOENT) | |
| 785 | if (GetLastError() == ERROR_PATH_NOT_FOUND) | |
| 784 | 786 | return ErrorFileNotFound; |
| 785 | if (errno == EACCES) | |
| 787 | if (GetLastError() == ERROR_ACCESS_DENIED) | |
| 786 | 788 | return ErrorAccess; |
| 787 | 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 | 56 | static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); |
| 57 | 57 | |
| 58 | 58 | |
| 59 | __attribute__ ((format (printf, 3, 4))) | |
| 59 | ATTRIBUTE_PRINTF(3, 4) | |
| 60 | 60 | static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { |
| 61 | 61 | if (!c->warnings_on) { |
| 62 | 62 | return; |
src/parser.cpp+5-5| ... | ... | @@ -24,8 +24,8 @@ struct ParseContext { |
| 24 | 24 | Buf *void_buf; |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | __attribute__ ((format (printf, 4, 5))) | |
| 28 | __attribute__ ((noreturn)) | |
| 27 | ATTRIBUTE_PRINTF(4, 5) | |
| 28 | ATTRIBUTE_NORETURN | |
| 29 | 29 | static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) { |
| 30 | 30 | assert(node->type == NodeTypeAsmExpr); |
| 31 | 31 | |
| ... | ... | @@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const |
| 46 | 46 | exit(EXIT_FAILURE); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | __attribute__ ((format (printf, 3, 4))) | |
| 50 | __attribute__ ((noreturn)) | |
| 49 | ATTRIBUTE_PRINTF(3, 4) | |
| 50 | ATTRIBUTE_NORETURN | |
| 51 | 51 | static void ast_error(ParseContext *pc, Token *token, const char *format, ...) { |
| 52 | 52 | va_list ap; |
| 53 | 53 | va_start(ap, format); |
| ... | ... | @@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) { |
| 205 | 205 | } |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | __attribute__ ((noreturn)) | |
| 208 | ATTRIBUTE_NORETURN | |
| 209 | 209 | static void ast_invalid_token_error(ParseContext *pc, Token *token) { |
| 210 | 210 | Buf token_value = BUF_INIT; |
| 211 | 211 | ast_buf_from_token(pc, token, &token_value); |
src/parser.hpp+1-1| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | #include "tokenizer.hpp" |
| 13 | 13 | #include "errmsg.hpp" |
| 14 | 14 | |
| 15 | __attribute__ ((format (printf, 2, 3))) | |
| 15 | ATTRIBUTE_PRINTF(2, 3) | |
| 16 | 16 | void ast_token_error(Token *token, const char *format, ...); |
| 17 | 17 | |
| 18 | 18 |
src/quadmath.hpp+32| ... | ... | @@ -8,6 +8,37 @@ |
| 8 | 8 | #ifndef ZIG_QUADMATH_HPP |
| 9 | 9 | #define ZIG_QUADMATH_HPP |
| 10 | 10 | |
| 11 | #if defined(_MSC_VER) | |
| 12 | #include <stdlib.h> | |
| 13 | #include <stdio.h> | |
| 14 | #include <stdarg.h> | |
| 15 | #include <cmath> | |
| 16 | ||
| 17 | static inline __float128 fmodq(__float128 a, __float128 b) { | |
| 18 | return fmodl(a, b); | |
| 19 | } | |
| 20 | ||
| 21 | static inline __float128 ceilq(__float128 a) { | |
| 22 | return ceill(a); | |
| 23 | } | |
| 24 | ||
| 25 | static inline __float128 floorq(__float128 a) { | |
| 26 | return floorl(a); | |
| 27 | } | |
| 28 | ||
| 29 | static inline __float128 strtoflt128(const char *s, char **sp) { | |
| 30 | return strtold(s, sp); | |
| 31 | } | |
| 32 | ||
| 33 | static 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 | |
| 11 | 42 | extern "C" { |
| 12 | 43 | __float128 fmodq(__float128 a, __float128 b); |
| 13 | 44 | __float128 ceilq(__float128 a); |
| ... | ... | @@ -15,5 +46,6 @@ extern "C" { |
| 15 | 46 | __float128 strtoflt128 (const char *s, char **sp); |
| 16 | 47 | int quadmath_snprintf (char *s, size_t size, const char *format, ...); |
| 17 | 48 | } |
| 49 | #endif | |
| 18 | 50 | |
| 19 | 51 | #endif |
src/tokenizer.cpp+2-2| ... | ... | @@ -234,7 +234,7 @@ struct Tokenize { |
| 234 | 234 | BigInt significand; |
| 235 | 235 | }; |
| 236 | 236 | |
| 237 | __attribute__ ((format (printf, 2, 3))) | |
| 237 | ATTRIBUTE_PRINTF(2, 3) | |
| 238 | 238 | static void tokenize_error(Tokenize *t, const char *format, ...) { |
| 239 | 239 | t->state = TokenizeStateError; |
| 240 | 240 | |
| ... | ... | @@ -331,7 +331,7 @@ static void end_float_token(Tokenize *t) { |
| 331 | 331 | if (t->radix == 10) { |
| 332 | 332 | zig_panic("TODO: decimal floats"); |
| 333 | 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 | 335 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; |
| 336 | 336 | if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) { |
| 337 | 337 | t->cur_tok->data.float_lit.overflow = true; |
src/util.hpp+41-8| ... | ... | @@ -15,21 +15,54 @@ |
| 15 | 15 | |
| 16 | 16 | #include <new> |
| 17 | 17 | |
| 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 | ||
| 27 | static 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 | 51 | #define BREAKPOINT __asm("int $0x03") |
| 19 | 52 | |
| 20 | void zig_panic(const char *format, ...) | |
| 21 | __attribute__((cold)) | |
| 22 | __attribute__ ((noreturn)) | |
| 23 | __attribute__ ((format (printf, 1, 2))); | |
| 53 | ATTRIBUTE_COLD | |
| 54 | ATTRIBUTE_NORETURN | |
| 55 | ATTRIBUTE_PRINTF(1, 2) | |
| 56 | void zig_panic(const char *format, ...); | |
| 24 | 57 | |
| 25 | __attribute__((cold)) | |
| 26 | __attribute__ ((noreturn)) | |
| 58 | ATTRIBUTE_COLD | |
| 59 | ATTRIBUTE_NORETURN | |
| 27 | 60 | static inline void zig_unreachable(void) { |
| 28 | 61 | zig_panic("unreachable"); |
| 29 | 62 | } |
| 30 | 63 | |
| 31 | 64 | template<typename T> |
| 32 | __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { | |
| 65 | ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { | |
| 33 | 66 | T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T))); |
| 34 | 67 | if (!ptr) |
| 35 | 68 | zig_panic("allocation failed"); |
| ... | ... | @@ -37,7 +70,7 @@ __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { |
| 37 | 70 | } |
| 38 | 71 | |
| 39 | 72 | template<typename T> |
| 40 | __attribute__((malloc)) static inline T *allocate(size_t count) { | |
| 73 | ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { | |
| 41 | 74 | T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T))); |
| 42 | 75 | if (!ptr) |
| 43 | 76 | zig_panic("allocation failed"); |