mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fixes: Extname works on global variables. Bug with boolean in ternary in some cases. Global declarations would not parse attributes.
This commit is contained in:
@@ -361,7 +361,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
|
||||
|
||||
// TODO fix name
|
||||
LLVMValueRef old = decl->backend_ref;
|
||||
decl->backend_ref = LLVMAddGlobal(c->module, LLVMTypeOf(init_value), decl->external_name);
|
||||
decl->backend_ref = LLVMAddGlobal(c->module, LLVMTypeOf(init_value), decl->extname ?: decl->external_name);
|
||||
llvm_set_alignment(decl->backend_ref, alignment);
|
||||
|
||||
LLVMValueRef failable_ref = decl->var.failable_ref;
|
||||
@@ -833,7 +833,15 @@ void llvm_value_addr(GenContext *c, BEValue *value)
|
||||
|
||||
void llvm_value_rvalue(GenContext *c, BEValue *value)
|
||||
{
|
||||
if (value->kind != BE_ADDRESS && value->kind != BE_ADDRESS_FAILABLE) return;
|
||||
if (value->kind != BE_ADDRESS && value->kind != BE_ADDRESS_FAILABLE)
|
||||
{
|
||||
if (value->type->type_kind == TYPE_BOOL && value->kind != BE_BOOLEAN)
|
||||
{
|
||||
value->value = LLVMBuildTrunc(c->builder, value->value, c->bool_type, "");
|
||||
value->kind = BE_BOOLEAN;
|
||||
}
|
||||
return;
|
||||
}
|
||||
llvm_value_fold_failable(c, value);
|
||||
value->value = llvm_emit_load_aligned(c,
|
||||
llvm_get_type(c, value->type),
|
||||
|
||||
@@ -2765,7 +2765,7 @@ void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
// 12. Basically void returns or empty structs.
|
||||
// Here we know we don't have a failable or any return value that can be used.
|
||||
assert(!signature->failable && "Failable should have produced a return value.");
|
||||
*be_value = (BEValue) {};
|
||||
*be_value = (BEValue) { .type = type_void, .kind = BE_VALUE };
|
||||
return;
|
||||
case ABI_ARG_INDIRECT:
|
||||
|
||||
@@ -2910,7 +2910,7 @@ void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
// 17g. If void, be_value contents should be skipped.
|
||||
if (!signature->ret_abi_info)
|
||||
{
|
||||
*be_value = (BEValue) {};
|
||||
*be_value = (BEValue) { .type = type_void, .kind = BE_VALUE };
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -837,37 +837,6 @@ static inline bool is_function_start(Context *context)
|
||||
return tok == TOKEN_LPAREN;
|
||||
}
|
||||
|
||||
/**
|
||||
* global_declaration
|
||||
* : failable_type IDENT ';'
|
||||
* | failable_type IDENT '=' expression ';'
|
||||
* | failable_type func_definition
|
||||
* ;
|
||||
*
|
||||
* @param visibility
|
||||
* @return true if parsing succeeded
|
||||
*/
|
||||
static inline Decl *parse_global_declaration(Context *context, Visibility visibility)
|
||||
{
|
||||
TypeInfo *type = TRY_TYPE_OR(parse_type(context), poisoned_decl);
|
||||
|
||||
Decl *decl = decl_new_var(context->tok.id, type, VARDECL_GLOBAL, visibility);
|
||||
|
||||
|
||||
if (TOKEN_IS(TOKEN_CONST_IDENT))
|
||||
{
|
||||
SEMA_TOKEN_ERROR(context->tok, "This looks like a constant variable, did you forget 'const'?");
|
||||
return poisoned_decl;
|
||||
}
|
||||
if (!consume_ident(context, "global variable")) return poisoned_decl;
|
||||
|
||||
if (try_consume(context, TOKEN_EQ))
|
||||
{
|
||||
decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl);
|
||||
}
|
||||
TRY_CONSUME_EOS_OR(poisoned_decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
static inline Decl *parse_incremental_array(Context *context)
|
||||
{
|
||||
@@ -1028,6 +997,46 @@ static inline bool parse_attributes(Context *context, Decl *parent_decl)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* global_declaration
|
||||
* : failable_type IDENT ';'
|
||||
* | failable_type IDENT '=' expression ';'
|
||||
* | failable_type func_definition
|
||||
* ;
|
||||
*
|
||||
* @param visibility
|
||||
* @return true if parsing succeeded
|
||||
*/
|
||||
static inline Decl *parse_global_declaration(Context *context, Visibility visibility)
|
||||
{
|
||||
TypeInfo *type = TRY_TYPE_OR(parse_type(context), poisoned_decl);
|
||||
|
||||
Decl *decl = decl_new_var(context->tok.id, type, VARDECL_GLOBAL, visibility);
|
||||
|
||||
if (TOKEN_IS(TOKEN_CONST_IDENT))
|
||||
{
|
||||
SEMA_TOKEN_ERROR(context->tok, "This looks like a constant variable, did you forget 'const'?");
|
||||
return poisoned_decl;
|
||||
}
|
||||
|
||||
if (!try_consume(context, TOKEN_IDENT))
|
||||
{
|
||||
if (token_is_some_ident(context->tok.type))
|
||||
{
|
||||
SEMA_TOKEN_ERROR(context->tok, "I expected a variable name here, but global variables need to start with lower case.");
|
||||
return poisoned_decl;
|
||||
}
|
||||
CONSUME_OR(TOKEN_IDENT, poisoned_decl);
|
||||
}
|
||||
|
||||
if (!parse_attributes(context, decl)) return poisoned_decl;
|
||||
if (try_consume(context, TOKEN_EQ))
|
||||
{
|
||||
decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl);
|
||||
}
|
||||
TRY_CONSUME_EOS_OR(poisoned_decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
7
test/test_suite/globals/global_extname.c3t
Normal file
7
test/test_suite/globals/global_extname.c3t
Normal file
@@ -0,0 +1,7 @@
|
||||
module foo;
|
||||
|
||||
int baz @extname("foobar") = 123;
|
||||
|
||||
// #expect: foo.ll
|
||||
|
||||
@foobar = global i32 123, align 4
|
||||
Reference in New Issue
Block a user