Simple globals now work correctly, but structs don't.

This commit is contained in:
Christoffer Lerno
2020-05-05 16:57:11 +02:00
parent 93bd0fb337
commit f62a094f75
8 changed files with 51 additions and 43 deletions

View File

@@ -18,6 +18,7 @@ Things missing:
- Vararray initializers
- Incremental array initializers
- Slice initializers
- Constant initializers for globals
* Asserts
- assert, $assert
@@ -60,13 +61,11 @@ Things missing:
* Functions
- C ABI
- Safe varargs
- Malloc/free
* Pre-post conditions
- Breakdown here
* Error handling
- Try goto/return/break/continue/throw
* Enum
- Values: min, max, array
- Functions: fomOrdinal, ordinal, fromName, name, fromFullName, fullName, fromQualifiedName, qualifiedName, <value>(), fromValue()

View File

@@ -594,9 +594,12 @@ func void testDefault(int x = 2, int y = 100, int z = -100)
printf("x = %d, y = %d, z = %d\n", x, y, z);
}
int foofei = 3;
func int testReturnDefer()
{
int i = 0;
foofei++;
i++;
defer ++i;
return i;
@@ -651,6 +654,7 @@ func int testThrow6(int x) throws Err, Err2
func int testThrow(int x) throws Err
{
throwsDone.times++;
if (x < 0) throw Err.TEST_ERR1;
return x * x;
}
@@ -704,16 +708,30 @@ func void throwAOrB(int i) throws Err, Err2
printf("None\n");
}
struct ThrowsDone
{
long x;
long y;
long z;
int times;
}
ThrowsDone throwsDone;
func void testErrors()
{
printf("Throws: %d\n", throwsDone.times);
int x = try testThrow(20) else 1;
printf("Value was %d, expected 400.\n", x);
printf("Throws: %d\n", throwsDone.times);
x = try testThrow(-1) else 20;
printf("Value was %d, expected 20.\n", x);
printf("Throws: %d\n", throwsDone.times);
printf("Begin\n");
int y = try testThrow(-1);
@@ -758,6 +776,7 @@ func void testErrors()
{
printf("Wut\n");
}
printf("Throws: %d\n", throwsDone.times);
printf("End of errors\n");
}

View File

@@ -315,7 +315,7 @@ void parse_arguments(int argc, const char *argv[])
build_options.emit_bitcode = true;
build_options.optimization_level = OPTIMIZATION_NOT_SET;
build_options.size_optimization_level = SIZE_OPTIMIZATION_NOT_SET;
build_options.debug_info = DEBUG_INFO_NONE;
build_options.debug_info = DEBUG_INFO_FULL;
build_options.debug_mode = false;
build_options.command = COMMAND_MISSING;
build_options.symtab_size = DEFAULT_SYMTAB_SIZE;

View File

@@ -60,40 +60,22 @@ LLVMValueRef gencontext_emit_memclear(GenContext *context, LLVMValueRef ref, Typ
static LLVMValueRef gencontext_emit_null_constant(GenContext *context, Type *type)
{
TODO
}
static LLVMValueRef gencontext_emit_initializer(GenContext *context, Expr *expr)
{
TODO
}
static void gencontext_emit_global_variable_definition(GenContext *context, Decl *decl, bool is_tentative)
static void gencontext_emit_global_variable_definition(GenContext *context, Decl *decl)
{
assert(decl->var.kind == VARDECL_GLOBAL);
LLVMValueRef init = NULL;
if (!decl->var.init_expr)
{
// Tentative definition, initialized to zero, but only
// emitted at the end of the translation unit.
init = gencontext_emit_null_constant(context, decl->type);
}
else
{
init = gencontext_emit_initializer(context, decl->var.init_expr);
}
assert(!init);
// TODO fix name
decl->var.backend_ref = LLVMAddGlobal(context->module, llvm_type(decl->type), decl->name);
if (decl->var.init_expr)
{
LLVMSetInitializer(decl->var.backend_ref, gencontext_emit_expr(context, decl->var.init_expr));
}
else
{
LLVMSetInitializer(decl->var.backend_ref, LLVMConstInt(llvm_type(type_bool), 0, false));
}
// If read only: LLVMSetGlobalConstant(decl->var.backend_ref, 1);
switch (decl->visibility)
@@ -122,7 +104,7 @@ static void gencontext_emit_global_variable_definition(GenContext *context, Decl
2,
context->debug.file,
12 /* lineno */,
decl->type->backend_debug_type,
llvm_debug_type(decl->type),
decl->visibility ==
VISIBLE_LOCAL, /* expr */
NULL, /** declaration **/
@@ -385,6 +367,10 @@ void llvm_codegen(Context *context)
{
gencontext_emit_error_decl(&gen_context, context->error_types[i]);
}
VECEACH(context->vars, i)
{
gencontext_emit_global_variable_definition(&gen_context, context->vars[i]);
}
VECEACH(context->functions, i)
{
Decl *decl = context->functions[i];

View File

@@ -132,19 +132,21 @@ LLVMMetadataRef gencontext_get_debug_type(GenContext *context, Type *type)
case TYPE_POINTER:
return type->backend_debug_type = LLVMDIBuilderCreatePointerType(context->debug.builder, type->pointer->backend_debug_type, type_size(type->canonical->pointer), 0, 0, type->name, strlen(type->name));
case TYPE_ENUM:
break;
TODO
case TYPE_ERROR:
break;
TODO
case TYPE_FUNC:
break;
// TODO
return NULL;
case TYPE_STRUCT:
break;
// LLVMDIBuilderCreateStructType(context->debug.builder, NULL, type->decl->name, strlen(type->decl->name), type->decl->module->)
TODO
case TYPE_UNION:
break;
TODO
case TYPE_TYPEDEF:
break;
TODO
case TYPE_STRING:
break;
TODO
case TYPE_ARRAY:
{
LLVMMetadataRef *ranges = NULL;
@@ -162,11 +164,11 @@ LLVMMetadataRef gencontext_get_debug_type(GenContext *context, Type *type)
ranges, vec_size(ranges));
}
case TYPE_VARARRAY:
break;
TODO
case TYPE_SUBARRAY:
break;
TODO
case TYPE_ERROR_UNION:
TODO
}
TODO
UNREACHABLE
}

View File

@@ -220,7 +220,7 @@ static inline LLVMCallConv llvm_call_convention_from_call(CallABI abi)
}
#define llvm_type(type) gencontext_get_llvm_type(context, type)
#define DEBUG_TYPE(type) gencontext_get_debug_type(context, type)
#define llvm_debug_type(type) gencontext_get_debug_type(context, type)
static inline LLVMValueRef gencontext_emit_const_int(GenContext *context, Type *type, uint64_t val)
{

View File

@@ -231,6 +231,7 @@ LLVMTypeRef llvm_get_type(LLVMContextRef context, Type *type)
LLVMTypeRef gencontext_get_llvm_type(GenContext *context, Type *type)
{
// gencontext_get_debug_type(context, type);
return llvm_get_type(context->context, type);
}

View File

@@ -488,6 +488,7 @@ static inline bool sema_analyse_macro(Context *context, Decl *decl)
static inline bool sema_analyse_global(Context *context, Decl *decl)
{
if (!sema_resolve_type_info(context, decl->var.type_info)) return false;
decl->type = decl->var.type_info->type;
if (decl->var.init_expr)
{
if (!sema_analyse_expr_of_required_type(context, decl->type, decl->var.init_expr)) return false;