mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix stringify of $vaexpr #2301.
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
- Fixed bug splatting constants into constants.
|
||||
- Resize bug when resizing memory down in ArenaAllocator, DynamicArenaAllocator, BackedArenaAllocator.
|
||||
- Error message for missing arg incorrect for methods with zero args #2296.
|
||||
- Fix stringify of $vaexpr #2301.
|
||||
|
||||
### Stdlib changes
|
||||
- Improve contract for readline. #2280
|
||||
|
||||
@@ -659,7 +659,7 @@ static Expr *parse_ct_stringify(ParseContext *c, Expr *left, SourceSpan lhs_star
|
||||
ASSIGN_EXPR_OR_RET(Expr *inner, parse_expr(c), poisoned_expr);
|
||||
const char *end = c->lexer.lexing_start - 1;
|
||||
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_expr);
|
||||
if (inner->expr_kind == EXPR_HASH_IDENT)
|
||||
if (inner->expr_kind == EXPR_HASH_IDENT || (inner->expr_kind == EXPR_CT_ARG && inner->ct_arg_expr.type == TOKEN_CT_VAEXPR))
|
||||
{
|
||||
Expr *expr = expr_new(EXPR_STRINGIFY, start_span);
|
||||
expr->inner_expr = inner;
|
||||
|
||||
@@ -10591,18 +10591,31 @@ static inline bool sema_expr_analyse_ct_stringify(SemaContext *context, Expr *ex
|
||||
{
|
||||
Expr *inner = expr->inner_expr;
|
||||
// Only hash ident style stringify reaches here.
|
||||
ASSERT_SPAN(expr, inner->expr_kind == EXPR_HASH_IDENT);
|
||||
while (true)
|
||||
{
|
||||
Decl *decl = sema_resolve_symbol(context, inner->ct_ident_expr.identifier, NULL, inner->span);
|
||||
if (!decl) return false;
|
||||
inner = decl->var.init_expr;
|
||||
while (inner->expr_kind == EXPR_OTHER_CONTEXT)
|
||||
switch (inner->expr_kind)
|
||||
{
|
||||
context = inner->expr_other_context.context;
|
||||
inner = inner->expr_other_context.inner;
|
||||
case EXPR_CT_ARG:
|
||||
{
|
||||
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(inner->ct_arg_expr.arg), NULL), false);
|
||||
inner = arg_expr;
|
||||
continue;
|
||||
}
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
context = inner->expr_other_context.context;
|
||||
inner = inner->expr_other_context.inner;
|
||||
continue;
|
||||
case EXPR_HASH_IDENT:
|
||||
{
|
||||
Decl *decl = sema_resolve_symbol(context, inner->ct_ident_expr.identifier, NULL, inner->span);
|
||||
if (!decl) return false;
|
||||
inner = decl->var.init_expr;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (inner->expr_kind != EXPR_HASH_IDENT) break;
|
||||
break;
|
||||
}
|
||||
const char *desc = span_to_string(inner->span);
|
||||
if (!desc)
|
||||
|
||||
47
test/test_suite/compile_time/stringify_vaexp.c3t
Normal file
47
test/test_suite/compile_time/stringify_vaexp.c3t
Normal file
@@ -0,0 +1,47 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std::io;
|
||||
|
||||
fn int main(String[] args)
|
||||
{
|
||||
String a = @foo1(args);
|
||||
String b = @foo2(args);
|
||||
String c = @foo3(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
macro @foo1(#expr)
|
||||
{
|
||||
return $stringify(#expr);
|
||||
}
|
||||
|
||||
macro @foo2(...)
|
||||
{
|
||||
return $stringify($vaexpr[0]);
|
||||
}
|
||||
|
||||
macro @foo3(#expr)
|
||||
{
|
||||
return @foo2(#expr);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
@.str = private unnamed_addr constant [5 x i8] c"args\00", align 1
|
||||
@.str.1 = private unnamed_addr constant [5 x i8] c"args\00", align 1
|
||||
@.str.2 = private unnamed_addr constant [5 x i8] c"args\00", align 1
|
||||
|
||||
define i32 @test.main(ptr %0, i64 %1) #0 {
|
||||
entry:
|
||||
%args = alloca %"char[][]", align 8
|
||||
%a = alloca %"char[]", align 8
|
||||
%b = alloca %"char[]", align 8
|
||||
%c = alloca %"char[]", align 8
|
||||
store ptr %0, ptr %args, align 8
|
||||
%ptradd = getelementptr inbounds i8, ptr %args, i64 8
|
||||
store i64 %1, ptr %ptradd, align 8
|
||||
store %"char[]" { ptr @.str, i64 4 }, ptr %a, align 8
|
||||
store %"char[]" { ptr @.str.1, i64 4 }, ptr %b, align 8
|
||||
store %"char[]" { ptr @.str.2, i64 4 }, ptr %c, align 8
|
||||
ret i32 0
|
||||
}
|
||||
Reference in New Issue
Block a user