Skip to content

Commit

Permalink
@tag on macros cannot be retrieved with tagof #1582
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Nov 4, 2024
1 parent 2138312 commit 6258cba
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
- `$define` would occasionally not properly evaluate declarations it encountered.
- Fixes with error handling recursive `@tag` #1583.
- Sometimes generating introspection info would not be in the global scope causing a crash #1586.
- @tag on macros cannot be retrieved with tagof #1582

### Stdlib changes
- Remove unintended print of `char[]` as String
Expand Down
44 changes: 41 additions & 3 deletions src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3608,6 +3608,32 @@ static inline bool sema_expr_replace_with_enum_name_array(SemaContext *context,
return sema_analyse_expr(context, enum_array_expr);
}

static inline bool sema_analyse_macro_func_access(SemaContext *context, Expr *expr, Decl *parent, Expr *identifier, const char *kw, bool *missing_ref)
{
if (kw == type_property_list[TYPE_PROPERTY_HAS_TAGOF])
{
expr->expr_kind = EXPR_TYPECALL;
expr->type_call_expr = (ExprTypeCall) { .type = parent, .property = TYPE_PROPERTY_HAS_TAGOF };
return true;
}
if (kw == type_property_list[TYPE_PROPERTY_TAGOF])
{
expr->expr_kind = EXPR_TYPECALL;
expr->type_call_expr = (ExprTypeCall) { .type = parent, .property = TYPE_PROPERTY_TAGOF };
return true;
}
if (parent->decl_kind == DECL_MACRO)
{
if (missing_ref)
{
*missing_ref = true;
return false;
}
RETURN_SEMA_ERROR(identifier, "The property '%s' is not valid on the macro '%s'.", kw, parent->name);
}
return sema_expr_analyse_type_access(context, expr, parent->type, identifier, missing_ref);
}

static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *expr, Type *parent_type, Expr *identifier, bool *missing_ref)
{
ASSERT_SPAN(expr, identifier->expr_kind == EXPR_IDENTIFIER);
Expand Down Expand Up @@ -4749,15 +4775,28 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo
SourceSpan span;
Expr *identifier = sema_expr_resolve_access_child(context, child, missing_ref);
if (!identifier) return false;
const char *kw = identifier->identifier_expr.ident;

// 2. If our left-hand side is a type, e.g. MyInt.abc, handle this here.
if (parent->expr_kind == EXPR_TYPEINFO)
{
return sema_expr_analyse_type_access(context, expr, parent->type_expr->type, identifier, missing_ref);
}
if (parent->expr_kind == EXPR_IDENTIFIER && parent->type->type_kind == TYPE_FUNC_RAW)
if (parent->expr_kind == EXPR_IDENTIFIER)
{
return sema_expr_analyse_type_access(context, expr, parent->type, identifier, missing_ref);
Decl *decl = parent->identifier_expr.decl;
switch (decl->decl_kind)
{
case DECL_FUNC:
case DECL_MACRO:
return sema_analyse_macro_func_access(context, expr, decl, identifier, kw, missing_ref);
default:
break;
}
if (parent->type->type_kind == TYPE_FUNC_RAW)
{
return sema_expr_analyse_type_access(context, expr, parent->type, identifier, missing_ref);
}
}
if (expr_is_const_member(parent))
{
Expand All @@ -4784,7 +4823,6 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo

Type *type = type_no_optional(parent->type)->canonical;
Type *flat_type = type_flatten(type);
const char *kw = identifier->identifier_expr.ident;
if (kw_type == kw)
{
if (type_is_any_raw(flat_type))
Expand Down
11 changes: 11 additions & 0 deletions test/test_suite/macros/macro_tagof.c3t
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import std::io;
macro int test() @tag("hello", 1)
{
return 1;
}

fn void main()
{
var $v = test.tagof("hello");
io::printn($v);
}

0 comments on commit 6258cba

Please sign in to comment.