X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ast.c;h=1e2836f8e2c39181b949d733e85503606b7e5703;hb=f6792c3a05cb1ac31be5a2eb717878b40c78ecc4;hp=4eb250fad19c360756aae26a362d5cc063bdbe3f;hpb=72106b0982d6948ff53c94df1cc3f8e9902f6ddf;p=xonotic%2Fgmqcc.git diff --git a/ast.c b/ast.c index 4eb250f..1e2836f 100644 --- a/ast.c +++ b/ast.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2012, 2013 * Wolfgang Bumiller - * Dale Weiler + * Dale Weiler * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -42,7 +42,7 @@ static GMQCC_NORETURN void _ast_node_destroy(ast_node *self) { (void)self; con_err("ast node missing destroy()\n"); - abort(); + exit(EXIT_FAILURE); } /* Initialize main ast node aprts */ @@ -87,6 +87,8 @@ static void ast_expression_delete(ast_expression *self) ast_delete(self->expression.params[i]); } vec_free(self->expression.params); + if (self->expression.varparam) + ast_delete(self->expression.varparam); } static void ast_expression_delete_full(ast_expression *self) @@ -218,7 +220,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi if (!e) { if (pos + 6 >= bufsize) goto full; - strcpy(buf + pos, "(null)"); + util_strncpy(buf + pos, "(null)", 6); return pos + 6; } @@ -227,7 +229,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi switch (e->expression.vtype) { case TYPE_VARIANT: - strcpy(buf + pos, "(variant)"); + util_strncpy(buf + pos, "(variant)", 9); return pos + 9; case TYPE_FIELD: @@ -273,7 +275,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi if (pos + 1 >= bufsize) goto full; buf[pos++] = '['; - pos += snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->expression.count); + pos += util_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->expression.count); if (pos + 1 >= bufsize) goto full; buf[pos++] = ']'; @@ -284,7 +286,7 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi typelen = strlen(typestr); if (pos + typelen >= bufsize) goto full; - strcpy(buf + pos, typestr); + util_strncpy(buf + pos, typestr, typelen); return pos + typelen; } @@ -314,8 +316,10 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->isfield = false; self->cvq = CV_NONE; self->hasvalue = false; - self->uses = 0; + self->isimm = false; + self->uses = 0; memset(&self->constval, 0, sizeof(self->constval)); + self->initlist = NULL; self->ir_v = NULL; self->ir_values = NULL; @@ -359,6 +363,20 @@ void ast_value_delete(ast_value* self) if (self->desc) mem_d(self->desc); + if (self->initlist) { + if (self->expression.next->expression.vtype == TYPE_STRING) { + /* strings are allocated, free them */ + size_t i, len = vec_size(self->initlist); + /* in theory, len should be expression.count + * but let's not take any chances */ + for (i = 0; i < len; ++i) { + if (self->initlist[i].vstring) + mem_d(self->initlist[i].vstring); + } + } + vec_free(self->initlist); + } + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -406,13 +424,17 @@ ast_binary* ast_binary_new(lex_ctx ctx, int op, else self->expression.vtype = left->expression.vtype; + /* references all */ + self->refs = AST_REF_ALL; + return self; } void ast_binary_delete(ast_binary *self) { - ast_unref(self->left); - ast_unref(self->right); + if (self->refs & AST_REF_LEFT) ast_unref(self->left); + if (self->refs & AST_REF_RIGHT) ast_unref(self->right); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -580,6 +602,7 @@ void ast_member_delete(ast_member *self) * purpose that is not garbage-collected. */ ast_expression_delete((ast_expression*)self); + mem_d(self->name); mem_d(self); } @@ -1212,12 +1235,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); - strcpy(name, self->name); + util_strncpy(name, self->name, namelen); array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count); array->ir_values[0] = v; for (ai = 1; ai < array->expression.count; ++ai) { - snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); + util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); array->ir_values[ai] = ir_builder_create_field(ir, name, vtype); if (!array->ir_values[ai]) { mem_d(name); @@ -1270,12 +1293,12 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); - strcpy(name, self->name); + util_strncpy(name, self->name, namelen); self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count); self->ir_values[0] = v; for (ai = 1; ai < self->expression.count; ++ai) { - snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); + util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); self->ir_values[ai] = ir_builder_create_global(ir, name, vtype); if (!self->ir_values[ai]) { mem_d(name); @@ -1403,7 +1426,7 @@ bool ast_local_codegen(ast_value *self, ir_function *func, bool param) v = ir_function_create_local(func, self->name, vtype, param); if (!v) { - compile_error(ast_ctx(self), "ir_function_create_local failed"); + compile_error(ast_ctx(self), "internal error: ir_function_create_local failed"); return false; } v->context = ast_ctx(self); @@ -1412,20 +1435,21 @@ bool ast_local_codegen(ast_value *self, ir_function *func, bool param) namelen = strlen(self->name); name = (char*)mem_a(namelen + 16); - strcpy(name, self->name); + util_strncpy(name, self->name, namelen); self->ir_values[0] = v; for (ai = 1; ai < self->expression.count; ++ai) { - snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); + util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai); self->ir_values[ai] = ir_function_create_local(func, name, vtype, param); if (!self->ir_values[ai]) { - compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", name); + compile_error(ast_ctx(self), "internal_error: ir_builder_create_global failed on `%s`", name); return false; } self->ir_values[ai]->context = ast_ctx(self); self->ir_values[ai]->unique_life = true; self->ir_values[ai]->locked = true; } + mem_d(name); } else { @@ -1534,7 +1558,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) irf = self->ir_func; if (!irf) { - compile_error(ast_ctx(self), "ast_function's related ast_value was not generated yet"); + compile_error(ast_ctx(self), "internal error: ast_function's related ast_value was not generated yet"); return false; } @@ -2123,7 +2147,7 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i } else { *out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"), ent, field, self->expression.vtype); - /* Done AFTER error checking: + /* Done AFTER error checking: codegen_output_type(self, *out); */ } @@ -2183,9 +2207,11 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva if (!lvalue && self->expression.outr) { *out = self->expression.outr; + return true; } if (lvalue && self->expression.outl) { *out = self->expression.outl; + return true; } if (!ast_istype(self->array, ast_value)) {