build_mode, has_debug_info and self-hosted test
All checks were successful
All checks were successful
This commit is contained in:
parent
fb54aec7c9
commit
3eca360dbe
@ -5449,8 +5449,15 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) void
|
|||||||
>base_name = relative_file_path[base_start..extension_start];
|
>base_name = relative_file_path[base_start..extension_start];
|
||||||
|
|
||||||
>is_compiler = string_equal(relative_file_path, "src/compiler.bbb");
|
>is_compiler = string_equal(relative_file_path, "src/compiler.bbb");
|
||||||
>outputh_path_dir = arena_join_string(arena, [
|
>base_dir = arena_join_string(arena, [
|
||||||
base_cache_dir,
|
base_cache_dir,
|
||||||
|
"/",
|
||||||
|
#enum_name(#build_mode),
|
||||||
|
"_",
|
||||||
|
#select(#has_debug_info(), "di", "nodi"),
|
||||||
|
][..]);
|
||||||
|
>outputh_path_dir = arena_join_string(arena, [
|
||||||
|
base_dir,
|
||||||
#select(is_compiler, "/compiler/", "/"),
|
#select(is_compiler, "/compiler/", "/"),
|
||||||
#enum_name(compile_options.build_mode),
|
#enum_name(compile_options.build_mode),
|
||||||
"_",
|
"_",
|
||||||
@ -5458,11 +5465,14 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) void
|
|||||||
][..]);
|
][..]);
|
||||||
|
|
||||||
os_make_directory(base_cache_dir.pointer);
|
os_make_directory(base_cache_dir.pointer);
|
||||||
|
os_make_directory(base_dir.pointer);
|
||||||
|
|
||||||
if (is_compiler)
|
if (is_compiler)
|
||||||
{
|
{
|
||||||
>compiler_dir = arena_join_string(arena, [ base_cache_dir, "/compiler" ][..]);
|
>compiler_dir = arena_join_string(arena, [ base_dir, "/compiler" ][..]);
|
||||||
os_make_directory(compiler_dir.pointer);
|
os_make_directory(compiler_dir.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
os_make_directory(outputh_path_dir.pointer);
|
os_make_directory(outputh_path_dir.pointer);
|
||||||
|
|
||||||
>outputh_path_base = arena_join_string(arena, [ outputh_path_dir, "/", base_name ][..]);
|
>outputh_path_base = arena_join_string(arena, [ outputh_path_dir, "/", base_name ][..]);
|
||||||
|
@ -588,24 +588,27 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BuildMode build_mode = BuildMode::debug_none; build_mode < BuildMode::count; build_mode = (BuildMode)((backing_type(BuildMode))build_mode + 1))
|
for (BuildMode compiler_build_mode = BuildMode::debug_none; compiler_build_mode < BuildMode::count; compiler_build_mode = (BuildMode)((backing_type(BuildMode))compiler_build_mode + 1))
|
||||||
{
|
{
|
||||||
for (bool has_debug_info : has_debug_info_array)
|
for (bool compiler_has_debug_info : has_debug_info_array)
|
||||||
{
|
{
|
||||||
auto compiler = compile_file(arena, {
|
auto compiler = compile_file(arena, {
|
||||||
.relative_file_path = string_literal("src/compiler.bbb"),
|
.relative_file_path = string_literal("src/compiler.bbb"),
|
||||||
.build_mode = build_mode,
|
.build_mode = compiler_build_mode,
|
||||||
.has_debug_info = has_debug_info,
|
.has_debug_info = compiler_has_debug_info,
|
||||||
.silent = true,
|
.silent = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (auto name: names)
|
Slice<String> name_slice = array_to_slice(names);
|
||||||
|
for (auto name: name_slice(0, 1))
|
||||||
{
|
{
|
||||||
|
// COMPILATION START
|
||||||
|
|
||||||
BuildMode build_mode = BuildMode::debug_none;
|
BuildMode build_mode = BuildMode::debug_none;
|
||||||
bool has_debug_info = true;
|
bool has_debug_info = true;
|
||||||
String relative_file_path_parts[] = { string_literal("tests/"), name, string_literal(".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));
|
||||||
char* const arguments[] =
|
char* const compiler_arguments[] =
|
||||||
{
|
{
|
||||||
(char*)compiler.pointer,
|
(char*)compiler.pointer,
|
||||||
(char*)"compile",
|
(char*)"compile",
|
||||||
@ -614,7 +617,7 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
(char*)(has_debug_info ? "true" : "false"),
|
(char*)(has_debug_info ? "true" : "false"),
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
Slice<char* const> arg_slice = array_to_slice(arguments);
|
Slice<char* const> arg_slice = array_to_slice(compiler_arguments);
|
||||||
arg_slice.length -= 1;
|
arg_slice.length -= 1;
|
||||||
auto execution = os_execute(arena, arg_slice, environment, {});
|
auto execution = os_execute(arena, arg_slice, environment, {});
|
||||||
auto success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0;
|
auto success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0;
|
||||||
@ -625,7 +628,42 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
|
|||||||
print(string_literal("\n"));
|
print(string_literal("\n"));
|
||||||
bb_fail();
|
bb_fail();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
// COMPILATION END
|
||||||
|
|
||||||
|
// RUN START
|
||||||
|
|
||||||
|
String exe_parts[] = {
|
||||||
|
string_literal("self-hosted-bb-cache/"),
|
||||||
|
build_mode_to_string(compiler_build_mode),
|
||||||
|
string_literal("_"),
|
||||||
|
compiler_has_debug_info ? string_literal("di") : string_literal("nodi"),
|
||||||
|
string_literal("/"),
|
||||||
|
build_mode_to_string(build_mode),
|
||||||
|
string_literal("_"),
|
||||||
|
has_debug_info ? string_literal("di") : string_literal("nodi"),
|
||||||
|
string_literal("/"),
|
||||||
|
name,
|
||||||
|
};
|
||||||
|
String exe_path = arena_join_string(arena, array_to_slice(exe_parts));
|
||||||
|
char* const run_arguments[] =
|
||||||
|
{
|
||||||
|
(char*)exe_path.pointer,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
arg_slice = array_to_slice(run_arguments);
|
||||||
|
arg_slice.length -= 1;
|
||||||
|
execution = os_execute(arena, arg_slice, environment, {});
|
||||||
|
success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0;
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
print(string_literal("Self-hosted test failed to run: "));
|
||||||
|
print(name);
|
||||||
|
print(string_literal("\n"));
|
||||||
|
bb_fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
// RUN END
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ enum class TypeId
|
|||||||
|
|
||||||
struct TypeInteger
|
struct TypeInteger
|
||||||
{
|
{
|
||||||
u32 bit_count;
|
u64 bit_count;
|
||||||
bool is_signed;
|
bool is_signed;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -840,6 +840,8 @@ enum class ValueId
|
|||||||
string_to_enum,
|
string_to_enum,
|
||||||
local,
|
local,
|
||||||
argument,
|
argument,
|
||||||
|
build_mode,
|
||||||
|
has_debug_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ValueConstantInteger
|
struct ValueConstantInteger
|
||||||
@ -1293,6 +1295,7 @@ struct Module
|
|||||||
Type* first_function_type;
|
Type* first_function_type;
|
||||||
|
|
||||||
Type* va_list_type;
|
Type* va_list_type;
|
||||||
|
Type* build_mode_enum;
|
||||||
|
|
||||||
Value* void_value;
|
Value* void_value;
|
||||||
Global* first_global;
|
Global* first_global;
|
||||||
@ -2037,6 +2040,13 @@ fn Type* resolve_alias(Module* module, Type* type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn u64 enum_bit_count(u64 highest_value)
|
||||||
|
{
|
||||||
|
auto needed_bit_count = 64 - (u64)clz(highest_value);
|
||||||
|
needed_bit_count = needed_bit_count ? needed_bit_count : 1;
|
||||||
|
return needed_bit_count;
|
||||||
|
}
|
||||||
|
|
||||||
struct ArgBuilder
|
struct ArgBuilder
|
||||||
{
|
{
|
||||||
char* args[128];
|
char* args[128];
|
||||||
|
@ -2609,6 +2609,52 @@ fn void copy_block(Module* module, Scope* parent_scope, BlockCopy copy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn Type* get_build_mode_enum(Module* module)
|
||||||
|
{
|
||||||
|
auto result = module->build_mode_enum;
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
String enum_names[] = {
|
||||||
|
string_literal("debug_none"),
|
||||||
|
string_literal("debug"),
|
||||||
|
string_literal("soft_optimize"),
|
||||||
|
string_literal("optimize_for_speed"),
|
||||||
|
string_literal("optimize_for_size"),
|
||||||
|
string_literal("aggressively_optimize_for_speed"),
|
||||||
|
string_literal("aggressively_optimize_for_size"),
|
||||||
|
};
|
||||||
|
|
||||||
|
auto enum_fields = arena_allocate<EnumField>(module->arena, array_length(enum_names));
|
||||||
|
|
||||||
|
u64 field_value = 0;
|
||||||
|
for (String enum_name : enum_names)
|
||||||
|
{
|
||||||
|
enum_fields[field_value] = {
|
||||||
|
.name = enum_name,
|
||||||
|
.value = field_value,
|
||||||
|
};
|
||||||
|
|
||||||
|
field_value += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto backing_type = integer_type(module, { .bit_count = array_length(enum_names) - 1, .is_signed = false });
|
||||||
|
|
||||||
|
result = type_allocate_init(module, {
|
||||||
|
.enumerator = {
|
||||||
|
.fields = enum_fields,
|
||||||
|
.backing_type = backing_type,
|
||||||
|
},
|
||||||
|
.id = TypeId::enumerator,
|
||||||
|
.name = string_literal("BuildMode"),
|
||||||
|
.scope = &module->scope,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnalysis analysis)
|
fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnalysis analysis)
|
||||||
{
|
{
|
||||||
assert(!value->type);
|
assert(!value->type);
|
||||||
@ -2829,6 +2875,7 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
|
|||||||
typecheck(module, expected_type, string_type);
|
typecheck(module, expected_type, string_type);
|
||||||
analyze_type(module, unary_value, 0, { .must_be_constant = analysis.must_be_constant });
|
analyze_type(module, unary_value, 0, { .must_be_constant = analysis.must_be_constant });
|
||||||
auto enum_type = unary_value->type;
|
auto enum_type = unary_value->type;
|
||||||
|
resolve_type_in_place(module, enum_type);
|
||||||
if (enum_type->id != TypeId::enumerator)
|
if (enum_type->id != TypeId::enumerator)
|
||||||
{
|
{
|
||||||
report_error();
|
report_error();
|
||||||
@ -4341,6 +4388,22 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
|
|||||||
module->current_macro_instantiation = current_macro_instantiation;
|
module->current_macro_instantiation = current_macro_instantiation;
|
||||||
module->current_function = current_function;
|
module->current_function = current_function;
|
||||||
} break;
|
} break;
|
||||||
|
case ValueId::build_mode:
|
||||||
|
{
|
||||||
|
value_type = get_build_mode_enum(module);
|
||||||
|
if (expected_type)
|
||||||
|
{
|
||||||
|
// typecheck(module, expected_type);
|
||||||
|
trap();
|
||||||
|
}
|
||||||
|
|
||||||
|
typecheck(module, expected_type, value_type);
|
||||||
|
} break;
|
||||||
|
case ValueId::has_debug_info:
|
||||||
|
{
|
||||||
|
value_type = uint1(module);
|
||||||
|
typecheck(module, expected_type, value_type);
|
||||||
|
} break;
|
||||||
default: unreachable();
|
default: unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7646,6 +7709,14 @@ fn void emit_value(Module* module, Value* value, TypeKind type_kind, bool expect
|
|||||||
{
|
{
|
||||||
llvm_value = LLVMGetPoison(get_llvm_type(resolved_value_type, type_kind));
|
llvm_value = LLVMGetPoison(get_llvm_type(resolved_value_type, type_kind));
|
||||||
} break;
|
} break;
|
||||||
|
case ValueId::build_mode:
|
||||||
|
{
|
||||||
|
llvm_value = LLVMConstInt(get_llvm_type(resolved_value_type->enumerator.backing_type, type_kind), (u64)module->build_mode, false);
|
||||||
|
} break;
|
||||||
|
case ValueId::has_debug_info:
|
||||||
|
{
|
||||||
|
llvm_value = LLVMConstInt(get_llvm_type(resolved_value_type, type_kind), module->has_debug_info, false);
|
||||||
|
} break;
|
||||||
default: unreachable();
|
default: unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
enum class ValueIntrinsic
|
enum class ValueIntrinsic
|
||||||
{
|
{
|
||||||
align_of,
|
align_of,
|
||||||
|
build_mode,
|
||||||
byte_size,
|
byte_size,
|
||||||
enum_from_int,
|
enum_from_int,
|
||||||
enum_name,
|
enum_name,
|
||||||
extend,
|
extend,
|
||||||
|
has_debug_info,
|
||||||
integer_max,
|
integer_max,
|
||||||
int_from_enum,
|
int_from_enum,
|
||||||
int_from_pointer,
|
int_from_pointer,
|
||||||
@ -1153,10 +1155,12 @@ fn Token tokenize(Module* module)
|
|||||||
|
|
||||||
String value_intrinsics[] = {
|
String value_intrinsics[] = {
|
||||||
string_literal("align_of"),
|
string_literal("align_of"),
|
||||||
|
string_literal("build_mode"),
|
||||||
string_literal("byte_size"),
|
string_literal("byte_size"),
|
||||||
string_literal("enum_from_int"),
|
string_literal("enum_from_int"),
|
||||||
string_literal("enum_name"),
|
string_literal("enum_name"),
|
||||||
string_literal("extend"),
|
string_literal("extend"),
|
||||||
|
string_literal("has_debug_info"),
|
||||||
string_literal("integer_max"),
|
string_literal("integer_max"),
|
||||||
string_literal("int_from_enum"),
|
string_literal("int_from_enum"),
|
||||||
string_literal("int_from_pointer"),
|
string_literal("int_from_pointer"),
|
||||||
@ -1790,6 +1794,7 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
|
|||||||
} break;
|
} break;
|
||||||
case ValueIntrinsic::trap:
|
case ValueIntrinsic::trap:
|
||||||
case ValueIntrinsic::va_start:
|
case ValueIntrinsic::va_start:
|
||||||
|
case ValueIntrinsic::has_debug_info:
|
||||||
{
|
{
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
expect_character(module, left_parenthesis);
|
expect_character(module, left_parenthesis);
|
||||||
@ -1801,6 +1806,7 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
|
|||||||
{
|
{
|
||||||
case ValueIntrinsic::trap: id = ValueId::trap; break;
|
case ValueIntrinsic::trap: id = ValueId::trap; break;
|
||||||
case ValueIntrinsic::va_start: id = ValueId::va_start; break;
|
case ValueIntrinsic::va_start: id = ValueId::va_start; break;
|
||||||
|
case ValueIntrinsic::has_debug_info: id = ValueId::has_debug_info; break;
|
||||||
default: unreachable();
|
default: unreachable();
|
||||||
}
|
}
|
||||||
*result = {
|
*result = {
|
||||||
@ -1862,6 +1868,12 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
|
|||||||
.id = ValueId::binary,
|
.id = ValueId::binary,
|
||||||
};
|
};
|
||||||
} break;
|
} break;
|
||||||
|
case ValueIntrinsic::build_mode:
|
||||||
|
{
|
||||||
|
*result = {
|
||||||
|
.id = ValueId::build_mode,
|
||||||
|
};
|
||||||
|
} break;
|
||||||
case ValueIntrinsic::count: unreachable();
|
case ValueIntrinsic::count: unreachable();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -3477,8 +3489,7 @@ void parse(Module* module)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto needed_bit_count = 64 - (u32)clz(highest_value);
|
auto needed_bit_count = enum_bit_count(highest_value);
|
||||||
needed_bit_count = needed_bit_count ? needed_bit_count : 1;
|
|
||||||
|
|
||||||
if (!backing_type)
|
if (!backing_type)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user