Support int[*] { 1, 2, 3 } expressions.

This commit is contained in:
Christoffer Lerno
2024-09-12 00:11:09 +02:00
parent 1b54a99f6a
commit 9f4da339c3
4 changed files with 42 additions and 7 deletions

View File

@@ -6,6 +6,7 @@
- Introduce `arg: x` named arguments instead of `.arg = x`, deprecate old style.
- Support splat for varargs #1352.
- Allow `var` in lambdas in macros.
- Support `int[*] { 1, 2, 3 }` expressions.
### Fixes
- Issue where a lambda wasn't correctly registered as external. #1408

View File

@@ -8913,17 +8913,15 @@ static inline bool sema_expr_analyse_builtin(SemaContext *context, Expr *expr, b
return true;
}
static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr *expr)
{
TypeInfo *type_info = expr->expr_compound_literal.type_info;
if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false;
// We allow infering the size of arrays.
if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_INFER)) return false;
Type *type = type_info->type;
if (type_is_optional(type))
{
SEMA_ERROR(type_info,
"The type here should always be written as a plain type and not an optional, please remove the '!'.");
return false;
RETURN_SEMA_ERROR(type_info, "The type here should always be written as a plain type and not an optional, please remove the '!'.");
}
if (!sema_resolve_type_structure(context, type, type_info->span)) return false;
if (!sema_expr_analyse_initializer_list(context, type, expr->expr_compound_literal.initializer)) return false;
@@ -8970,8 +8968,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
case EXPR_EMBED:
return sema_expr_analyse_embed(context, expr, false);
case EXPR_VASPLAT:
SEMA_ERROR(expr, "'$vasplat' can only be used inside of macros.");
return false;
RETURN_SEMA_ERROR(expr, "'$vasplat' can only be used inside of macros.");
case EXPR_GENERIC_IDENT:
return sema_expr_analyse_generic_ident(context, expr);
case EXPR_LAMBDA:

View File

@@ -9,6 +9,7 @@
#if PLATFORM_WINDOWS
#include "direct.h"
#include "intrin.h"
#endif
#if FETCH_AVAILABLE
@@ -412,6 +413,22 @@ static inline bool is_power_of_two(uint64_t x)
return x != 0 && (x & (x - 1)) == 0;
}
static int clz(uint64_t num)
{
#if IS_CLANG || IS_GCC
return (int)__builtin_ctzll(num);
#else
unsigned long index;
_BitScanReverse64(&index, (__int64)num);
return (int)index;
#endif
}
static inline unsigned char power_of_2(uint64_t pot_value)
{
return 64 - clz(pot_value);
}
static inline uint32_t next_highest_power_of_2(uint32_t v)
{
v--;

View File

@@ -0,0 +1,20 @@
// #target: windows-x64
module test;
const int[*] X = int[*] { 1, 2, 3 };
int[*] y = int[*] { 1, 2, 3 };
fn void main()
{
int x = $typeof(int[*] { 1, 2, 3}).len;
int z = X.len;
int w = y.len;
}
/* #expect: test.ll
@test.X = local_unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4
@test.y = local_unnamed_addr global [3 x i32] [i32 1, i32 2, i32 3], align 4
store i32 3, ptr %x, align 4
store i32 3, ptr %z, align 4
store i32 3, ptr %w, align 4