mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Reorganize decl attribute code
This commit is contained in:
@@ -55,7 +55,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
String const ODIN_VERSION = str_lit("0.9.1");
|
String const ODIN_VERSION = str_lit("0.9.2");
|
||||||
String cross_compile_target = str_lit("");
|
String cross_compile_target = str_lit("");
|
||||||
String cross_compile_lib_dir = str_lit("");
|
String cross_compile_lib_dir = str_lit("");
|
||||||
|
|
||||||
|
|||||||
+40
-33
@@ -1840,15 +1840,31 @@ void init_preload(Checker *c) {
|
|||||||
init_core_map_type(c);
|
init_core_map_type(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) {
|
||||||
|
ExactValue ev = {};
|
||||||
|
if (value != nullptr) {
|
||||||
|
Operand op = {};
|
||||||
|
check_expr(c, &op, value);
|
||||||
|
if (op.mode) {
|
||||||
|
if (op.mode == Addressing_Constant) {
|
||||||
|
ev = op.value;
|
||||||
|
} else {
|
||||||
|
error(value, "Expected a constant attribute element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
if (name == "default_calling_convention") {
|
if (name == "default_calling_convention") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
auto cc = string_to_calling_convention(value.value_string);
|
auto cc = string_to_calling_convention(ev.value_string);
|
||||||
if (cc == ProcCC_Invalid) {
|
if (cc == ProcCC_Invalid) {
|
||||||
error(elem, "Unknown procedure calling convention: '%.*s'\n", LIT(value.value_string));
|
error(elem, "Unknown procedure calling convention: '%.*s'\n", LIT(ev.value_string));
|
||||||
} else {
|
} else {
|
||||||
c->foreign_context.default_cc = cc;
|
c->foreign_context.default_cc = cc;
|
||||||
}
|
}
|
||||||
@@ -1857,8 +1873,8 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (name == "link_prefix") {
|
} else if (name == "link_prefix") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
String link_prefix = value.value_string;
|
String link_prefix = ev.value_string;
|
||||||
if (!is_foreign_name_valid(link_prefix)) {
|
if (!is_foreign_name_valid(link_prefix)) {
|
||||||
error(elem, "Invalid link prefix: '%.*s'\n", LIT(link_prefix));
|
error(elem, "Invalid link prefix: '%.*s'\n", LIT(link_prefix));
|
||||||
} else {
|
} else {
|
||||||
@@ -1874,9 +1890,11 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
if (name == "link_name") {
|
if (name == "link_name") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
ac->link_name = value.value_string;
|
ac->link_name = ev.value_string;
|
||||||
if (!is_foreign_name_valid(ac->link_name)) {
|
if (!is_foreign_name_valid(ac->link_name)) {
|
||||||
error(elem, "Invalid link name: %.*s", LIT(ac->link_name));
|
error(elem, "Invalid link name: %.*s", LIT(ac->link_name));
|
||||||
}
|
}
|
||||||
@@ -1885,8 +1903,8 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (name == "link_prefix") {
|
} else if (name == "link_prefix") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
ac->link_prefix = value.value_string;
|
ac->link_prefix = ev.value_string;
|
||||||
if (!is_foreign_name_valid(ac->link_prefix)) {
|
if (!is_foreign_name_valid(ac->link_prefix)) {
|
||||||
error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
|
error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
|
||||||
}
|
}
|
||||||
@@ -1895,8 +1913,8 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (name == "deprecated") {
|
} else if (name == "deprecated") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
String msg = value.value_string;
|
String msg = ev.value_string;
|
||||||
if (msg.len == 0) {
|
if (msg.len == 0) {
|
||||||
error(elem, "Deprecation message cannot be an empty string");
|
error(elem, "Deprecation message cannot be an empty string");
|
||||||
} else {
|
} else {
|
||||||
@@ -1911,14 +1929,16 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
if (c->curr_proc_decl != nullptr) {
|
if (c->curr_proc_decl != nullptr) {
|
||||||
error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name));
|
error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == "link_name") {
|
if (name == "link_name") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
ac->link_name = value.value_string;
|
ac->link_name = ev.value_string;
|
||||||
if (!is_foreign_name_valid(ac->link_name)) {
|
if (!is_foreign_name_valid(ac->link_name)) {
|
||||||
error(elem, "Invalid link name: %.*s", LIT(ac->link_name));
|
error(elem, "Invalid link name: %.*s", LIT(ac->link_name));
|
||||||
}
|
}
|
||||||
@@ -1927,8 +1947,8 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (name == "link_prefix") {
|
} else if (name == "link_prefix") {
|
||||||
if (value.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
ac->link_prefix = value.value_string;
|
ac->link_prefix = ev.value_string;
|
||||||
if (!is_foreign_name_valid(ac->link_prefix)) {
|
if (!is_foreign_name_valid(ac->link_prefix)) {
|
||||||
error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
|
error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
|
||||||
}
|
}
|
||||||
@@ -1941,10 +1961,10 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
|||||||
error(elem, "A thread local variable declaration cannot have initialization values");
|
error(elem, "A thread local variable declaration cannot have initialization values");
|
||||||
} else if (c->foreign_context.curr_library || c->foreign_context.in_export) {
|
} else if (c->foreign_context.curr_library || c->foreign_context.in_export) {
|
||||||
error(elem, "A foreign block variable cannot be thread local");
|
error(elem, "A foreign block variable cannot be thread local");
|
||||||
} else if (value.kind == ExactValue_Invalid) {
|
} else if (ev.kind == ExactValue_Invalid) {
|
||||||
ac->thread_local_model = str_lit("default");
|
ac->thread_local_model = str_lit("default");
|
||||||
} else if (value.kind == ExactValue_String) {
|
} else if (ev.kind == ExactValue_String) {
|
||||||
String model = value.value_string;
|
String model = ev.value_string;
|
||||||
if (model == "default" ||
|
if (model == "default" ||
|
||||||
model == "localdynamic" ||
|
model == "localdynamic" ||
|
||||||
model == "initialexec" ||
|
model == "initialexec" ||
|
||||||
@@ -2013,19 +2033,6 @@ void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, De
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExactValue ev = {};
|
|
||||||
if (value != nullptr) {
|
|
||||||
Operand op = {};
|
|
||||||
check_expr(c, &op, value);
|
|
||||||
if (op.mode) {
|
|
||||||
if (op.mode != Addressing_Constant) {
|
|
||||||
error(value, "An attribute element must be constant");
|
|
||||||
} else {
|
|
||||||
ev = op.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string_set_exists(&set, name)) {
|
if (string_set_exists(&set, name)) {
|
||||||
error(elem, "Previous declaration of '%.*s'", LIT(name));
|
error(elem, "Previous declaration of '%.*s'", LIT(name));
|
||||||
continue;
|
continue;
|
||||||
@@ -2033,7 +2040,7 @@ void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, De
|
|||||||
string_set_add(&set, name);
|
string_set_add(&set, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proc(c, elem, name, ev, ac)) {
|
if (!proc(c, elem, name, value, ac)) {
|
||||||
error(elem, "Unknown attribute element name '%.*s'", LIT(name));
|
error(elem, "Unknown attribute element name '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -294,6 +294,7 @@ struct AttributeContext {
|
|||||||
isize init_expr_list_count;
|
isize init_expr_list_count;
|
||||||
String thread_local_model;
|
String thread_local_model;
|
||||||
String deprecated_message;
|
String deprecated_message;
|
||||||
|
Entity *deferred_procedure;
|
||||||
};
|
};
|
||||||
|
|
||||||
AttributeContext make_attribute_context(String link_prefix) {
|
AttributeContext make_attribute_context(String link_prefix) {
|
||||||
@@ -302,7 +303,7 @@ AttributeContext make_attribute_context(String link_prefix) {
|
|||||||
return ac;
|
return ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECL_ATTRIBUTE_PROC(_name) bool _name(CheckerContext *c, Ast *elem, String name, ExactValue value, AttributeContext *ac)
|
#define DECL_ATTRIBUTE_PROC(_name) bool _name(CheckerContext *c, Ast *elem, String name, Ast *value, AttributeContext *ac)
|
||||||
typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc);
|
typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc);
|
||||||
|
|
||||||
void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, DeclAttributeProc *proc, AttributeContext *ac);
|
void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, DeclAttributeProc *proc, AttributeContext *ac);
|
||||||
|
|||||||
Reference in New Issue
Block a user