mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Simple globals now work correctly, but structs don't.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user