mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Refactoring codegen with Flat / Lowered types. Helpers for struct gep. type_get_indexed_type no longer returns the canonical type, fixes issues in #2534
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#include "compiler_internal.h"
|
||||
|
||||
enum IntrospectIndex
|
||||
typedef enum IntrospectIndex
|
||||
{
|
||||
INTROSPECT_INDEX_KIND = 0,
|
||||
INTROSPECT_INDEX_PARENTOF = 1,
|
||||
@@ -10,14 +10,14 @@ enum IntrospectIndex
|
||||
INTROSPECT_INDEX_LEN = 5,
|
||||
INTROSPECT_INDEX_ADDITIONAL = 6,
|
||||
INTROSPECT_INDEX_TOTAL,
|
||||
};
|
||||
} IntrospectIndex;
|
||||
|
||||
bool type_is_homogenous_aggregate(Type *type, Type **base, unsigned *elements);
|
||||
static inline bool abi_type_is_type(AbiType type);
|
||||
|
||||
static inline bool abi_type_is_valid(AbiType type);
|
||||
|
||||
static inline Type *type_lowering(Type *type)
|
||||
static inline LoweredType *type_lowering(Type *type)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -95,6 +95,8 @@ typedef struct Expr_ Expr;
|
||||
typedef struct Module_ Module;
|
||||
typedef struct Type_ Type;
|
||||
typedef Type CanonicalType;
|
||||
typedef Type FlatType;
|
||||
typedef Type LoweredType;
|
||||
typedef struct Signature_ Signature;
|
||||
typedef struct ConstInitializer_ ConstInitializer;
|
||||
typedef struct CompilationUnit_ CompilationUnit;
|
||||
@@ -2681,7 +2683,7 @@ INLINE BitSize type_bit_size(Type *type);
|
||||
INLINE Type *type_vector_type(Type *type);
|
||||
|
||||
static inline CanonicalType *type_pointer_type(Type *type);
|
||||
static inline CanonicalType *type_flatten(Type *type);
|
||||
static inline FlatType *type_flatten(Type *type);
|
||||
static inline Type *type_base(Type *type);
|
||||
|
||||
INLINE TypeInfo *type_info_new(TypeInfoKind kind, SourceSpan span);
|
||||
@@ -3366,7 +3368,7 @@ static inline CanonicalType *type_distinct_inline(Type *type)
|
||||
}
|
||||
}
|
||||
}
|
||||
static inline CanonicalType *type_flatten(Type *type)
|
||||
static inline FlatType *type_flatten(Type *type)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -486,7 +486,7 @@ LLVMValueRef llvm_coerce_int_ptr(GenContext *c, LLVMValueRef value, LLVMTypeRef
|
||||
return value;
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value, Type *original_type)
|
||||
LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value)
|
||||
{
|
||||
LLVMTypeRef llvm_source_type = llvm_get_type(c, value->type);
|
||||
|
||||
@@ -656,11 +656,11 @@ static inline void llvm_emit_subscript_addr_with_base(GenContext *c, BEValue *re
|
||||
switch (type->type_kind)
|
||||
{
|
||||
case TYPE_POINTER:
|
||||
llvm_value_set_address_abi_aligned(c, result, llvm_emit_pointer_inbounds_gep_raw(
|
||||
c,
|
||||
llvm_get_pointee_type(c, parent->type),
|
||||
parent->value,
|
||||
index->value), type->pointer);
|
||||
llvm_value_set_address_abi_aligned(
|
||||
c,
|
||||
result,
|
||||
llvm_emit_pointer_inbounds_gep_raw(c, llvm_get_pointee_type(c, parent->type), parent->value, index->value),
|
||||
type->pointer);
|
||||
return;
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
@@ -4957,11 +4957,11 @@ static void llvm_expand_struct_to_args(GenContext *context, Type *param_type, LL
|
||||
Type *member_type = member->type;
|
||||
AlignSize load_align;
|
||||
LLVMValueRef member_ptr = llvm_emit_struct_gep_raw(context,
|
||||
expand_ptr,
|
||||
llvm_get_type(context, param_type),
|
||||
i,
|
||||
alignment,
|
||||
&load_align);
|
||||
expand_ptr,
|
||||
llvm_get_type(context, param_type),
|
||||
i,
|
||||
alignment,
|
||||
&load_align);
|
||||
llvm_expand_type_to_args(context, member_type, member_ptr, args, arg_count_ref, load_align);
|
||||
}
|
||||
}
|
||||
@@ -5002,16 +5002,23 @@ static void llvm_expand_type_to_args(GenContext *context, Type *param_type, LLVM
|
||||
}
|
||||
}
|
||||
|
||||
void llvm_emit_struct_gep_ref(GenContext *c, BEValue *ref, BEValue *member_ref, Type *element_type, unsigned member_id)
|
||||
{
|
||||
ASSERT(llvm_value_is_addr(ref));
|
||||
llvm_value_fold_optional(c, ref);
|
||||
AlignSize align;
|
||||
LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, ref->value, llvm_get_type(c, ref->type), member_id, ref->alignment, &align);
|
||||
llvm_value_set_address(c, member_ref, ptr, element_type, align);
|
||||
}
|
||||
|
||||
void llvm_emit_struct_member_ref(GenContext *c, BEValue *struct_ref, BEValue *member_ref, unsigned member_id)
|
||||
{
|
||||
ASSERT(llvm_value_is_addr(struct_ref));
|
||||
llvm_value_fold_optional(c, struct_ref);
|
||||
ASSERT(struct_ref->type->type_kind == TYPE_STRUCT);
|
||||
AlignSize align;
|
||||
LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, struct_ref->value, llvm_get_type(c, struct_ref->type), member_id, struct_ref->alignment, &align);
|
||||
llvm_value_set_address(c, member_ref, ptr, struct_ref->type->decl->strukt.members[member_id]->type, align);
|
||||
llvm_emit_struct_gep_ref(c, struct_ref, member_ref, struct_ref->type->decl->strukt.members[member_id]->type, member_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LLVMValueRef llvm_emit_struct_gep_raw(GenContext *c, LLVMValueRef ptr, LLVMTypeRef struct_type, unsigned index,
|
||||
unsigned struct_alignment, AlignSize *alignment)
|
||||
{
|
||||
@@ -5123,14 +5130,7 @@ void llvm_emit_slice_len(GenContext *c, BEValue *slice, BEValue *len)
|
||||
llvm_value_set(len, llvm_emit_extract_value(c, slice->value, 1), type_usz);
|
||||
return;
|
||||
}
|
||||
AlignSize alignment = 0;
|
||||
LLVMValueRef len_addr = llvm_emit_struct_gep_raw(c,
|
||||
slice->value,
|
||||
llvm_get_type(c, slice->type),
|
||||
1,
|
||||
slice->alignment,
|
||||
&alignment);
|
||||
llvm_value_set_address(c, len, len_addr, type_usz, alignment);
|
||||
llvm_emit_struct_gep_ref(c, slice, len, type_usz, 1);
|
||||
}
|
||||
|
||||
void llvm_emit_slice_pointer(GenContext *c, BEValue *slice, BEValue *pointer)
|
||||
@@ -5145,9 +5145,7 @@ void llvm_emit_slice_pointer(GenContext *c, BEValue *slice, BEValue *pointer)
|
||||
llvm_value_set(slice, LLVMGetInitializer(slice->value), slice->type);
|
||||
goto NEXT;
|
||||
}
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, slice->value, llvm_get_type(c, slice->type), 0, slice->alignment, &alignment);
|
||||
llvm_value_set_address(c, pointer, ptr, ptr_type, alignment);
|
||||
llvm_emit_struct_gep_ref(c, slice, pointer, ptr_type, 0);
|
||||
return;
|
||||
}
|
||||
NEXT:;
|
||||
@@ -5160,9 +5158,7 @@ static void llvm_emit_any_pointer(GenContext *c, BEValue *value, BEValue *pointe
|
||||
llvm_value_fold_optional(c, value);
|
||||
if (value->kind == BE_ADDRESS)
|
||||
{
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, value->value, llvm_get_type(c, value->type), 0, value->alignment, &alignment);
|
||||
llvm_value_set_address(c, pointer, ptr, type_voidptr, alignment);
|
||||
llvm_emit_struct_gep_ref(c, value, pointer, type_voidptr, 0);
|
||||
return;
|
||||
}
|
||||
LLVMValueRef ptr = llvm_emit_extract_value(c, value->value, 0);
|
||||
@@ -5173,7 +5169,7 @@ void llvm_value_struct_gep(GenContext *c, BEValue *element, BEValue *struct_poin
|
||||
{
|
||||
llvm_value_fold_optional(c, struct_pointer);
|
||||
ArrayIndex actual_index = -1;
|
||||
Decl *member;
|
||||
Decl *member = NULL;
|
||||
for (ArrayIndex i = 0; i <= index; i++)
|
||||
{
|
||||
member = struct_pointer->type->decl->strukt.members[i];
|
||||
@@ -5183,15 +5179,8 @@ void llvm_value_struct_gep(GenContext *c, BEValue *element, BEValue *struct_poin
|
||||
}
|
||||
actual_index++;
|
||||
}
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ref = llvm_emit_struct_gep_raw(c,
|
||||
struct_pointer->value,
|
||||
llvm_get_type(c, struct_pointer->type),
|
||||
(unsigned)actual_index,
|
||||
struct_pointer->alignment,
|
||||
&alignment);
|
||||
llvm_value_set_address_abi_aligned(c, element, ref, member->type);
|
||||
element->alignment = alignment;
|
||||
assert(member);
|
||||
llvm_emit_struct_gep_ref(c, struct_pointer, element, member->type, actual_index);
|
||||
}
|
||||
|
||||
|
||||
@@ -5247,7 +5236,7 @@ void llvm_emit_parameter(GenContext *c, LLVMValueRef *args, unsigned *arg_count_
|
||||
args[(*arg_count_ref)++] = llvm_load_value_store(c, be_value);
|
||||
return;
|
||||
}
|
||||
args[(*arg_count_ref)++] = llvm_emit_coerce(c, coerce_type, be_value, type);
|
||||
args[(*arg_count_ref)++] = llvm_emit_coerce(c, coerce_type, be_value);
|
||||
return;
|
||||
}
|
||||
case ABI_ARG_DIRECT_COERCE_INT:
|
||||
@@ -5258,7 +5247,7 @@ void llvm_emit_parameter(GenContext *c, LLVMValueRef *args, unsigned *arg_count_
|
||||
args[(*arg_count_ref)++] = llvm_load_value_store(c, be_value);
|
||||
return;
|
||||
}
|
||||
args[(*arg_count_ref)++] = llvm_emit_coerce(c, coerce_type, be_value, type);
|
||||
args[(*arg_count_ref)++] = llvm_emit_coerce(c, coerce_type, be_value);
|
||||
return;
|
||||
}
|
||||
case ABI_ARG_DIRECT_PAIR:
|
||||
@@ -6567,7 +6556,12 @@ void llvm_emit_catch_unwrap(GenContext *c, BEValue *value, Expr *expr)
|
||||
llvm_value_set(value, addr.value, type_fault);
|
||||
}
|
||||
|
||||
|
||||
static inline LLVMValueRef llvm_load_introspect(GenContext *c, LLVMValueRef ref, AlignSize align, IntrospectIndex index, const char *name, LLVMTypeRef type)
|
||||
{
|
||||
AlignSize alignment;
|
||||
LLVMValueRef parent = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, index, align, &alignment);
|
||||
return llvm_load(c, type, parent, alignment, name);
|
||||
}
|
||||
static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
llvm_emit_exprid(c, value, expr->typeid_info_expr.parent);
|
||||
@@ -6580,8 +6574,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
TypeIdInfoKind info_kind = expr->typeid_info_expr.kind;
|
||||
if (info_kind == TYPEID_INFO_PARENTOF)
|
||||
{
|
||||
LLVMValueRef parent = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_PARENTOF, align, &alignment);
|
||||
LLVMValueRef parent_value = llvm_load(c, c->typeid_type, parent, alignment, "typeid.parent");
|
||||
LLVMValueRef parent_value = llvm_load_introspect(c, ref, align, INTROSPECT_INDEX_PARENTOF, "typeid.parent", c->typeid_type);
|
||||
LLVMValueRef is_zero = LLVMBuildICmp(c->builder, LLVMIntEQ, parent_value, LLVMConstNull(c->typeid_type), "");
|
||||
parent_value = LLVMBuildSelect(c->builder, is_zero, llvm_get_typeid(c, type_void), parent_value, "");
|
||||
llvm_value_set(value, parent_value, expr->type);
|
||||
@@ -6590,8 +6583,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
bool safe_mode = safe_mode_enabled();
|
||||
if (safe_mode || info_kind == TYPEID_INFO_KIND)
|
||||
{
|
||||
kind = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_KIND, align, &alignment);
|
||||
kind = llvm_load(c, c->byte_type, kind, alignment, "typeid.kind");
|
||||
kind = llvm_load_introspect(c, ref, align, INTROSPECT_INDEX_KIND, "typeid.kind", c->byte_type);
|
||||
}
|
||||
switch (info_kind)
|
||||
{
|
||||
@@ -6628,8 +6620,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
EMIT_EXPR_LOC(c, expr);
|
||||
}
|
||||
{
|
||||
LLVMValueRef val = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_INNER, align, &alignment);
|
||||
val = llvm_load(c, c->typeid_type, val, alignment, "typeid.inner");
|
||||
LLVMValueRef val = llvm_load_introspect(c, ref, align, INTROSPECT_INDEX_INNER, "typeid.inner", c->typeid_type);
|
||||
llvm_value_set(value, val, expr->type);
|
||||
return;
|
||||
}
|
||||
@@ -6657,8 +6648,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
EMIT_EXPR_LOC(c, expr);
|
||||
}
|
||||
{
|
||||
LLVMValueRef len = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_LEN, align, &alignment);
|
||||
len = llvm_load(c, c->size_type, len, alignment, "namelen");
|
||||
LLVMValueRef len = llvm_load_introspect(c, ref, align, INTROSPECT_INDEX_LEN, "namelen", c->size_type);
|
||||
LLVMValueRef val = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_ADDITIONAL, align, &alignment);
|
||||
Type *slice = type_get_slice(type_chars);
|
||||
llvm_value_set(value, llvm_emit_aggregate_two(c, slice, val, len), slice);
|
||||
@@ -6690,15 +6680,13 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
EMIT_EXPR_LOC(c, expr);
|
||||
}
|
||||
{
|
||||
LLVMValueRef val = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_LEN, align, &alignment);
|
||||
val = llvm_load(c, c->size_type, val, alignment, "typeid.len");
|
||||
LLVMValueRef val = llvm_load_introspect(c, ref, align, INTROSPECT_INDEX_LEN, "typeid.len", c->size_type);
|
||||
llvm_value_set(value, val, expr->type);
|
||||
return;
|
||||
}
|
||||
case TYPEID_INFO_SIZEOF:
|
||||
{
|
||||
LLVMValueRef val = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_SIZEOF, align, &alignment);
|
||||
val = llvm_load(c, c->size_type, val, alignment, "typeid.size");
|
||||
LLVMValueRef val = llvm_load_introspect(c, ref, align, INTROSPECT_INDEX_SIZEOF, "typeid.size", c->size_type);
|
||||
llvm_value_set(value, val, expr->type);
|
||||
return;
|
||||
}
|
||||
@@ -6770,14 +6758,7 @@ static inline void llvm_emit_type_from_any(GenContext *c, BEValue *be_value)
|
||||
{
|
||||
if (llvm_value_is_addr(be_value))
|
||||
{
|
||||
AlignSize alignment = 0;
|
||||
LLVMValueRef pointer_addr = llvm_emit_struct_gep_raw(c,
|
||||
be_value->value,
|
||||
llvm_get_type(c, type_any),
|
||||
1,
|
||||
be_value->alignment,
|
||||
&alignment);
|
||||
llvm_value_set_address(c, be_value, pointer_addr, type_typeid, alignment);
|
||||
llvm_emit_struct_gep_ref(c, be_value, be_value, type_typeid, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7025,9 +7006,7 @@ static void llvm_emit_ptr_access(GenContext *c, BEValue *value, Expr *expr)
|
||||
llvm_value_fold_optional(c, value);
|
||||
if (value->kind == BE_ADDRESS)
|
||||
{
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, value->value, llvm_get_type(c, value->type), 0, value->alignment, &alignment);
|
||||
llvm_value_set_address(c, value, ptr, expr->type, alignment);
|
||||
llvm_emit_struct_gep_ref(c, value, value, expr->type, 0);
|
||||
return;
|
||||
}
|
||||
LLVMValueRef ptr = llvm_emit_extract_value(c, value->value, 0);
|
||||
|
||||
@@ -365,21 +365,21 @@ DIRECT_RETURN:
|
||||
{
|
||||
LLVMTypeRef coerce_type = llvm_get_coerce_type(c, info);
|
||||
if (coerce_type == llvm_get_type(c, call_return_type)) goto DIRECT_RETURN;
|
||||
llvm_emit_return_value(c, llvm_emit_coerce(c, coerce_type, return_value, call_return_type));
|
||||
llvm_emit_return_value(c, llvm_emit_coerce(c, coerce_type, return_value));
|
||||
return;
|
||||
}
|
||||
case ABI_ARG_DIRECT_COERCE_INT:
|
||||
{
|
||||
LLVMTypeRef coerce_type = LLVMIntTypeInContext(c->context, type_size(call_return_type) * 8);
|
||||
if (coerce_type == llvm_get_type(c, call_return_type)) goto DIRECT_RETURN;
|
||||
llvm_emit_return_value(c, llvm_emit_coerce(c, coerce_type, return_value, call_return_type));
|
||||
llvm_emit_return_value(c, llvm_emit_coerce(c, coerce_type, return_value));
|
||||
return;
|
||||
}
|
||||
case ABI_ARG_DIRECT_COERCE:
|
||||
{
|
||||
LLVMTypeRef coerce_type = llvm_abi_type(c, info->direct_coerce_type);
|
||||
if (coerce_type == llvm_get_type(c, call_return_type)) goto DIRECT_RETURN;
|
||||
llvm_emit_return_value(c, llvm_emit_coerce(c, coerce_type, return_value, call_return_type));
|
||||
llvm_emit_return_value(c, llvm_emit_coerce(c, coerce_type, return_value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ typedef struct
|
||||
{
|
||||
BackendValueKind kind : 5;
|
||||
AlignSize alignment;
|
||||
Type *type; // Should never be a distinct or canonical type.
|
||||
LoweredType *type; // Should never be a distinct or canonical type.
|
||||
LLVMValueRef value;
|
||||
LLVMValueRef optional;
|
||||
} BEValue;
|
||||
@@ -486,6 +486,7 @@ LLVMValueRef llvm_emit_pointer_inbounds_gep_raw(GenContext *c, LLVMTypeRef point
|
||||
LLVMTypeRef llvm_coerce_expand_hi_offset(GenContext *c, LLVMValueRef *addr, ABIArgInfo *info, AlignSize *align);
|
||||
void llvm_emit_ptr_from_array(GenContext *c, BEValue *value);
|
||||
void llvm_emit_struct_member_ref(GenContext *c, BEValue *struct_ref, BEValue *member_ref, unsigned member_id);
|
||||
void llvm_emit_struct_gep_ref(GenContext *c, BEValue *ref, BEValue *member_ref, Type *element_type, unsigned member_id);
|
||||
INLINE LLVMValueRef llvm_emit_extract_value(GenContext *c, LLVMValueRef agg, unsigned index);
|
||||
|
||||
// -- Int operations ---
|
||||
@@ -510,7 +511,7 @@ LLVMTypeRef llvm_get_coerce_type(GenContext *c, ABIArgInfo *arg_info);
|
||||
LLVMValueRef llvm_get_next_param(GenContext *c, unsigned *index);
|
||||
void llvm_emit_convert_value_from_coerced(GenContext *c, BEValue *result, LLVMTypeRef coerced, LLVMValueRef value, Type *original_type);
|
||||
void llvm_emit_coerce_store(GenContext *c, LLVMValueRef addr, AlignSize alignment, LLVMTypeRef coerced, LLVMValueRef value, LLVMTypeRef target_type);
|
||||
LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value, Type *original_type);
|
||||
LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value);
|
||||
|
||||
static inline LLVMCallConv llvm_call_convention_from_call(CallABI abi);
|
||||
void llvm_emit_raw_call(GenContext *c, BEValue *result_value, FunctionPrototype *prototype, LLVMTypeRef func_type, LLVMValueRef func, LLVMValueRef *args, unsigned arg_count, int inline_flag, LLVMValueRef error_var, bool sret_return, BEValue *synthetic_return_param, bool no_return);
|
||||
|
||||
@@ -124,8 +124,7 @@ INLINE LLVMValueRef llvm_store_to_ptr_raw(GenContext *c, LLVMValueRef pointer, L
|
||||
INLINE void llvm_value_bitcast(GenContext *c UNUSED, BEValue *value, Type *type)
|
||||
{
|
||||
ASSERT(llvm_value_is_addr(value));
|
||||
type = type_lowering(type);
|
||||
value->type = type;
|
||||
value->type = type_lowering(type);
|
||||
}
|
||||
|
||||
INLINE LLVMValueRef llvm_emit_shl(GenContext *c, LLVMValueRef value, LLVMValueRef shift)
|
||||
|
||||
@@ -302,7 +302,7 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type)
|
||||
ASSERT(LLVMGetTypeContext(any_type->backend_type) == c->context && "Should have been purged");
|
||||
return any_type->backend_type;
|
||||
}
|
||||
Type *type = type_lowering(any_type);
|
||||
LoweredType *type = type_lowering(any_type);
|
||||
if (type != any_type)
|
||||
{
|
||||
return any_type->backend_type = llvm_get_type(c, type);
|
||||
@@ -436,7 +436,7 @@ static inline LLVMValueRef llvm_generate_temp_introspection_global(GenContext *c
|
||||
}
|
||||
|
||||
static inline LLVMValueRef llvm_generate_introspection_global(GenContext *c, LLVMValueRef original_global, Type *type, IntrospectType introspect_type,
|
||||
Type *inner, size_t len, LLVMValueRef additional, bool is_external)
|
||||
Type *inner, size_t len, LLVMValueRef additional, bool is_external)
|
||||
{
|
||||
// Push the builder
|
||||
void *builder = c->builder;
|
||||
|
||||
@@ -57,7 +57,7 @@ void llvm_value_set_address(GenContext *c, BEValue *value, LLVMValueRef llvm_val
|
||||
|
||||
void llvm_value_set_address_abi_aligned(GenContext *c, BEValue *value, LLVMValueRef llvm_value, Type *type)
|
||||
{
|
||||
llvm_value_set_address(c, value, llvm_value, type_lowering(type), type_abi_alignment(type));
|
||||
llvm_value_set_address(c, value, llvm_value, type, type_abi_alignment(type));
|
||||
}
|
||||
|
||||
void llvm_value_addr(GenContext *c, BEValue *value)
|
||||
|
||||
@@ -3896,7 +3896,7 @@ static inline bool sema_expr_resolve_subscript_index(SemaContext *context, Expr
|
||||
ArrayIndex size;
|
||||
bool check_len = !context->call_env.in_no_eval || current_type == type_untypedlist;
|
||||
Expr *len_expr = current_expr->expr_kind == EXPR_CT_IDENT ? current_expr->ct_ident_expr.decl->var.init_expr : current_expr;
|
||||
if (sema_cast_const(index)&& expr_is_const_int(index) && (size = sema_len_from_expr(len_expr)) >= 0)
|
||||
if (sema_cast_const(index) && expr_is_const_int(index) && (size = sema_len_from_expr(len_expr)) >= 0)
|
||||
{
|
||||
// 4c. And that it's in range.
|
||||
if (int_is_neg(index->const_expr.ixx))
|
||||
|
||||
@@ -1173,14 +1173,14 @@ Type *type_get_indexed_type(Type *type)
|
||||
switch (type->type_kind)
|
||||
{
|
||||
case TYPE_POINTER:
|
||||
return type->pointer->canonical;
|
||||
return type->pointer;
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_SLICE:
|
||||
case TYPE_INFERRED_ARRAY:
|
||||
case TYPE_INFERRED_VECTOR:
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
case TYPE_VECTOR:
|
||||
return type->array.base->canonical;
|
||||
return type->array.base;
|
||||
case TYPE_TYPEDEF:
|
||||
type = type->decl->distinct->type;
|
||||
goto RETRY;
|
||||
|
||||
7
test/test_suite/define/alias_through_index.c3
Normal file
7
test/test_suite/define/alias_through_index.c3
Normal file
@@ -0,0 +1,7 @@
|
||||
alias MyChar = char;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
MyChar[<2>] my = { '1', '2' };
|
||||
my[0].ok(); // #error: There is no member or method 'ok' on 'MyChar' (char)
|
||||
}
|
||||
Reference in New Issue
Block a user