mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Make ODIN_BUILD_MODE a enum type
This commit is contained in:
@@ -386,6 +386,19 @@ Raw_Cstring :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Defined internally by the compiler
|
||||||
|
Odin_Build_Mode_Type :: enum int {
|
||||||
|
Executable,
|
||||||
|
Dynamic,
|
||||||
|
Object,
|
||||||
|
Assembly,
|
||||||
|
LLVM_IR,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE)
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Init Startup Procedures //
|
// Init Startup Procedures //
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package runtime
|
|||||||
|
|
||||||
import "core:intrinsics"
|
import "core:intrinsics"
|
||||||
|
|
||||||
when ODIN_BUILD_MODE == "dynamic" {
|
when ODIN_BUILD_MODE == .Dynamic {
|
||||||
@(link_name="_odin_entry_point", linkage="strong", require, link_section=".init")
|
@(link_name="_odin_entry_point", linkage="strong", require, link_section=".init")
|
||||||
_odin_entry_point :: proc "c" () {
|
_odin_entry_point :: proc "c" () {
|
||||||
context = default_context()
|
context = default_context()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package runtime
|
|||||||
|
|
||||||
import "core:intrinsics"
|
import "core:intrinsics"
|
||||||
|
|
||||||
when ODIN_BUILD_MODE == "dynamic" {
|
when ODIN_BUILD_MODE == .Dynamic {
|
||||||
@(link_name="DllMain", linkage="strong", require)
|
@(link_name="DllMain", linkage="strong", require)
|
||||||
DllMain :: proc "stdcall" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 {
|
DllMain :: proc "stdcall" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 {
|
||||||
context = default_context()
|
context = default_context()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ IS_WASM :: ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64"
|
|||||||
@(private)
|
@(private)
|
||||||
RUNTIME_LINKAGE :: "strong" when (
|
RUNTIME_LINKAGE :: "strong" when (
|
||||||
(ODIN_USE_SEPARATE_MODULES ||
|
(ODIN_USE_SEPARATE_MODULES ||
|
||||||
ODIN_BUILD_MODE == "dynamic" ||
|
ODIN_BUILD_MODE == .Dynamic ||
|
||||||
!ODIN_NO_CRT) &&
|
!ODIN_NO_CRT) &&
|
||||||
!IS_WASM) else "internal"
|
!IS_WASM) else "internal"
|
||||||
RUNTIME_REQUIRE :: true
|
RUNTIME_REQUIRE :: true
|
||||||
|
|||||||
+3
-20
@@ -119,6 +119,8 @@ enum BuildModeKind {
|
|||||||
BuildMode_Object,
|
BuildMode_Object,
|
||||||
BuildMode_Assembly,
|
BuildMode_Assembly,
|
||||||
BuildMode_LLVM_IR,
|
BuildMode_LLVM_IR,
|
||||||
|
|
||||||
|
BuildMode_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CommandKind : u32 {
|
enum CommandKind : u32 {
|
||||||
@@ -172,10 +174,9 @@ struct BuildContext {
|
|||||||
String ODIN_VENDOR; // compiler vendor
|
String ODIN_VENDOR; // compiler vendor
|
||||||
String ODIN_VERSION; // compiler version
|
String ODIN_VERSION; // compiler version
|
||||||
String ODIN_ROOT; // Odin ROOT
|
String ODIN_ROOT; // Odin ROOT
|
||||||
String ODIN_BUILD_MODE;
|
|
||||||
bool ODIN_DEBUG; // Odin in debug mode
|
bool ODIN_DEBUG; // Odin in debug mode
|
||||||
bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
|
bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
|
||||||
bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
|
bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
|
||||||
|
|
||||||
TargetEndianKind endian_kind;
|
TargetEndianKind endian_kind;
|
||||||
|
|
||||||
@@ -855,24 +856,6 @@ void init_build_context(TargetMetrics *cross_target) {
|
|||||||
bc->ODIN_VENDOR = str_lit("odin");
|
bc->ODIN_VENDOR = str_lit("odin");
|
||||||
bc->ODIN_VERSION = ODIN_VERSION;
|
bc->ODIN_VERSION = ODIN_VERSION;
|
||||||
bc->ODIN_ROOT = odin_root_dir();
|
bc->ODIN_ROOT = odin_root_dir();
|
||||||
switch (bc->build_mode) {
|
|
||||||
default:
|
|
||||||
case BuildMode_Executable:
|
|
||||||
bc->ODIN_BUILD_MODE = str_lit("executable");
|
|
||||||
break;
|
|
||||||
case BuildMode_DynamicLibrary:
|
|
||||||
bc->ODIN_BUILD_MODE = str_lit("dynamic");
|
|
||||||
break;
|
|
||||||
case BuildMode_Object:
|
|
||||||
bc->ODIN_BUILD_MODE = str_lit("object");
|
|
||||||
break;
|
|
||||||
case BuildMode_Assembly:
|
|
||||||
bc->ODIN_BUILD_MODE = str_lit("assembly");
|
|
||||||
break;
|
|
||||||
case BuildMode_LLVM_IR:
|
|
||||||
bc->ODIN_BUILD_MODE = str_lit("llvm-ir");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bc->copy_file_contents = true;
|
bc->copy_file_contents = true;
|
||||||
|
|
||||||
|
|||||||
+62
-50
@@ -119,6 +119,58 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name
|
|||||||
void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint);
|
void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint);
|
||||||
void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_);
|
void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_);
|
||||||
|
|
||||||
|
|
||||||
|
void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") {
|
||||||
|
auto results = did_you_mean_results(d);
|
||||||
|
if (results.count != 0) {
|
||||||
|
error_line("\tSuggestion: Did you mean?\n");
|
||||||
|
for_array(i, results) {
|
||||||
|
String const &target = results[i].target;
|
||||||
|
error_line("\t\t%s%.*s\n", prefix, LIT(target));
|
||||||
|
// error_line("\t\t%.*s %td\n", LIT(target), results[i].distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_did_you_mean_type(String const &name, Array<Entity *> const &fields, char const *prefix = "") {
|
||||||
|
ERROR_BLOCK();
|
||||||
|
|
||||||
|
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
|
||||||
|
defer (did_you_mean_destroy(&d));
|
||||||
|
|
||||||
|
for_array(i, fields) {
|
||||||
|
did_you_mean_append(&d, fields[i]->token.string);
|
||||||
|
}
|
||||||
|
check_did_you_mean_print(&d, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields, char const *prefix = "") {
|
||||||
|
ERROR_BLOCK();
|
||||||
|
|
||||||
|
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
|
||||||
|
defer (did_you_mean_destroy(&d));
|
||||||
|
|
||||||
|
for_array(i, fields) {
|
||||||
|
did_you_mean_append(&d, fields[i]->token.string);
|
||||||
|
}
|
||||||
|
check_did_you_mean_print(&d, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") {
|
||||||
|
ERROR_BLOCK();
|
||||||
|
|
||||||
|
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
|
||||||
|
defer (did_you_mean_destroy(&d));
|
||||||
|
|
||||||
|
mutex_lock(&scope->mutex);
|
||||||
|
for_array(i, scope->elements.entries) {
|
||||||
|
Entity *e = scope->elements.entries[i].value;
|
||||||
|
did_you_mean_append(&d, e->token.string);
|
||||||
|
}
|
||||||
|
mutex_unlock(&scope->mutex);
|
||||||
|
check_did_you_mean_print(&d, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
Entity *entity_from_expr(Ast *expr) {
|
Entity *entity_from_expr(Ast *expr) {
|
||||||
expr = unparen_expr(expr);
|
expr = unparen_expr(expr);
|
||||||
switch (expr->kind) {
|
switch (expr->kind) {
|
||||||
@@ -3361,7 +3413,17 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ERROR_BLOCK();
|
||||||
|
|
||||||
error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text);
|
error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text);
|
||||||
|
if (operand->value.kind == ExactValue_String) {
|
||||||
|
String key = operand->value.value_string;
|
||||||
|
if (is_type_string(operand->type) && is_type_enum(target_type)) {
|
||||||
|
gb_printf_err("HERE!\n");
|
||||||
|
Type *et = base_type(target_type);
|
||||||
|
check_did_you_mean_type(key, et->Enum.fields, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gb_string_free(from_type_str);
|
gb_string_free(from_type_str);
|
||||||
gb_string_free(type_str);
|
gb_string_free(type_str);
|
||||||
@@ -3979,56 +4041,6 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti
|
|||||||
if (success_) *success_ = true;
|
if (success_) *success_ = true;
|
||||||
return empty_exact_value;
|
return empty_exact_value;
|
||||||
}
|
}
|
||||||
void check_did_you_mean_print(DidYouMeanAnswers *d) {
|
|
||||||
auto results = did_you_mean_results(d);
|
|
||||||
if (results.count != 0) {
|
|
||||||
error_line("\tSuggestion: Did you mean?\n");
|
|
||||||
for_array(i, results) {
|
|
||||||
String const &target = results[i].target;
|
|
||||||
error_line("\t\t%.*s\n", LIT(target));
|
|
||||||
// error_line("\t\t%.*s %td\n", LIT(target), results[i].distance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_did_you_mean_type(String const &name, Array<Entity *> const &fields) {
|
|
||||||
ERROR_BLOCK();
|
|
||||||
|
|
||||||
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
|
|
||||||
defer (did_you_mean_destroy(&d));
|
|
||||||
|
|
||||||
for_array(i, fields) {
|
|
||||||
did_you_mean_append(&d, fields[i]->token.string);
|
|
||||||
}
|
|
||||||
check_did_you_mean_print(&d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields) {
|
|
||||||
ERROR_BLOCK();
|
|
||||||
|
|
||||||
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name);
|
|
||||||
defer (did_you_mean_destroy(&d));
|
|
||||||
|
|
||||||
for_array(i, fields) {
|
|
||||||
did_you_mean_append(&d, fields[i]->token.string);
|
|
||||||
}
|
|
||||||
check_did_you_mean_print(&d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_did_you_mean_scope(String const &name, Scope *scope) {
|
|
||||||
ERROR_BLOCK();
|
|
||||||
|
|
||||||
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
|
|
||||||
defer (did_you_mean_destroy(&d));
|
|
||||||
|
|
||||||
mutex_lock(&scope->mutex);
|
|
||||||
for_array(i, scope->elements.entries) {
|
|
||||||
Entity *e = scope->elements.entries[i].value;
|
|
||||||
did_you_mean_append(&d, e->token.string);
|
|
||||||
}
|
|
||||||
mutex_unlock(&scope->mutex);
|
|
||||||
check_did_you_mean_print(&d);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) {
|
Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) {
|
||||||
Type *array_type = base_type(type_deref(original_type));
|
Type *array_type = base_type(type_deref(original_type));
|
||||||
|
|||||||
+63
-1
@@ -780,6 +780,54 @@ AstPackage *create_builtin_package(char const *name) {
|
|||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GlobalEnumValue {
|
||||||
|
char const *name;
|
||||||
|
i64 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
Slice<Entity *> add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count) {
|
||||||
|
Scope *scope = create_scope(nullptr, builtin_pkg->scope);
|
||||||
|
Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved);
|
||||||
|
|
||||||
|
Type *enum_type = alloc_type_enum();
|
||||||
|
Type *named_type = alloc_type_named(type_name, enum_type, e);
|
||||||
|
set_base_type(named_type, enum_type);
|
||||||
|
enum_type->Enum.base_type = t_int;
|
||||||
|
enum_type->Enum.scope = scope;
|
||||||
|
|
||||||
|
auto fields = array_make<Entity *>(permanent_allocator(), value_count);
|
||||||
|
for (isize i = 0; i < value_count; i++) {
|
||||||
|
i64 value = values[i].value;
|
||||||
|
Entity *e = alloc_entity_constant(scope, make_token_ident(values[i].name), named_type, exact_value_i64(value));
|
||||||
|
e->flags |= EntityFlag_Visited;
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
|
fields[i] = e;
|
||||||
|
|
||||||
|
Entity *ie = scope_insert(scope, e);
|
||||||
|
GB_ASSERT(ie == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum_type->Enum.fields = fields;
|
||||||
|
enum_type->Enum.min_value_index = 0;
|
||||||
|
enum_type->Enum.max_value_index = value_count-1;
|
||||||
|
enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value;
|
||||||
|
enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value;
|
||||||
|
|
||||||
|
return slice_from_array(fields);
|
||||||
|
}
|
||||||
|
void add_global_enum_constant(Slice<Entity *> const &fields, char const *name, i64 value) {
|
||||||
|
for (Entity *field : fields) {
|
||||||
|
GB_ASSERT(field->kind == Entity_Constant);
|
||||||
|
if (value == exact_value_to_i64(field->Constant.value)) {
|
||||||
|
add_global_constant(name, field->type, field->Constant.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void init_universal(void) {
|
void init_universal(void) {
|
||||||
BuildContext *bc = &build_context;
|
BuildContext *bc = &build_context;
|
||||||
|
|
||||||
@@ -815,7 +863,21 @@ void init_universal(void) {
|
|||||||
add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
|
add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
|
||||||
add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT);
|
add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT);
|
||||||
|
|
||||||
add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE);
|
{
|
||||||
|
GlobalEnumValue values[BuildMode_COUNT] = {
|
||||||
|
{"Executable", BuildMode_Executable},
|
||||||
|
{"Dynamic", BuildMode_DynamicLibrary},
|
||||||
|
{"Object", BuildMode_Object},
|
||||||
|
{"Assembly", BuildMode_Assembly},
|
||||||
|
{"LLVM_IR", BuildMode_LLVM_IR},
|
||||||
|
};
|
||||||
|
|
||||||
|
auto fields = add_global_enum_type(str_lit("Odin_Build_Mode_Type"), values, gb_count_of(values));
|
||||||
|
add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE);
|
||||||
|
|
||||||
add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG);
|
add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG);
|
||||||
add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT);
|
add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT);
|
||||||
add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR);
|
add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR);
|
||||||
|
|||||||
Reference in New Issue
Block a user