"@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 escaping : 1;
bool is_value : 1;
bool is_autoimport : 1;
union
{
void *backend_ref;

View File

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

View File

@@ -1157,6 +1157,7 @@ AttributeType sema_analyse_attribute(SemaContext *context, Attr *attr, Attribute
[ATTRIBUTE_OVERLAP] = ATTR_BITSTRUCT,
[ATTRIBUTE_NOSCOPE] = ATTR_MACRO,
[ATTRIBUTE_ESCAPING] = ATTR_MACRO,
[ATTRIBUTE_AUTOIMPORT] = ATTR_MACRO | ATTR_FUNC,
};
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_WEAK: SET_ATTR(attr_weak);
case ATTRIBUTE_NAKED: SET_ATTR(attr_naked);
case ATTRIBUTE_AUTOIMPORT:
decl->is_autoimport = true;
break;
default:
UNREACHABLE
}
@@ -1571,6 +1575,9 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl)
had = decl->escaping;
decl->escaping = true;
break;
case ATTRIBUTE_AUTOIMPORT:
decl->is_autoimport = true;
break;
default:
UNREACHABLE
}

View File

@@ -883,10 +883,28 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to,
// Already handled
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");
return false;
if (decl->module != context->unit->module && !decl->is_autoimport && !expr->identifier_expr.path)
{
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)
{

View File

@@ -214,6 +214,7 @@ void symtab_init(uint32_t capacity)
attribute_list[ATTRIBUTE_REGCALL] = KW_DEF("regcall");
attribute_list[ATTRIBUTE_FASTCALL] = KW_DEF("fastcall");
attribute_list[ATTRIBUTE_OVERLAP] = KW_DEF("overlap");
attribute_list[ATTRIBUTE_AUTOIMPORT] = KW_DEF("autoimport");
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;
fn void test()
{
@bar1();
@bar::bar1();
}
/* #expect: baz.ll