Skip to content

Commit

Permalink
0.5.4: Hash variables accept designated initializers. @safemacro over…
Browse files Browse the repository at this point in the history
…rides the need for `@` in macro names. Fixes to macro context evaluation. Updated allocator api. Removed install_win_reqs.bat. Deterministic @init for MacOS. Fixed temp memory issue with formatter. Support LLVM 19. Add support to compare bitstructs using == and !=. Support Windows `.def` files. Removed invalid grammar from grammar.y. Support compile time folding of &|^~ for bitstructs.
  • Loading branch information
lerno committed Feb 4, 2024
1 parent 86ed720 commit ec5824d
Show file tree
Hide file tree
Showing 19 changed files with 247 additions and 46 deletions.
26 changes: 23 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ jobs:
cd test
..\build\${{ matrix.build_type }}\c3c.exe compile-test unit -O1
- name: Test python script
run: |
py msvc_build_libraries.py --accept-license
dir msvc_sdk
- name: upload artifacts
uses: actions/upload-artifact@v3
with:
Expand Down Expand Up @@ -193,7 +198,7 @@ jobs:
fail-fast: false
matrix:
build_type: [Release, Debug]
llvm_version: [15, 16, 17, 18]
llvm_version: [15, 16, 17, 18, 19]

steps:
- uses: actions/checkout@v4
Expand All @@ -207,7 +212,7 @@ jobs:
if [[ "${{matrix.llvm_version}}" < 16 ]]; then
sudo apt remove libllvm15
fi
if [[ "${{matrix.llvm_version}}" < 18 ]]; then
if [[ "${{matrix.llvm_version}}" < 19 ]]; then
sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{matrix.llvm_version}} main"
sudo apt-get update
sudo apt-get install -y -t llvm-toolchain-focal-${{matrix.llvm_version}} libpolly-${{matrix.llvm_version}}-dev \
Expand All @@ -222,6 +227,7 @@ jobs:
libmlir-${{matrix.llvm_version}}-dev mlir-${{matrix.llvm_version}}-tools
fi
- name: CMake
if: matrix.llvm_version != 18
run: |
cmake -B build \
-G Ninja \
Expand All @@ -234,6 +240,20 @@ jobs:
-DCMAKE_DLLTOOL=llvm-dlltool-${{matrix.llvm_version}} \
-DC3_LLVM_VERSION=${{matrix.llvm_version}}
cmake --build build
- name: CMake18
if: matrix.llvm_version == 18
run: |
cmake -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DCMAKE_C_COMPILER=clang-${{matrix.llvm_version}} \
-DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm_version}} \
-DCMAKE_LINKER=lld-link-${{matrix.llvm_version}} \
-DCMAKE_OBJCOPY=llvm-objcopy-${{matrix.llvm_version}} \
-DCMAKE_STRIP=llvm-strip-${{matrix.llvm_version}} \
-DCMAKE_DLLTOOL=llvm-dlltool-${{matrix.llvm_version}} \
-DC3_LLVM_VERSION=18.1
cmake --build build
- name: Compile and run some examples
run: |
Expand Down Expand Up @@ -418,7 +438,7 @@ jobs:
fail-fast: false
matrix:
build_type: [Release, Debug]
llvm_version: [15, 16]
llvm_version: [15, 16, 17]
steps:
- uses: actions/checkout@v4
- name: Download LLVM
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ if (NOT WIN32)
find_package(CURL)
endif()
if (NOT C3_LLVM_VERSION STREQUAL "auto")
if (${C3_LLVM_VERSION} VERSION_LESS 15 OR ${C3_LLVM_VERSION} VERSION_GREATER 18)
if (${C3_LLVM_VERSION} VERSION_LESS 15 OR ${C3_LLVM_VERSION} VERSION_GREATER 19)
message(FATAL_ERROR "LLVM ${C3_LLVM_VERSION} is not supported!")
endif()
endif()
Expand Down
2 changes: 1 addition & 1 deletion lib/std/core/mem.c3
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ macro void @pool(TempAllocator* #other_temp = null; @body) @builtin
TempAllocator* original = current;
if (current == (void*)#other_temp) current = allocator::temp_allocator_next();
$endif
usz mark = current.mark();
usz mark = current.used;
defer
{
current.reset(mark);
Expand Down
4 changes: 4 additions & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
- Removed install_win_reqs.bat which didn't work well.
- Support `**` to mean `./**`
- MacOS init/finalizer now respects priority.
- Bitstructs supports `!=` and `==`.
- Support Windows `.def` files using `--windef`.
- Bitstructs now fold compile time constant bit ops.

### Fixes
- Fixes to macro context evaluation with macro varargs.
- Dynamic methods registered before init functions on MacOS.
- Fixed clobber on x86 `cpuid` instruction.
- Removed invalid syntax from grammar.y.

### Stdlib changes
- Deprecated `Allocator` helper functions.
Expand Down
31 changes: 0 additions & 31 deletions resources/grammar/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -1150,22 +1150,6 @@ global_declaration
| global_storage optional_type IDENT opt_attributes '=' expr ';'
;

opt_tl_stmts
: top_level_statements
| empty
;

tl_ct_case
: CT_CASE constant_expr ':' opt_tl_stmts
| CT_CASE type ':' opt_tl_stmts
| CT_DEFAULT ':' opt_tl_stmts
;

tl_ct_switch_body
: tl_ct_case
| tl_ct_switch_body tl_ct_case
;

define_attribute
: AT_TYPE_IDENT '(' parameters ')' opt_attributes '=' '{' opt_attributes '}'
| AT_TYPE_IDENT opt_attributes '=' '{' opt_attributes '}'
Expand Down Expand Up @@ -1206,19 +1190,6 @@ distinct_declaration
: DISTINCT TYPE_IDENT opt_interface_impl opt_attributes '=' opt_inline type ';'
;

tl_ct_if
: CT_IF constant_expr ':' opt_tl_stmts tl_ct_if_tail
;

tl_ct_if_tail
: CT_ENDIF
| CT_ELSE opt_tl_stmts CT_ENDIF
;

tl_ct_switch
: ct_switch tl_ct_switch_body CT_ENDSWITCH
;

module_param
: CONST_IDENT
| TYPE_IDENT
Expand Down Expand Up @@ -1267,8 +1238,6 @@ top_level
| ct_assert_stmt
| ct_echo_stmt
| ct_include_stmt
| tl_ct_if
| tl_ct_switch
| struct_declaration
| fault_declaration
| enum_declaration
Expand Down
3 changes: 3 additions & 0 deletions src/build/build.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ typedef struct BuildOptions_
const char* std_lib_dir;
struct {
const char *sdk;
const char *def;
WinCrtLinking crt_linking;
} win;
struct {
Expand Down Expand Up @@ -501,6 +502,7 @@ typedef struct
struct
{
const char *sdk;
const char *def;
WinCrtLinking crt_linking;
bool use_win_subsystem;
} win;
Expand Down Expand Up @@ -551,6 +553,7 @@ static BuildTarget default_build_target = {
.feature.x86_cpu_set = X86CPU_DEFAULT,
.feature.safe_mode = SAFETY_NOT_SET,
.win.crt_linking = WIN_CRT_DEFAULT,
.win.def = NULL,
.switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE,
};

Expand Down
7 changes: 7 additions & 0 deletions src/build/build_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ static void usage(void)
OUTPUT("");
OUTPUT(" --winsdk <dir> - Set the directory for Windows system library files for cross compilation.");
OUTPUT(" --wincrt=<option> - Windows CRT linking: none, static, dynamic (default).");
OUTPUT(" --windef <file> - Use Windows 'def' file for function exports instead of 'dllexport'.");
OUTPUT("");
OUTPUT(" --macossdk <dir> - Set the directory for the MacOS SDK for cross compilation.");
OUTPUT(" --macos-min-version <ver> - Set the minimum MacOS version to compile for.");
Expand Down Expand Up @@ -898,6 +899,12 @@ static void parse_option(BuildOptions *options)
options->trust_level = (TrustLevel) parse_multi_option(argopt, 3, trust_level);
return;
}
if (match_longopt("windef"))
{
if (at_end() || next_is_opt()) error_exit("error: --windef needs a file.");
options->win.def = next_arg();
return;
}
if ((argopt = match_argopt("wincrt")))
{
options->win.crt_linking = (WinCrtLinking)parse_multi_option(argopt, 3, wincrt_linking);
Expand Down
1 change: 1 addition & 0 deletions src/build/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
vec_add(target->linker_libs, options->linker_libs[i]);
}
target->trust_level = options->trust_level;
if (options->win.def) target->win.def = options->win.def;
if (options->use_stdlib != USE_STDLIB_NOT_SET) target->use_stdlib = options->use_stdlib;
if (options->link_libc != LINK_LIBC_NOT_SET) target->link_libc = options->link_libc;
if (options->system_linker != SYSTEM_LINKER_NOT_SET) target->system_linker = options->system_linker;
Expand Down
5 changes: 5 additions & 0 deletions src/build/project.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const char *project_default_keys[][2] = {
{"version", "Version using semantic versioning."},
{"warnings", "Warnings used for all targets."},
{"wincrt", "Windows CRT linking: none, static, dynamic (default)."},
{"windef", "Windows def file, used as an alternative to dllexport when exporting a DLL."},
{"winsdk", "Set the path to Windows system library files for cross compilation."},
{"x86cpu", "Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native."},
{"x86vec", "Set max type of vector use: none, mmx, sse, avx, avx512, native."},
Expand Down Expand Up @@ -108,6 +109,7 @@ const char* project_target_keys[][2] = {
{"version", "Version using semantic versioning."},
{"warnings", "Warnings used for all targets."},
{"wincrt", "Windows CRT linking: none, static, dynamic (default)."},
{"windef", "Windows def file, used as an alternative to dllexport when exporting a DLL."},
{"winsdk", "Set the path to Windows system library files for cross compilation."},
{"x86cpu", "Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native."},
{"x86vec", "Set max type of vector use: none, mmx, sse, avx, avx512, native."},
Expand Down Expand Up @@ -444,6 +446,9 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
// winsdk
target->win.sdk = get_valid_string(json, "winsdk", type, false);

// windef
target->win.def = get_valid_string(json, "windef", type, false);

// macossdk
target->macos.sysroot = get_valid_string(json, "macossdk", type, false);

Expand Down
1 change: 0 additions & 1 deletion src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2019,7 +2019,6 @@ int64_t int_to_i64(Int op);
bool int_is_zero(Int op);
unsigned int_bits_needed(Int op);
bool int_fits(Int op1, TypeKind kind);
Int int_rightmost_bits(Int op, unsigned to_bits, TypeKind result_type);
Int int_conv(Int op, TypeKind to_type);
Int int_div(Int op1, Int op2);
Int int_mul(Int op1, Int op2);
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/linker.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ static void linker_setup_windows(const char ***args_ref, LinkerType linker_type,
}
}
}
if (active_target.win.def)
{
add_arg(str_printf("/def:%s", active_target.win.def));
}
if (active_target.win.sdk)
{
add_arg(str_printf("/LIBPATH:%s", active_target.win.sdk));
Expand Down Expand Up @@ -875,6 +879,7 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi
arg_list = str_cat(arg_list, " ");
arg_list = str_cat(arg_list, args[i]);
}
if (active_target.print_linking) puts(arg_list);
DEBUG_LOG("INFO_LOG arguments: %s to %d", arg_list, platform_target.object_format);
switch (platform_target.object_format)
{
Expand All @@ -899,8 +904,6 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi
}
INFO_LOG("Linking complete.");
return true;

error_exit("Apologies, dynamic libs are still not supported.");
}

bool static_lib_linker(const char *output_file, const char **files, unsigned file_count)
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/llvm_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
}
assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
llvm_add_global_decl(c, decl);
if (decl->is_export && platform_target.os == OS_TYPE_WIN32)
if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && !active_target.win.def)
{
LLVMSetDLLStorageClass(decl->backend_ref, LLVMDLLExportStorageClass);
}
Expand All @@ -1148,7 +1148,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
}
backend_ref = decl->backend_ref = LLVMAddFunction(c->module, decl_get_extname(decl), llvm_get_type(c, decl->type));
llvm_append_function_attributes(c, decl);
if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && decl->name != kw_main && decl->name != kw_mainstub)
if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && !active_target.win.def && decl->name != kw_main && decl->name != kw_mainstub)
{
LLVMSetDLLStorageClass(backend_ref, LLVMDLLExportStorageClass);
}
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2170,8 +2170,10 @@ LLVMValueRef llvm_emit_const_bitstruct_array(GenContext *c, ConstInitializer *in
unsigned start_bit = member->var.start_bit;
unsigned end_bit = member->var.end_bit;
Type *member_type = type_flatten(member->type);
assert(initializer->init_struct[i]->kind == CONST_INIT_VALUE);
Expr *expr = initializer->init_struct[i]->init_value;
ConstInitializer *init = initializer->init_struct[i];
if (init->kind == CONST_INIT_ZERO) continue;
assert(init->kind == CONST_INIT_VALUE);
Expr *expr = init->init_value;

// Special case for bool
if (member_type == type_bool)
Expand Down
17 changes: 15 additions & 2 deletions src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -5578,7 +5578,7 @@ static bool sema_expr_analyse_bit(SemaContext *context, Expr *expr, Expr *left,
}

// 3. Do constant folding if both sides are constant.
if (expr_both_const(left, right) && sema_constant_fold_ops(left))
if (expr_both_const(left, right) && (sema_constant_fold_ops(left) || is_bitstruct))
{
BinaryOp op = expr->binary_expr.operator;
expr_replace(expr, left);
Expand All @@ -5599,6 +5599,12 @@ static bool sema_expr_analyse_bit(SemaContext *context, Expr *expr, Expr *left,
UNREACHABLE;
}
}
else if (is_bitstruct)
{
ConstInitializer *merged = sema_merge_bitstruct_const_initializers(left->const_expr.initializer,
right->const_expr.initializer, op);
expr->const_expr.initializer = merged;
}
else
{
switch (op)
Expand Down Expand Up @@ -6207,7 +6213,8 @@ static inline bool sema_expr_analyse_bit_not(SemaContext *context, Expr *expr)
// 2. Check that it's a vector, bool
Type *canonical = type_no_optional(inner->type)->canonical;
Type *flat = type_flatten(canonical);
if (!type_is_integer_or_bool_kind(flat) && flat->type_kind != TYPE_BITSTRUCT)
bool is_bitstruct = flat->type_kind == TYPE_BITSTRUCT;
if (!type_is_integer_or_bool_kind(flat) && !is_bitstruct)
{
Type *vector_type = type_vector_type(canonical);
if (vector_type && (type_is_integer(vector_type) || vector_type == type_bool)) goto VALID_VEC;
Expand All @@ -6216,6 +6223,12 @@ static inline bool sema_expr_analyse_bit_not(SemaContext *context, Expr *expr)
}

VALID_VEC:
if (is_bitstruct && expr_is_const(inner))
{
expr_replace(expr, inner);
sema_invert_bitstruct_const_initializer(expr->const_expr.initializer);
return true;
}
// 3. The simple case, non-const.
if (!sema_constant_fold_ops(inner))
{
Expand Down
Loading

0 comments on commit ec5824d

Please sign in to comment.