Link LLVM
This commit is contained in:
parent
0166e74e6a
commit
4b01d07117
@ -1,4 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.15)
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
include(CMakePrintHelpers)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
|
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
|
||||||
endif()
|
endif()
|
||||||
@ -7,11 +9,16 @@ set(CMAKE_CXX_STANDARD 23)
|
|||||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||||
project(bb)
|
project(bb)
|
||||||
|
|
||||||
|
find_package(LLVM REQUIRED CONFIG)
|
||||||
|
find_package(LLD REQUIRED CONFIG)
|
||||||
|
|
||||||
add_executable(bb
|
add_executable(bb
|
||||||
src/compiler.cpp
|
src/lib.cpp
|
||||||
src/entry_point.cpp
|
src/entry_point.cpp
|
||||||
|
src/compiler.cpp
|
||||||
src/parser.cpp
|
src/parser.cpp
|
||||||
src/emitter.cpp
|
src/emitter.cpp
|
||||||
|
src/llvm.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(bb PUBLIC src)
|
target_include_directories(bb PUBLIC src)
|
||||||
@ -19,5 +26,24 @@ target_compile_definitions(bb PUBLIC
|
|||||||
$<$<CONFIG:Debug>:BB_DEBUG=1>
|
$<$<CONFIG:Debug>:BB_DEBUG=1>
|
||||||
$<$<NOT:$<CONFIG:Debug>>:BB_DEBUG=0>
|
$<$<NOT:$<CONFIG:Debug>>:BB_DEBUG=0>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(bb PUBLIC ${LLVM_AVAILABLE_LIBS})
|
||||||
|
|
||||||
|
find_library(LLD_COMMON NAMES liblldCommon.dylib lldCommon.lib lldCommon.a liblldCommon.dll.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
find_library(LLD_ELF NAMES liblldELF.dylib lldELF.lib lldELF.a liblldELF.dll.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
# find_library(LLD_COFF NAMES liblldCOFF.dylib lldCOFF.lib lldCOFF.a liblldCOFF.dll.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
# find_library(LLD_MACHO NAMES liblldMachO.dylib lldMachO.lib lldMachO.a liblldMachO.dll.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
# find_library(LLD_MINGW NAMES liblldMinGW.dylib lldMinGW.lib lldMinGW.a liblldMinGW.dll.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
# find_library(LLD_WASM NAMES liblldWasm.dylib lldWasm.lib lldWasm.a liblldWasm.dll.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
|
||||||
|
|
||||||
|
target_link_libraries(bb PUBLIC
|
||||||
|
${LLD_COMMON}
|
||||||
|
# ${LLD_COFF}
|
||||||
|
${LLD_ELF}
|
||||||
|
# ${LLD_MACHO}
|
||||||
|
# ${LLD_MINGW}
|
||||||
|
# ${LLD_WASM}
|
||||||
|
)
|
||||||
|
|
||||||
#target_compile_options(bb PRIVATE -fsanitize=address)
|
#target_compile_options(bb PRIVATE -fsanitize=address)
|
||||||
#target_link_options(bb PRIVATE -fsanitize=address)
|
#target_link_options(bb PRIVATE -fsanitize=address)
|
||||||
|
@ -3,5 +3,5 @@ set -eu
|
|||||||
rm -rf build
|
rm -rf build
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_LINKER_TYPE=MOLD -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_LINKER_TYPE=MOLD -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_PREFIX_PATH=/home/david/dev/llvm/install/llvm_20.1.3_x86_64-linux-Release -DCMAKE_COLOR_DIAGNOSTICS=ON
|
||||||
cd ..
|
cd ..
|
||||||
|
264
src/compiler.cpp
264
src/compiler.cpp
@ -41,7 +41,7 @@ fn void compile(Arena* arena, Options options)
|
|||||||
|
|
||||||
for (bool sign: signs)
|
for (bool sign: signs)
|
||||||
{
|
{
|
||||||
auto name = sign ? str("s128") : str("u128");
|
auto name = sign ? string_literal("s128") : string_literal("u128");
|
||||||
*type_it = {
|
*type_it = {
|
||||||
.integer = {
|
.integer = {
|
||||||
.bit_count = 128,
|
.bit_count = 128,
|
||||||
@ -65,12 +65,12 @@ fn void compile(Arena* arena, Options options)
|
|||||||
previous->next = void_type;
|
previous->next = void_type;
|
||||||
*void_type = {
|
*void_type = {
|
||||||
.id = TypeId::void_type,
|
.id = TypeId::void_type,
|
||||||
.name = str("void"),
|
.name = string_literal("void"),
|
||||||
.next = noreturn_type,
|
.next = noreturn_type,
|
||||||
};
|
};
|
||||||
*noreturn_type = {
|
*noreturn_type = {
|
||||||
.id = TypeId::noreturn,
|
.id = TypeId::noreturn,
|
||||||
.name = str("noreturn"),
|
.name = string_literal("noreturn"),
|
||||||
};
|
};
|
||||||
|
|
||||||
auto module = Module{
|
auto module = Module{
|
||||||
@ -114,7 +114,7 @@ fn void compile_file(Arena* arena, Compile options)
|
|||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!relative_file_path(extension_start).equal(str(".bbb")))
|
if (!relative_file_path(extension_start).equal(string_literal(".bbb")))
|
||||||
{
|
{
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
@ -125,14 +125,14 @@ fn void compile_file(Arena* arena, Compile options)
|
|||||||
auto base_start = separator_index + (separator_index != 0 || relative_file_path[separator_index] == '/');
|
auto base_start = separator_index + (separator_index != 0 || relative_file_path[separator_index] == '/');
|
||||||
auto base_name = relative_file_path(base_start, extension_start);
|
auto base_name = relative_file_path(base_start, extension_start);
|
||||||
|
|
||||||
auto is_compiler = relative_file_path.equal(str("src/compiler.bbb"));
|
auto is_compiler = relative_file_path.equal(string_literal("src/compiler.bbb"));
|
||||||
|
|
||||||
String output_path_dir_parts[] = {
|
String output_path_dir_parts[] = {
|
||||||
str(base_cache_dir),
|
string_literal(base_cache_dir),
|
||||||
is_compiler ? str("/compiler") : str("/"),
|
is_compiler ? string_literal("/compiler") : string_literal("/"),
|
||||||
build_mode_to_string(options.build_mode),
|
build_mode_to_string(options.build_mode),
|
||||||
str("_"),
|
string_literal("_"),
|
||||||
options.has_debug_info ? str("di") : str("nodi"),
|
options.has_debug_info ? string_literal("di") : string_literal("nodi"),
|
||||||
};
|
};
|
||||||
auto output_path_dir = arena_join_string(arena, array_to_slice(output_path_dir_parts));
|
auto output_path_dir = arena_join_string(arena, array_to_slice(output_path_dir_parts));
|
||||||
|
|
||||||
@ -147,27 +147,27 @@ fn void compile_file(Arena* arena, Compile options)
|
|||||||
|
|
||||||
String output_path_base_parts[] = {
|
String output_path_base_parts[] = {
|
||||||
output_path_dir,
|
output_path_dir,
|
||||||
str("/"),
|
string_literal("/"),
|
||||||
base_name,
|
base_name,
|
||||||
};
|
};
|
||||||
auto output_path_base = arena_join_string(arena, array_to_slice(output_path_base_parts));
|
auto output_path_base = arena_join_string(arena, array_to_slice(output_path_base_parts));
|
||||||
String output_object_path_parts[] = {
|
String output_object_path_parts[] = {
|
||||||
output_path_base,
|
output_path_base,
|
||||||
str(".o"),
|
string_literal(".o"),
|
||||||
};
|
};
|
||||||
auto output_object_path = arena_join_string(arena, array_to_slice(output_object_path_parts));
|
auto output_object_path = arena_join_string(arena, array_to_slice(output_object_path_parts));
|
||||||
auto output_executable_path = output_path_base;
|
auto output_executable_path = output_path_base;
|
||||||
|
|
||||||
auto file_content = file_read(arena, relative_file_path);
|
auto file_content = file_read(arena, relative_file_path);
|
||||||
auto file_path = path_absolute(arena, relative_file_path);
|
auto file_path = path_absolute(arena, relative_file_path);
|
||||||
auto c_abi_object_path = str("build/c_abi.o");
|
auto c_abi_object_path = string_literal("build/c_abi.o");
|
||||||
|
|
||||||
String objects[] = {
|
String objects[] = {
|
||||||
c_abi_object_path,
|
c_abi_object_path,
|
||||||
output_object_path,
|
output_object_path,
|
||||||
};
|
};
|
||||||
Slice<String> object_slice = array_to_slice(objects);
|
Slice<String> object_slice = array_to_slice(objects);
|
||||||
object_slice = object_slice(!base_name.equal(str("c_abi")));
|
object_slice = object_slice(!base_name.equal(string_literal("c_abi")));
|
||||||
|
|
||||||
compile(arena, {
|
compile(arena, {
|
||||||
.content = file_content,
|
.content = file_content,
|
||||||
@ -186,107 +186,107 @@ fn void compile_file(Arena* arena, Compile options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
global_variable String names[] = {
|
global_variable String names[] = {
|
||||||
str("minimal"),
|
string_literal("minimal"),
|
||||||
str("comments"),
|
string_literal("comments"),
|
||||||
str("constant_add"),
|
string_literal("constant_add"),
|
||||||
str("constant_and"),
|
string_literal("constant_and"),
|
||||||
str("constant_div"),
|
string_literal("constant_div"),
|
||||||
str("constant_mul"),
|
string_literal("constant_mul"),
|
||||||
str("constant_rem"),
|
string_literal("constant_rem"),
|
||||||
str("constant_or"),
|
string_literal("constant_or"),
|
||||||
str("constant_sub"),
|
string_literal("constant_sub"),
|
||||||
str("constant_xor"),
|
string_literal("constant_xor"),
|
||||||
str("constant_shift_left"),
|
string_literal("constant_shift_left"),
|
||||||
str("constant_shift_right"),
|
string_literal("constant_shift_right"),
|
||||||
str("minimal_stack"),
|
string_literal("minimal_stack"),
|
||||||
str("minimal_stack_arithmetic"),
|
string_literal("minimal_stack_arithmetic"),
|
||||||
str("minimal_stack_arithmetic2"),
|
string_literal("minimal_stack_arithmetic2"),
|
||||||
str("minimal_stack_arithmetic3"),
|
string_literal("minimal_stack_arithmetic3"),
|
||||||
str("stack_negation"),
|
string_literal("stack_negation"),
|
||||||
str("stack_add"),
|
string_literal("stack_add"),
|
||||||
str("stack_sub"),
|
string_literal("stack_sub"),
|
||||||
str("extend"),
|
string_literal("extend"),
|
||||||
str("integer_max"),
|
string_literal("integer_max"),
|
||||||
str("integer_hex"),
|
string_literal("integer_hex"),
|
||||||
str("basic_pointer"),
|
string_literal("basic_pointer"),
|
||||||
str("basic_call"),
|
string_literal("basic_call"),
|
||||||
str("basic_branch"),
|
string_literal("basic_branch"),
|
||||||
str("basic_array"),
|
string_literal("basic_array"),
|
||||||
str("basic_enum"),
|
string_literal("basic_enum"),
|
||||||
str("basic_slice"),
|
string_literal("basic_slice"),
|
||||||
str("basic_string"),
|
string_literal("basic_string"),
|
||||||
str("basic_varargs"),
|
string_literal("basic_varargs"),
|
||||||
str("basic_while"),
|
string_literal("basic_while"),
|
||||||
str("pointer"),
|
string_literal("pointer"),
|
||||||
str("pointer_cast"),
|
string_literal("pointer_cast"),
|
||||||
str("u1_return"),
|
string_literal("u1_return"),
|
||||||
str("local_type_inference"),
|
string_literal("local_type_inference"),
|
||||||
str("global"),
|
string_literal("global"),
|
||||||
str("function_pointer"),
|
string_literal("function_pointer"),
|
||||||
str("extern"),
|
string_literal("extern"),
|
||||||
str("byte_size"),
|
string_literal("byte_size"),
|
||||||
str("argv"),
|
string_literal("argv"),
|
||||||
str("assignment_operators"),
|
string_literal("assignment_operators"),
|
||||||
str("not_pointer"),
|
string_literal("not_pointer"),
|
||||||
str("bits"),
|
string_literal("bits"),
|
||||||
str("bits_no_backing_type"),
|
string_literal("bits_no_backing_type"),
|
||||||
str("bits_return_u1"),
|
string_literal("bits_return_u1"),
|
||||||
str("bits_zero"),
|
string_literal("bits_zero"),
|
||||||
str("comparison"),
|
string_literal("comparison"),
|
||||||
str("global_struct"),
|
string_literal("global_struct"),
|
||||||
str("if_no_else"),
|
string_literal("if_no_else"),
|
||||||
str("if_no_else_void"),
|
string_literal("if_no_else_void"),
|
||||||
str("indirect"),
|
string_literal("indirect"),
|
||||||
str("indirect_struct"),
|
string_literal("indirect_struct"),
|
||||||
str("indirect_varargs"),
|
string_literal("indirect_varargs"),
|
||||||
str("ret_c_bool"),
|
string_literal("ret_c_bool"),
|
||||||
str("return_type_builtin"),
|
string_literal("return_type_builtin"),
|
||||||
str("return_u64_u64"),
|
string_literal("return_u64_u64"),
|
||||||
str("select"),
|
string_literal("select"),
|
||||||
str("slice"),
|
string_literal("slice"),
|
||||||
str("small_struct_ints"),
|
string_literal("small_struct_ints"),
|
||||||
str("struct_assignment"),
|
string_literal("struct_assignment"),
|
||||||
str("struct"),
|
string_literal("struct"),
|
||||||
str("struct_u64_u64"),
|
string_literal("struct_u64_u64"),
|
||||||
str("struct_varargs"),
|
string_literal("struct_varargs"),
|
||||||
str("struct_zero"),
|
string_literal("struct_zero"),
|
||||||
str("unreachable"),
|
string_literal("unreachable"),
|
||||||
str("varargs"),
|
string_literal("varargs"),
|
||||||
str("c_abi0"),
|
string_literal("c_abi0"),
|
||||||
str("c_abi1"),
|
string_literal("c_abi1"),
|
||||||
str("c_med_struct_ints"),
|
string_literal("c_med_struct_ints"),
|
||||||
str("c_ret_struct_array"),
|
string_literal("c_ret_struct_array"),
|
||||||
str("c_split_struct_ints"),
|
string_literal("c_split_struct_ints"),
|
||||||
str("c_string_to_slice"),
|
string_literal("c_string_to_slice"),
|
||||||
str("c_struct_with_array"),
|
string_literal("c_struct_with_array"),
|
||||||
str("c_function_pointer"),
|
string_literal("c_function_pointer"),
|
||||||
str("c_abi"),
|
string_literal("c_abi"),
|
||||||
str("string_to_enum"),
|
string_literal("string_to_enum"),
|
||||||
str("abi_enum_bool"),
|
string_literal("abi_enum_bool"),
|
||||||
str("empty_if"),
|
string_literal("empty_if"),
|
||||||
str("else_if"),
|
string_literal("else_if"),
|
||||||
str("else_if_complicated"),
|
string_literal("else_if_complicated"),
|
||||||
str("shortcircuiting_if"),
|
string_literal("shortcircuiting_if"),
|
||||||
str("field_access_left_assign"),
|
string_literal("field_access_left_assign"),
|
||||||
str("for_each"),
|
string_literal("for_each"),
|
||||||
str("pointer_decay"),
|
string_literal("pointer_decay"),
|
||||||
str("enum_name"),
|
string_literal("enum_name"),
|
||||||
str("slice_of_slices"),
|
string_literal("slice_of_slices"),
|
||||||
str("type_alias"),
|
string_literal("type_alias"),
|
||||||
str("integer_formats"),
|
string_literal("integer_formats"),
|
||||||
str("return_small_struct"),
|
string_literal("return_small_struct"),
|
||||||
str("for_each_int"),
|
string_literal("for_each_int"),
|
||||||
str("bool_array"),
|
string_literal("bool_array"),
|
||||||
str("basic_union"),
|
string_literal("basic_union"),
|
||||||
str("break_continue"),
|
string_literal("break_continue"),
|
||||||
str("constant_global_reference"),
|
string_literal("constant_global_reference"),
|
||||||
str("self_referential_struct"),
|
string_literal("self_referential_struct"),
|
||||||
str("forward_declared_type"),
|
string_literal("forward_declared_type"),
|
||||||
str("basic_macro"),
|
string_literal("basic_macro"),
|
||||||
str("generic_macro"),
|
string_literal("generic_macro"),
|
||||||
str("generic_pointer_macro"),
|
string_literal("generic_pointer_macro"),
|
||||||
str("noreturn_macro"),
|
string_literal("noreturn_macro"),
|
||||||
str("generic_pointer_array"),
|
string_literal("generic_pointer_array"),
|
||||||
};
|
};
|
||||||
|
|
||||||
void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
||||||
@ -295,13 +295,13 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
|
|
||||||
if (arguments.length < 2)
|
if (arguments.length < 2)
|
||||||
{
|
{
|
||||||
fail_with_message(str("error: Not enough arguments\n"));
|
fail_with_message(string_literal("error: Not enough arguments\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
String command_string = c_string_to_slice(arguments[1]);
|
String command_string = c_string_to_slice(arguments[1]);
|
||||||
String command_strings[] = {
|
String command_strings[] = {
|
||||||
str("compile"),
|
string_literal("compile"),
|
||||||
str("test"),
|
string_literal("test"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(command_strings) == (u64)Command::count);
|
static_assert(array_length(command_strings) == (u64)Command::count);
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
{
|
{
|
||||||
if (arguments.length < 3)
|
if (arguments.length < 3)
|
||||||
{
|
{
|
||||||
fail_with_message(str("Not enough arguments for command 'compile'\n"));
|
fail_with_message(string_literal("Not enough arguments for command 'compile'\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto build_mode = BuildMode::debug_none;
|
auto build_mode = BuildMode::debug_none;
|
||||||
@ -333,13 +333,13 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
{
|
{
|
||||||
auto build_mode_string = c_string_to_slice(arguments[3]);
|
auto build_mode_string = c_string_to_slice(arguments[3]);
|
||||||
String build_mode_strings[] = {
|
String build_mode_strings[] = {
|
||||||
str("debug_none"),
|
string_literal("debug_none"),
|
||||||
str("debug"),
|
string_literal("debug"),
|
||||||
str("soft_optimize"),
|
string_literal("soft_optimize"),
|
||||||
str("optimize_for_speed"),
|
string_literal("optimize_for_speed"),
|
||||||
str("optimize_for_size"),
|
string_literal("optimize_for_size"),
|
||||||
str("aggressively_optimize_for_speed"),
|
string_literal("aggressively_optimize_for_speed"),
|
||||||
str("aggressively_optimize_for_size"),
|
string_literal("aggressively_optimize_for_size"),
|
||||||
};
|
};
|
||||||
|
|
||||||
backing_type(BuildMode) i;
|
backing_type(BuildMode) i;
|
||||||
@ -355,24 +355,24 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
build_mode = (BuildMode)i;
|
build_mode = (BuildMode)i;
|
||||||
if (build_mode == BuildMode::count)
|
if (build_mode == BuildMode::count)
|
||||||
{
|
{
|
||||||
fail_with_message(str("Invalid build mode\n"));
|
fail_with_message(string_literal("Invalid build mode\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments.length >= 5)
|
if (arguments.length >= 5)
|
||||||
{
|
{
|
||||||
auto has_debug_info_string = c_string_to_slice(arguments[3]);
|
auto has_debug_info_string = c_string_to_slice(arguments[3]);
|
||||||
if (has_debug_info_string.equal(str("true")))
|
if (has_debug_info_string.equal(string_literal("true")))
|
||||||
{
|
{
|
||||||
has_debug_info = true;
|
has_debug_info = true;
|
||||||
}
|
}
|
||||||
else if (has_debug_info_string.equal(str("false")))
|
else if (has_debug_info_string.equal(string_literal("false")))
|
||||||
{
|
{
|
||||||
has_debug_info = false;
|
has_debug_info = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fail_with_message(str("Wrong value for has_debug_info\n"));
|
fail_with_message(string_literal("Wrong value for has_debug_info\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
// TODO: provide more arguments
|
// TODO: provide more arguments
|
||||||
if (arguments.length != 2)
|
if (arguments.length != 2)
|
||||||
{
|
{
|
||||||
fail_with_message(str("error: 'test' command takes no arguments"));
|
fail_with_message(string_literal("error: 'test' command takes no arguments"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: introduce build mode, debug info switch, etc
|
// TODO: introduce build mode, debug info switch, etc
|
||||||
@ -399,7 +399,7 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
{
|
{
|
||||||
auto position = arena->position;
|
auto position = arena->position;
|
||||||
|
|
||||||
String relative_file_path_parts[] = { str("tests/"), name, str(".bbb") };
|
String relative_file_path_parts[] = { string_literal("tests/"), name, string_literal(".bbb") };
|
||||||
auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts));
|
auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts));
|
||||||
auto build_mode = BuildMode::debug_none;
|
auto build_mode = BuildMode::debug_none;
|
||||||
bool has_debug_info = true;
|
bool has_debug_info = true;
|
||||||
@ -417,7 +417,7 @@ void entry_point(Slice<const char*> arguments, Slice<const char*> environment)
|
|||||||
} break;
|
} break;
|
||||||
case Command::count:
|
case Command::count:
|
||||||
{
|
{
|
||||||
fail_with_message(str("error: Invalid command\n"));
|
fail_with_message(string_literal("error: Invalid command\n"));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,7 +896,7 @@ fn Type* get_pointer_type(Module* module, Type* element_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
String name_parts[] = {
|
String name_parts[] = {
|
||||||
str("&"),
|
string_literal("&"),
|
||||||
element_type->name,
|
element_type->name,
|
||||||
};
|
};
|
||||||
auto result = type_allocate_init(module, {
|
auto result = type_allocate_init(module, {
|
||||||
@ -952,19 +952,19 @@ fn Type* get_slice_type(Module* module, Type* element_type)
|
|||||||
Type* last_slice_type = slice_type;
|
Type* last_slice_type = slice_type;
|
||||||
auto fields = arena_allocate<Field>(module->arena, 2);
|
auto fields = arena_allocate<Field>(module->arena, 2);
|
||||||
fields[0] = {
|
fields[0] = {
|
||||||
.name = str("pointer"),
|
.name = string_literal("pointer"),
|
||||||
.type = get_pointer_type(module, element_type),
|
.type = get_pointer_type(module, element_type),
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.line = 0,
|
.line = 0,
|
||||||
};
|
};
|
||||||
fields[1] = {
|
fields[1] = {
|
||||||
.name = str("length"),
|
.name = string_literal("length"),
|
||||||
.type = integer_type(module, { .bit_count = 64, .is_signed = false }),
|
.type = integer_type(module, { .bit_count = 64, .is_signed = false }),
|
||||||
.offset = 8,
|
.offset = 8,
|
||||||
.line = 0,
|
.line = 0,
|
||||||
};
|
};
|
||||||
String name_parts[] = {
|
String name_parts[] = {
|
||||||
str("[]"),
|
string_literal("[]"),
|
||||||
element_type->name,
|
element_type->name,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
43
src/lib.cpp
Normal file
43
src/lib.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <lib.h>
|
||||||
|
using uid_t = u32;
|
||||||
|
using gid_t = u32;
|
||||||
|
using off_t = s64;
|
||||||
|
using ino_t = u64;
|
||||||
|
using dev_t = u64;
|
||||||
|
|
||||||
|
struct timespec
|
||||||
|
{
|
||||||
|
s64 seconds;
|
||||||
|
s64 nanoseconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Stat
|
||||||
|
{
|
||||||
|
dev_t dev;
|
||||||
|
ino_t ino;
|
||||||
|
u64 nlink;
|
||||||
|
|
||||||
|
u32 mode;
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
|
u32 _0;
|
||||||
|
dev_t rdev;
|
||||||
|
off_t size;
|
||||||
|
s64 blksize;
|
||||||
|
s64 blocks;
|
||||||
|
|
||||||
|
timespec atim;
|
||||||
|
timespec mtim;
|
||||||
|
timespec ctim;
|
||||||
|
s64 _1[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" s32 fstat(s32, Stat*);
|
||||||
|
|
||||||
|
u64 os_file_size(s32 fd)
|
||||||
|
{
|
||||||
|
Stat stat;
|
||||||
|
auto result = fstat(fd, &stat);
|
||||||
|
assert(result == 0);
|
||||||
|
return (u64)stat.size;
|
||||||
|
}
|
60
src/lib.h
60
src/lib.h
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#define global_variable static
|
#define global_variable static
|
||||||
|
|
||||||
|
#define EXPORT extern "C"
|
||||||
#define fn static
|
#define fn static
|
||||||
#define unused(x) (void)(x)
|
#define unused(x) (void)(x)
|
||||||
#define breakpoint() __builtin_debugtrap()
|
#define breakpoint() __builtin_debugtrap()
|
||||||
#define string_literal_length(s) (sizeof(s) - 1)
|
#define string_literal_length(s) (sizeof(s) - 1)
|
||||||
#define string_literal(s) ((String){ .pointer = (u8*)(s), .length = string_literal_length(s), })
|
#define string_literal(s) ((String){ .pointer = (u8*)(s), .length = string_literal_length(s), })
|
||||||
#define str(x) string_literal(x)
|
|
||||||
#define offsetof(S, f) __builtin_offsetof(S, f)
|
#define offsetof(S, f) __builtin_offsetof(S, f)
|
||||||
|
|
||||||
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
|
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
|
||||||
@ -34,7 +34,7 @@
|
|||||||
#define clz(x) __builtin_clzg(x)
|
#define clz(x) __builtin_clzg(x)
|
||||||
#define ctz(x) __builtin_ctzg(x)
|
#define ctz(x) __builtin_ctzg(x)
|
||||||
|
|
||||||
#define case_to_name(E,n) case E::n: return str(#n)
|
#define case_to_name(E,n) case E::n: return string_literal(#n)
|
||||||
|
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
@ -61,10 +61,10 @@ constexpr u64 kb = 1024;
|
|||||||
constexpr u64 mb = 1024 * 1024;
|
constexpr u64 mb = 1024 * 1024;
|
||||||
constexpr u64 gb = 1024 * 1024 * 1024;
|
constexpr u64 gb = 1024 * 1024 * 1024;
|
||||||
|
|
||||||
extern "C" [[noreturn]] void exit(s32 status);
|
extern "C" [[noreturn]] void exit(s32 status) noexcept(true);
|
||||||
extern "C" void *memcpy (void* __restrict destination, const void *__restrict source, u64 byte_count);
|
extern "C" void *memcpy (void* __restrict destination, const void *__restrict source, u64 byte_count) noexcept(true);
|
||||||
extern "C" void *memcmp (const void* a, const void *b, u64 __n);
|
extern "C" s32 memcmp (const void* a, const void *b, u64 __n) noexcept(true);
|
||||||
extern "C" const char* realpath(const char* __restrict path, char* resolved_path);
|
extern "C" char* realpath(const char* __restrict path, char* resolved_path) noexcept(true);
|
||||||
|
|
||||||
struct RawSlice
|
struct RawSlice
|
||||||
{
|
{
|
||||||
@ -272,48 +272,14 @@ struct OPEN
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(OPEN) == sizeof(u32));
|
static_assert(sizeof(OPEN) == sizeof(u32));
|
||||||
|
|
||||||
using uid_t = u32;
|
extern "C" s32* __errno_location() noexcept(true);
|
||||||
using gid_t = u32;
|
|
||||||
using off_t = s64;
|
|
||||||
using ino_t = u64;
|
|
||||||
using dev_t = u64;
|
|
||||||
|
|
||||||
struct timespec
|
|
||||||
{
|
|
||||||
s64 seconds;
|
|
||||||
s64 nanoseconds;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Stat
|
|
||||||
{
|
|
||||||
dev_t dev;
|
|
||||||
ino_t ino;
|
|
||||||
u64 nlink;
|
|
||||||
|
|
||||||
u32 mode;
|
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
u32 _0;
|
|
||||||
dev_t rdev;
|
|
||||||
off_t size;
|
|
||||||
s64 blksize;
|
|
||||||
s64 blocks;
|
|
||||||
|
|
||||||
timespec atim;
|
|
||||||
timespec mtim;
|
|
||||||
timespec ctim;
|
|
||||||
s64 _1[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" s32* __errno_location();
|
|
||||||
extern "C" void* mmap(void*, u64, PROT, MAP, s32, s64);
|
extern "C" void* mmap(void*, u64, PROT, MAP, s32, s64);
|
||||||
extern "C" s32 mprotect(void*, u64, PROT);
|
extern "C" s32 mprotect(void*, u64, PROT);
|
||||||
extern "C" s64 ptrace(s32, s32, u64, u64);
|
extern "C" s64 ptrace(s32, s32, u64, u64);
|
||||||
extern "C" s32 open(const char*, OPEN, ...);
|
extern "C" s32 open(const char*, OPEN, ...);
|
||||||
extern "C" s32 close(s32);
|
extern "C" s32 close(s32);
|
||||||
extern "C" s32 fstat(s32, Stat*);
|
extern "C" s64 write(s32, const void*, u64);
|
||||||
extern "C" s64 write(s32, u8*, u64);
|
extern "C" s64 read(s32, void*, u64);
|
||||||
extern "C" s64 read(s32, u8*, u64);
|
|
||||||
extern "C" s32 mkdir(const char*, u64);
|
extern "C" s32 mkdir(const char*, u64);
|
||||||
|
|
||||||
enum class Error : u32
|
enum class Error : u32
|
||||||
@ -426,13 +392,7 @@ fn void os_close(s32 fd)
|
|||||||
assert(result == 0);
|
assert(result == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn u64 os_file_size(s32 fd)
|
u64 os_file_size(s32 fd);
|
||||||
{
|
|
||||||
Stat stat;
|
|
||||||
auto result = fstat(fd, &stat);
|
|
||||||
assert(result == 0);
|
|
||||||
return (u64)stat.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn u64 os_read_partially(s32 fd, u8* buffer, u64 byte_count)
|
fn u64 os_read_partially(s32 fd, u8* buffer, u64 byte_count)
|
||||||
{
|
{
|
||||||
|
31
src/llvm.cpp
31
src/llvm.cpp
@ -1,13 +1,4 @@
|
|||||||
#include <stdint.h>
|
#include <llvm.h>
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
|
|
||||||
#define EXPORT extern "C"
|
|
||||||
#define fn static
|
|
||||||
#define array_length(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
||||||
|
|
||||||
#include "llvm/Config/llvm-config.h"
|
#include "llvm/Config/llvm-config.h"
|
||||||
|
|
||||||
@ -62,18 +53,18 @@ EXPORT unsigned llvm_integer_type_get_bit_count(const IntegerType& integer_type)
|
|||||||
|
|
||||||
EXPORT GlobalVariable* llvm_module_create_global_variable(Module& module, Type* type, bool is_constant, GlobalValue::LinkageTypes linkage_type, Constant* initial_value, BBLLVMString name, GlobalVariable* before, GlobalValue::ThreadLocalMode thread_local_mode, unsigned address_space, bool externally_initialized)
|
EXPORT GlobalVariable* llvm_module_create_global_variable(Module& module, Type* type, bool is_constant, GlobalValue::LinkageTypes linkage_type, Constant* initial_value, BBLLVMString name, GlobalVariable* before, GlobalValue::ThreadLocalMode thread_local_mode, unsigned address_space, bool externally_initialized)
|
||||||
{
|
{
|
||||||
auto* global_variable = new GlobalVariable(module, type, is_constant, linkage_type, initial_value, name.string_ref(), before, thread_local_mode, address_space, externally_initialized);
|
auto* global = new GlobalVariable(module, type, is_constant, linkage_type, initial_value, name.string_ref(), before, thread_local_mode, address_space, externally_initialized);
|
||||||
return global_variable;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void llvm_global_variable_add_debug_info(GlobalVariable& global_variable, DIGlobalVariableExpression* debug_global_variable)
|
EXPORT void llvm_global_variable_add_debug_info(GlobalVariable& global, DIGlobalVariableExpression* debug_global_variable)
|
||||||
{
|
{
|
||||||
global_variable.addDebugInfo(debug_global_variable);
|
global.addDebugInfo(debug_global_variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void llvm_global_variable_delete(GlobalVariable* global_variable)
|
EXPORT void llvm_global_variable_delete(GlobalVariable* global)
|
||||||
{
|
{
|
||||||
delete global_variable;
|
delete global;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void llvm_subprogram_replace_type(DISubprogram& subprogram, DISubroutineType* subroutine_type)
|
EXPORT void llvm_subprogram_replace_type(DISubprogram& subprogram, DISubroutineType* subroutine_type)
|
||||||
@ -1856,8 +1847,8 @@ EXPORT lld_api_function_decl(link_name)\
|
|||||||
return lld_api_generic(argument_pointer, argument_count, exit_early, disable_output, lld::link_name::link);\
|
return lld_api_generic(argument_pointer, argument_count, exit_early, disable_output, lld::link_name::link);\
|
||||||
}
|
}
|
||||||
|
|
||||||
lld_api_function_impl(coff)
|
// lld_api_function_impl(coff)
|
||||||
lld_api_function_impl(elf)
|
lld_api_function_impl(elf)
|
||||||
lld_api_function_impl(mingw)
|
// lld_api_function_impl(mingw)
|
||||||
lld_api_function_impl(macho)
|
// lld_api_function_impl(macho)
|
||||||
lld_api_function_impl(wasm)
|
// lld_api_function_impl(wasm)
|
||||||
|
1
src/llvm.h
Normal file
1
src/llvm.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include <lib.h>
|
102
src/parser.cpp
102
src/parser.cpp
@ -594,11 +594,11 @@ fn Type* parse_type(Module* module, Scope* scope)
|
|||||||
if (is_identifier_start(start_character))
|
if (is_identifier_start(start_character))
|
||||||
{
|
{
|
||||||
auto identifier = parse_identifier(module);
|
auto identifier = parse_identifier(module);
|
||||||
if (identifier.equal(str("void")))
|
if (identifier.equal(string_literal("void")))
|
||||||
{
|
{
|
||||||
return void_type(module);
|
return void_type(module);
|
||||||
}
|
}
|
||||||
else if (identifier.equal(str("noreturn")))
|
else if (identifier.equal(string_literal("noreturn")))
|
||||||
{
|
{
|
||||||
return noreturn_type(module);
|
return noreturn_type(module);
|
||||||
}
|
}
|
||||||
@ -733,7 +733,7 @@ fn Type* parse_type(Module* module, Scope* scope)
|
|||||||
.element_type = element_type,
|
.element_type = element_type,
|
||||||
},
|
},
|
||||||
.id = TypeId::array,
|
.id = TypeId::array,
|
||||||
.name = str(""),
|
.name = string_literal(""),
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -770,7 +770,7 @@ fn Type* parse_type(Module* module, Scope* scope)
|
|||||||
};
|
};
|
||||||
|
|
||||||
String type_intrinsics[] = {
|
String type_intrinsics[] = {
|
||||||
str("ReturnType"),
|
string_literal("ReturnType"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(array_length(type_intrinsics) == (u64)TypeIntrinsic::count);
|
static_assert(array_length(type_intrinsics) == (u64)TypeIntrinsic::count);
|
||||||
@ -943,22 +943,22 @@ fn Token tokenize(Module* module)
|
|||||||
auto identifier = parse_identifier(module);
|
auto identifier = parse_identifier(module);
|
||||||
|
|
||||||
String value_intrinsics[] = {
|
String value_intrinsics[] = {
|
||||||
str("align_of"),
|
string_literal("align_of"),
|
||||||
str("byte_size"),
|
string_literal("byte_size"),
|
||||||
str("enum_name"),
|
string_literal("enum_name"),
|
||||||
str("extend"),
|
string_literal("extend"),
|
||||||
str("integer_max"),
|
string_literal("integer_max"),
|
||||||
str("int_from_enum"),
|
string_literal("int_from_enum"),
|
||||||
str("int_from_pointer"),
|
string_literal("int_from_pointer"),
|
||||||
str("pointer_cast"),
|
string_literal("pointer_cast"),
|
||||||
str("select"),
|
string_literal("select"),
|
||||||
str("string_to_enum"),
|
string_literal("string_to_enum"),
|
||||||
str("trap"),
|
string_literal("trap"),
|
||||||
str("truncate"),
|
string_literal("truncate"),
|
||||||
str("va_start"),
|
string_literal("va_start"),
|
||||||
str("va_end"),
|
string_literal("va_end"),
|
||||||
str("va_arg"),
|
string_literal("va_arg"),
|
||||||
str("va_copy"),
|
string_literal("va_copy"),
|
||||||
};
|
};
|
||||||
|
|
||||||
backing_type(ValueIntrinsic) i;
|
backing_type(ValueIntrinsic) i;
|
||||||
@ -1251,9 +1251,9 @@ fn Token tokenize(Module* module)
|
|||||||
auto identifier = parse_identifier(module);
|
auto identifier = parse_identifier(module);
|
||||||
|
|
||||||
String value_keywords[] = {
|
String value_keywords[] = {
|
||||||
str("undefined"),
|
string_literal("undefined"),
|
||||||
str("unreachable"),
|
string_literal("unreachable"),
|
||||||
str("zero"),
|
string_literal("zero"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(value_keywords) == (u64)ValueKeyword::count);
|
static_assert(array_length(value_keywords) == (u64)ValueKeyword::count);
|
||||||
|
|
||||||
@ -1276,10 +1276,10 @@ fn Token tokenize(Module* module)
|
|||||||
module->offset += advance;
|
module->offset += advance;
|
||||||
|
|
||||||
String operators[] = {
|
String operators[] = {
|
||||||
str("and"),
|
string_literal("and"),
|
||||||
str("or"),
|
string_literal("or"),
|
||||||
str("and?"),
|
string_literal("and?"),
|
||||||
str("or?"),
|
string_literal("or?"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(operators) == (u64)OperatorKeyword::count);
|
static_assert(array_length(operators) == (u64)OperatorKeyword::count);
|
||||||
|
|
||||||
@ -1330,8 +1330,8 @@ fn Token tokenize(Module* module)
|
|||||||
|
|
||||||
fn Value* reference_identifier(Module* module, Scope* current_scope, String identifier, ValueKind kind)
|
fn Value* reference_identifier(Module* module, Scope* current_scope, String identifier, ValueKind kind)
|
||||||
{
|
{
|
||||||
assert(!identifier.equal(str("")));
|
assert(!identifier.equal(string_literal("")));
|
||||||
assert(!identifier.equal(str("_")));
|
assert(!identifier.equal(string_literal("_")));
|
||||||
|
|
||||||
Variable* variable = 0;
|
Variable* variable = 0;
|
||||||
|
|
||||||
@ -2367,14 +2367,14 @@ fn Statement* parse_statement(Module* module, Scope* scope)
|
|||||||
};
|
};
|
||||||
|
|
||||||
String statement_start_keywords[] = {
|
String statement_start_keywords[] = {
|
||||||
str("_"),
|
string_literal("_"),
|
||||||
str("return"),
|
string_literal("return"),
|
||||||
str("if"),
|
string_literal("if"),
|
||||||
str("for"),
|
string_literal("for"),
|
||||||
str("while"),
|
string_literal("while"),
|
||||||
str("switch"),
|
string_literal("switch"),
|
||||||
str("break"),
|
string_literal("break"),
|
||||||
str("continue"),
|
string_literal("continue"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(array_length(statement_start_keywords) == (u64)StatementStartKeyword::count);
|
static_assert(array_length(statement_start_keywords) == (u64)StatementStartKeyword::count);
|
||||||
@ -2424,7 +2424,7 @@ fn Statement* parse_statement(Module* module, Scope* scope)
|
|||||||
{
|
{
|
||||||
auto checkpoint = get_checkpoint(module);
|
auto checkpoint = get_checkpoint(module);
|
||||||
auto identifier = parse_identifier(module);
|
auto identifier = parse_identifier(module);
|
||||||
is_else = identifier.equal(str("else"));
|
is_else = identifier.equal(string_literal("else"));
|
||||||
|
|
||||||
if (is_else)
|
if (is_else)
|
||||||
{
|
{
|
||||||
@ -2628,7 +2628,7 @@ fn Statement* parse_statement(Module* module, Scope* scope)
|
|||||||
{
|
{
|
||||||
auto else_checkpoint = get_checkpoint(module);
|
auto else_checkpoint = get_checkpoint(module);
|
||||||
auto i = parse_identifier(module);
|
auto i = parse_identifier(module);
|
||||||
is_else = i.equal(str("else"));
|
is_else = i.equal(string_literal("else"));
|
||||||
if (!is_else)
|
if (!is_else)
|
||||||
{
|
{
|
||||||
set_checkpoint(module, else_checkpoint);
|
set_checkpoint(module, else_checkpoint);
|
||||||
@ -2846,8 +2846,8 @@ void parse(Module* module)
|
|||||||
count,
|
count,
|
||||||
};
|
};
|
||||||
String global_keyword_strings[] = {
|
String global_keyword_strings[] = {
|
||||||
str("export"),
|
string_literal("export"),
|
||||||
str("extern"),
|
string_literal("extern"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(global_keyword_strings) == (u64)GlobalKeyword::count);
|
static_assert(array_length(global_keyword_strings) == (u64)GlobalKeyword::count);
|
||||||
|
|
||||||
@ -2974,13 +2974,13 @@ void parse(Module* module)
|
|||||||
skip_space(module);
|
skip_space(module);
|
||||||
|
|
||||||
String global_keywords[] = {
|
String global_keywords[] = {
|
||||||
str("bits"),
|
string_literal("bits"),
|
||||||
str("enum"),
|
string_literal("enum"),
|
||||||
str("fn"),
|
string_literal("fn"),
|
||||||
str("macro"),
|
string_literal("macro"),
|
||||||
str("struct"),
|
string_literal("struct"),
|
||||||
str("typealias"),
|
string_literal("typealias"),
|
||||||
str("union"),
|
string_literal("union"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(global_keywords) == (u64)GlobalKeyword::count);
|
static_assert(array_length(global_keywords) == (u64)GlobalKeyword::count);
|
||||||
|
|
||||||
@ -3226,7 +3226,7 @@ void parse(Module* module)
|
|||||||
};
|
};
|
||||||
|
|
||||||
String function_keywords[] = {
|
String function_keywords[] = {
|
||||||
str("cc"),
|
string_literal("cc"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(function_keywords) == (u64)FunctionKeyword::count);
|
static_assert(array_length(function_keywords) == (u64)FunctionKeyword::count);
|
||||||
|
|
||||||
@ -3251,7 +3251,7 @@ void parse(Module* module)
|
|||||||
skip_space(module);
|
skip_space(module);
|
||||||
auto calling_convention_string = parse_identifier(module);
|
auto calling_convention_string = parse_identifier(module);
|
||||||
String calling_conventions[] = {
|
String calling_conventions[] = {
|
||||||
str("c"),
|
string_literal("c"),
|
||||||
};
|
};
|
||||||
static_assert(array_length(calling_conventions) == (u64)CallingConvention::count);
|
static_assert(array_length(calling_conventions) == (u64)CallingConvention::count);
|
||||||
|
|
||||||
@ -3368,7 +3368,7 @@ void parse(Module* module)
|
|||||||
.is_variable_arguments = is_variable_arguments,
|
.is_variable_arguments = is_variable_arguments,
|
||||||
},
|
},
|
||||||
.id = TypeId::function,
|
.id = TypeId::function,
|
||||||
.name = str(""),
|
.name = string_literal(""),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto storage = new_value(module);
|
auto storage = new_value(module);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user