aboutsummaryrefslogtreecommitdiff
path: root/src/check_builtin.cpp
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2024-05-05 21:50:57 +0100
committerGitHub <noreply@github.com>2024-05-05 21:50:57 +0100
commit15f7148eae89a36696916e15ed4c83fb7fed01c5 (patch)
tree1b743cb73db6ee1e5849820739c535e5a36f917f /src/check_builtin.cpp
parent1e5267c8e7ab1777e6691d28b4cf84f62c5e1871 (diff)
parent25f1d0906d2b5a8276c3832783970a798c12cc6c (diff)
Merge pull request #3526 from laytan/target-features
Improve target features support
Diffstat (limited to 'src/check_builtin.cpp')
-rw-r--r--src/check_builtin.cpp46
1 files changed, 44 insertions, 2 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index c3c217ec7..825fc6448 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -1719,6 +1719,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
case BuiltinProc_objc_register_selector:
case BuiltinProc_objc_register_class:
case BuiltinProc_atomic_type_is_lock_free:
+ case BuiltinProc_has_target_feature:
// NOTE(bill): The first arg may be a Type, this will be checked case by case
break;
@@ -3663,6 +3664,41 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
break;
}
+ case BuiltinProc_has_target_feature: {
+ String features = str_lit("");
+
+ check_expr_or_type(c, operand, ce->args[0]);
+
+ if (is_type_string(operand->type) && operand->mode == Addressing_Constant) {
+ GB_ASSERT(operand->value.kind == ExactValue_String);
+ features = operand->value.value_string;
+ } else {
+ Type *pt = base_type(operand->type);
+ if (pt->kind == Type_Proc) {
+ if (pt->Proc.require_target_feature.len != 0) {
+ GB_ASSERT(pt->Proc.enable_target_feature.len == 0);
+ features = pt->Proc.require_target_feature;
+ } else if (pt->Proc.enable_target_feature.len != 0) {
+ features = pt->Proc.enable_target_feature;
+ } else {
+ error(ce->args[0], "Expected the procedure type given to '%.*s' to have @(require_target_feature=\"...\") or @(enable_target_feature=\"...\")", LIT(builtin_name));
+ }
+ } else {
+ error(ce->args[0], "Expected a constant string or procedure type for '%.*s'", LIT(builtin_name));
+ }
+ }
+
+ String invalid;
+ if (!check_target_feature_is_valid_globally(features, &invalid)) {
+ error(ce->args[0], "Target feature '%.*s' is not a valid target feature", LIT(invalid));
+ }
+
+ operand->value = exact_value_bool(check_target_feature_is_enabled(features, nullptr));
+ operand->mode = Addressing_Constant;
+ operand->type = t_untyped_bool;
+ break;
+ }
+
case BuiltinProc_soa_struct: {
Operand x = {};
Operand y = {};
@@ -6014,7 +6050,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
- enable_target_feature({}, str_lit("atomics"));
+ if (!check_target_feature_is_enabled(str_lit("atomics"), nullptr)) {
+ error(call, "'%.*s' requires target feature 'atomics' to be enabled, enable it with -target-features:\"atomics\" or choose a different -microarch", LIT(builtin_name));
+ return false;
+ }
Operand ptr = {};
Operand expected = {};
@@ -6068,7 +6107,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
- enable_target_feature({}, str_lit("atomics"));
+ if (!check_target_feature_is_enabled(str_lit("atomics"), nullptr)) {
+ error(call, "'%.*s' requires target feature 'atomics' to be enabled, enable it with -target-features:\"atomics\" or choose a different -microarch", LIT(builtin_name));
+ return false;
+ }
Operand ptr = {};
Operand waiters = {};