"@autoimport" attribute #366

This commit is contained in:
Christoffer Lerno
2022-01-18 23:09:30 +01:00
committed by Christoffer Lerno
parent 8adb0faa06
commit 556be2ff7f
7 changed files with 68 additions and 4 deletions

View File

@@ -586,6 +586,7 @@ typedef struct Decl_
bool no_scope : 1; bool no_scope : 1;
bool escaping : 1; bool escaping : 1;
bool is_value : 1; bool is_value : 1;
bool is_autoimport : 1;
union union
{ {
void *backend_ref; void *backend_ref;

View File

@@ -654,6 +654,7 @@ typedef enum
ATTRIBUTE_REGCALL, ATTRIBUTE_REGCALL,
ATTRIBUTE_FASTCALL, ATTRIBUTE_FASTCALL,
ATTRIBUTE_OVERLAP, ATTRIBUTE_OVERLAP,
ATTRIBUTE_AUTOIMPORT,
ATTRIBUTE_NONE, ATTRIBUTE_NONE,
NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE, NUMBER_OF_ATTRIBUTES = ATTRIBUTE_NONE,
} AttributeType; } AttributeType;

View File

@@ -1157,6 +1157,7 @@ AttributeType sema_analyse_attribute(SemaContext *context, Attr *attr, Attribute
[ATTRIBUTE_OVERLAP] = ATTR_BITSTRUCT, [ATTRIBUTE_OVERLAP] = ATTR_BITSTRUCT,
[ATTRIBUTE_NOSCOPE] = ATTR_MACRO, [ATTRIBUTE_NOSCOPE] = ATTR_MACRO,
[ATTRIBUTE_ESCAPING] = ATTR_MACRO, [ATTRIBUTE_ESCAPING] = ATTR_MACRO,
[ATTRIBUTE_AUTOIMPORT] = ATTR_MACRO | ATTR_FUNC,
}; };
if ((attribute_domain[type] & domain) != domain) if ((attribute_domain[type] & domain) != domain)
@@ -1481,6 +1482,9 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl)
case ATTRIBUTE_NORETURN: SET_ATTR(attr_noreturn); case ATTRIBUTE_NORETURN: SET_ATTR(attr_noreturn);
case ATTRIBUTE_WEAK: SET_ATTR(attr_weak); case ATTRIBUTE_WEAK: SET_ATTR(attr_weak);
case ATTRIBUTE_NAKED: SET_ATTR(attr_naked); case ATTRIBUTE_NAKED: SET_ATTR(attr_naked);
case ATTRIBUTE_AUTOIMPORT:
decl->is_autoimport = true;
break;
default: default:
UNREACHABLE UNREACHABLE
} }
@@ -1571,6 +1575,9 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl)
had = decl->escaping; had = decl->escaping;
decl->escaping = true; decl->escaping = true;
break; break;
case ATTRIBUTE_AUTOIMPORT:
decl->is_autoimport = true;
break;
default: default:
UNREACHABLE UNREACHABLE
} }

View File

@@ -883,10 +883,28 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to,
// Already handled // Already handled
if (!decl_ok(decl)) return false; if (!decl_ok(decl)) return false;
if (decl->decl_kind == DECL_FUNC && !expr->identifier_expr.path && decl->module != context->unit->module) if (decl->decl_kind == DECL_FUNC || decl->decl_kind == DECL_MACRO || decl->decl_kind == DECL_GENERIC)
{ {
SEMA_ERROR(expr, "Functions from other modules, must be prefixed with the module name"); if (decl->module != context->unit->module && !decl->is_autoimport && !expr->identifier_expr.path)
return false; {
const char *message;
switch (decl->decl_kind)
{
case DECL_FUNC:
message = "Functions from other modules must be prefixed with the module name.";
break;
case DECL_MACRO:
message = "Macros from other modules must be prefixed with the module name.";
break;
case DECL_GENERIC:
message = "Generic functions from other modules must be prefixed with the module name.";
break;
default:
UNREACHABLE
}
SEMA_ERROR(expr, message);
return false;
}
} }
if (decl->resolve_status != RESOLVE_DONE) if (decl->resolve_status != RESOLVE_DONE)
{ {

View File

@@ -214,6 +214,7 @@ void symtab_init(uint32_t capacity)
attribute_list[ATTRIBUTE_REGCALL] = KW_DEF("regcall"); attribute_list[ATTRIBUTE_REGCALL] = KW_DEF("regcall");
attribute_list[ATTRIBUTE_FASTCALL] = KW_DEF("fastcall"); attribute_list[ATTRIBUTE_FASTCALL] = KW_DEF("fastcall");
attribute_list[ATTRIBUTE_OVERLAP] = KW_DEF("overlap"); attribute_list[ATTRIBUTE_OVERLAP] = KW_DEF("overlap");
attribute_list[ATTRIBUTE_AUTOIMPORT] = KW_DEF("autoimport");
for (unsigned i = 0; i < NUMBER_OF_ATTRIBUTES; i++) for (unsigned i = 0; i < NUMBER_OF_ATTRIBUTES; i++)
{ {

View File

@@ -0,0 +1,36 @@
module foo;
fn int test() @autoimport
{
return 1;
}
macro int testm() @autoimport
{
return 1;
}
fn int test1()
{
return 1;
}
macro int testm1()
{
return 1;
}
module bar;
import foo;
fn void main()
{
@testm();
test();
}
fn void main2()
{
@testm1(); // #error: Macros from other modules must be prefixed with the module nam
test1(); // #error: Functions from other modules must be prefixed with the module nam
}

View File

@@ -14,7 +14,7 @@ module baz;
import bar; import bar;
fn void test() fn void test()
{ {
@bar1(); @bar::bar1();
} }
/* #expect: baz.ll /* #expect: baz.ll