mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-23 12:22:26 +00:00
temp committing major c++ification
This commit is contained in:
parent
794396df79
commit
f09c6a5d63
11 changed files with 592 additions and 776 deletions
47
ast.cpp
47
ast.cpp
|
@ -151,7 +151,7 @@ void ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
|
|||
}
|
||||
}
|
||||
|
||||
static ast_expression* ast_shallow_type(lex_ctx_t ctx, int vtype)
|
||||
static ast_expression* ast_shallow_type(lex_ctx_t ctx, qc_type vtype)
|
||||
{
|
||||
ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
|
||||
ast_expression_init(self, nullptr);
|
||||
|
@ -318,7 +318,7 @@ void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize)
|
|||
}
|
||||
|
||||
static bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out);
|
||||
ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int t)
|
||||
ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type t)
|
||||
{
|
||||
ast_instantiate(ast_value, ctx, ast_value_delete);
|
||||
ast_expression_init((ast_expression*)self,
|
||||
|
@ -1407,7 +1407,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
|
|||
size_t namelen;
|
||||
|
||||
ast_expression *elemtype;
|
||||
int vtype;
|
||||
qc_type vtype;
|
||||
ast_value *array = (ast_value*)fieldtype;
|
||||
|
||||
if (!ast_istype(fieldtype, ast_value)) {
|
||||
|
@ -1480,7 +1480,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
|
|||
size_t namelen;
|
||||
|
||||
ast_expression *elemtype = self->next;
|
||||
int vtype = elemtype->vtype;
|
||||
qc_type vtype = elemtype->vtype;
|
||||
|
||||
if (self->flags & AST_FLAG_ARRAY_INIT && !self->count) {
|
||||
compile_error(ast_ctx(self), "array `%s' has no size", self->name);
|
||||
|
@ -1595,7 +1595,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
|
|||
return true;
|
||||
|
||||
error: /* clean up */
|
||||
if(v) ir_value_delete(v);
|
||||
if (v) delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1622,7 +1622,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
|
|||
size_t namelen;
|
||||
|
||||
ast_expression *elemtype = self->next;
|
||||
int vtype = elemtype->vtype;
|
||||
qc_type vtype = elemtype->vtype;
|
||||
|
||||
func->flags |= IR_FLAG_HAS_ARRAYS;
|
||||
|
||||
|
@ -1710,7 +1710,7 @@ static bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
|
|||
return true;
|
||||
|
||||
error: /* clean up */
|
||||
ir_value_delete(v);
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1729,7 +1729,7 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir)
|
|||
compile_error(ast_ctx(self), "internal error: not all array values have been generated for `%s`", self->name);
|
||||
return false;
|
||||
}
|
||||
if (self->ir_values[i]->life) {
|
||||
if (!self->ir_values[i]->life.empty()) {
|
||||
compile_error(ast_ctx(self), "internal error: function containing `%s` already generated", self->name);
|
||||
return false;
|
||||
}
|
||||
|
@ -1756,9 +1756,8 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < self->count; ++i) {
|
||||
vec_free(self->ir_values[i]->life);
|
||||
}
|
||||
for (i = 0; i < self->count; ++i)
|
||||
self->ir_values[i]->life.clear();
|
||||
opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
|
||||
return true;
|
||||
}
|
||||
|
@ -1867,7 +1866,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
|
|||
}
|
||||
else if (compile_warning(ast_ctx(self), WARN_MISSING_RETURN_VALUES,
|
||||
"control reaches end of non-void function (`%s`) via %s",
|
||||
self->name, self->curblock->label))
|
||||
self->name, self->curblock->label.c_str()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2069,7 +2068,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
size_t merge_id;
|
||||
|
||||
/* prepare end-block */
|
||||
merge_id = vec_size(func->ir_func->blocks);
|
||||
merge_id = func->ir_func->blocks.size();
|
||||
merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_merge"));
|
||||
|
||||
/* generate the left expression */
|
||||
|
@ -2106,8 +2105,8 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge))
|
||||
return false;
|
||||
|
||||
vec_remove(func->ir_func->blocks, merge_id, 1);
|
||||
vec_push(func->ir_func->blocks, merge);
|
||||
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + merge_id);
|
||||
func->ir_func->blocks.emplace_back(merge);
|
||||
|
||||
func->curblock = merge;
|
||||
phi = ir_block_create_phi(func->curblock, ast_ctx(self),
|
||||
|
@ -2868,7 +2867,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
bpostcond = end_bpostcond = nullptr;
|
||||
}
|
||||
|
||||
bout_id = vec_size(func->ir_func->blocks);
|
||||
bout_id = func->ir_func->blocks.size();
|
||||
bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_loop"));
|
||||
if (!bout)
|
||||
return false;
|
||||
|
@ -3012,8 +3011,8 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
}
|
||||
|
||||
/* Move 'bout' to the end */
|
||||
vec_remove(func->ir_func->blocks, bout_id, 1);
|
||||
vec_push(func->ir_func->blocks, bout);
|
||||
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
|
||||
func->ir_func->blocks.emplace_back(bout);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3096,7 +3095,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
return false;
|
||||
}
|
||||
|
||||
bout_id = vec_size(func->ir_func->blocks);
|
||||
bout_id = func->ir_func->blocks.size();
|
||||
bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_switch"));
|
||||
if (!bout)
|
||||
return false;
|
||||
|
@ -3124,7 +3123,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
return false;
|
||||
|
||||
bcase = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "case"));
|
||||
bnot_id = vec_size(func->ir_func->blocks);
|
||||
bnot_id = func->ir_func->blocks.size();
|
||||
bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case"));
|
||||
if (!bcase || !bnot)
|
||||
return false;
|
||||
|
@ -3152,8 +3151,8 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
|
||||
/* enter the else and move it down */
|
||||
func->curblock = bnot;
|
||||
vec_remove(func->ir_func->blocks, bnot_id, 1);
|
||||
vec_push(func->ir_func->blocks, bnot);
|
||||
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bnot_id);
|
||||
func->ir_func->blocks.emplace_back(bnot);
|
||||
} else {
|
||||
/* The default case */
|
||||
/* Remember where to fall through from: */
|
||||
|
@ -3210,8 +3209,8 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
func->breakblocks.pop_back();
|
||||
|
||||
/* Move 'bout' to the end, it's nicer */
|
||||
vec_remove(func->ir_func->blocks, bout_id, 1);
|
||||
vec_push(func->ir_func->blocks, bout);
|
||||
func->ir_func->blocks.erase(func->ir_func->blocks.begin() + bout_id);
|
||||
func->ir_func->blocks.emplace_back(bout);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
16
ast.h
16
ast.h
|
@ -145,7 +145,7 @@ struct ast_expression : ast_node {
|
|||
ast_expression() {}
|
||||
|
||||
ast_expression_codegen *codegen;
|
||||
int vtype;
|
||||
qc_type vtype;
|
||||
ast_expression *next;
|
||||
/* arrays get a member-count */
|
||||
size_t count;
|
||||
|
@ -173,13 +173,13 @@ struct ast_expression : ast_node {
|
|||
* is like creating a 'float foo', foo serving as the type's name.
|
||||
*/
|
||||
union basic_value_t {
|
||||
qcfloat_t vfloat;
|
||||
int vint;
|
||||
vec3_t vvec;
|
||||
const char *vstring;
|
||||
int ventity;
|
||||
qcfloat_t vfloat;
|
||||
int vint;
|
||||
vec3_t vvec;
|
||||
const char *vstring;
|
||||
int ventity;
|
||||
ast_function *vfunc;
|
||||
ast_value *vfield;
|
||||
ast_value *vfield;
|
||||
};
|
||||
|
||||
struct ast_value : ast_expression
|
||||
|
@ -216,7 +216,7 @@ struct ast_value : ast_expression
|
|||
bool intrinsic; /* true if associated with intrinsic */
|
||||
};
|
||||
|
||||
ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int qctype);
|
||||
ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type qctype);
|
||||
ast_value* ast_value_copy(const ast_value *self);
|
||||
/* This will NOT delete an underlying ast_function */
|
||||
void ast_value_delete(ast_value*);
|
||||
|
|
2
fold.cpp
2
fold.cpp
|
@ -939,7 +939,7 @@ bool fold::generate(ir_builder *ir) {
|
|||
return true;
|
||||
err:
|
||||
con_out("failed to generate global %s\n", cur->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
8
gmqcc.h
8
gmqcc.h
|
@ -1,6 +1,10 @@
|
|||
#ifndef GMQCC_HDR
|
||||
#define GMQCC_HDR
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
using std::move;
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -259,7 +263,7 @@ int util_getline(char **, size_t *, FILE *);
|
|||
/* code.c */
|
||||
|
||||
/* Note: if you change the order, fix type_sizeof in ir.c */
|
||||
enum {
|
||||
enum qc_type {
|
||||
TYPE_VOID ,
|
||||
TYPE_STRING ,
|
||||
TYPE_FLOAT ,
|
||||
|
@ -589,7 +593,7 @@ void compile_show_werrors(void);
|
|||
|
||||
/* ir.c */
|
||||
/* TODO: cleanup */
|
||||
enum store_types {
|
||||
enum store_type {
|
||||
store_global,
|
||||
store_local, /* local, assignable for now, should get promoted later */
|
||||
store_param, /* parameters, they are locals with a fixed position */
|
||||
|
|
|
@ -8,7 +8,7 @@ lex_ctx_t intrin::ctx() const {
|
|||
return parser_ctx(m_parser);
|
||||
}
|
||||
|
||||
ast_function *intrin::value(ast_value **out, const char *name, qcint_t vtype) {
|
||||
ast_function *intrin::value(ast_value **out, const char *name, qc_type vtype) {
|
||||
ast_value *value = nullptr;
|
||||
ast_function *func = nullptr;
|
||||
char buffer[1024];
|
||||
|
|
2
intrin.h
2
intrin.h
|
@ -30,7 +30,7 @@ struct intrin {
|
|||
|
||||
protected:
|
||||
lex_ctx_t ctx() const;
|
||||
ast_function *value(ast_value **out, const char *name, qcint_t vtype);
|
||||
ast_function *value(ast_value **out, const char *name, qc_type vtype);
|
||||
void reg(ast_value *const value, ast_function *const func);
|
||||
|
||||
ast_expression *nullfunc();
|
||||
|
|
168
ir.h
168
ir.h
|
@ -36,12 +36,19 @@ enum {
|
|||
};
|
||||
|
||||
struct ir_value {
|
||||
char *name;
|
||||
int vtype;
|
||||
int store;
|
||||
ir_value(std::string&& name, store_type storetype, qc_type vtype);
|
||||
~ir_value();
|
||||
|
||||
void* operator new(std::size_t); // to use mem_a
|
||||
void operator delete(void*); // to use mem_d
|
||||
|
||||
std::string name;
|
||||
|
||||
qc_type vtype;
|
||||
store_type store;
|
||||
lex_ctx_t context;
|
||||
int fieldtype; // even the IR knows the subtype of a field
|
||||
int outtype; // and the output type of a function
|
||||
qc_type fieldtype; // even the IR knows the subtype of a field
|
||||
qc_type outtype; // and the output type of a function
|
||||
int cvq; // 'const' vs 'var' qualifier
|
||||
ir_flag_t flags;
|
||||
|
||||
|
@ -51,12 +58,12 @@ struct ir_value {
|
|||
// constant values
|
||||
bool hasvalue;
|
||||
union {
|
||||
qcfloat_t vfloat;
|
||||
int vint;
|
||||
vec3_t vvec;
|
||||
int32_t ivec[3];
|
||||
char *vstring;
|
||||
ir_value *vpointer;
|
||||
qcfloat_t vfloat;
|
||||
int vint;
|
||||
vec3_t vvec;
|
||||
int32_t ivec[3];
|
||||
char *vstring;
|
||||
ir_value *vpointer;
|
||||
ir_function *vfunc;
|
||||
} constval;
|
||||
|
||||
|
@ -76,7 +83,7 @@ struct ir_value {
|
|||
bool locked; // temps living during a CALL must be locked
|
||||
bool callparam;
|
||||
|
||||
ir_life_entry_t *life; // For the temp allocator
|
||||
std::vector<ir_life_entry_t> life; // For the temp allocator
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -84,7 +91,6 @@ struct ir_value {
|
|||
* if a result of an operation: the function should store
|
||||
* it to remember to delete it / garbage collect it
|
||||
*/
|
||||
void ir_value_delete(ir_value*);
|
||||
ir_value* ir_value_vector_member(ir_value*, unsigned int member);
|
||||
bool GMQCC_WARN ir_value_set_float(ir_value*, float f);
|
||||
bool GMQCC_WARN ir_value_set_func(ir_value*, int f);
|
||||
|
@ -121,38 +127,44 @@ struct ir_instr {
|
|||
|
||||
/* block */
|
||||
struct ir_block {
|
||||
char *label;
|
||||
lex_ctx_t context;
|
||||
bool final; /* once a jump is added we're done */
|
||||
void* operator new(std::size_t);
|
||||
void operator delete(void*);
|
||||
|
||||
ir_instr **instr;
|
||||
ir_block **entries;
|
||||
ir_block **exits;
|
||||
ir_block(ir_function *owner, const std::string& name);
|
||||
~ir_block();
|
||||
|
||||
ir_function *owner;
|
||||
std::string label;
|
||||
|
||||
lex_ctx_t context;
|
||||
bool final = false; /* once a jump is added we're done */
|
||||
|
||||
ir_instr **instr = nullptr;
|
||||
ir_block **entries = nullptr;
|
||||
ir_block **exits = nullptr;
|
||||
std::vector<ir_value *> living;
|
||||
|
||||
/* For the temp-allocation */
|
||||
size_t entry_id;
|
||||
size_t eid;
|
||||
bool is_return;
|
||||
size_t entry_id = 0;
|
||||
size_t eid = 0;
|
||||
bool is_return = false;
|
||||
|
||||
ir_function *owner;
|
||||
|
||||
bool generated;
|
||||
size_t code_start;
|
||||
bool generated = false;
|
||||
size_t code_start = 0;
|
||||
};
|
||||
|
||||
ir_value* ir_block_create_binop(ir_block*, lex_ctx_t, const char *label, int op, ir_value *left, ir_value *right);
|
||||
ir_value* ir_block_create_unary(ir_block*, lex_ctx_t, const char *label, int op, ir_value *operand);
|
||||
bool GMQCC_WARN ir_block_create_store_op(ir_block*, lex_ctx_t, int op, ir_value *target, ir_value *what);
|
||||
bool GMQCC_WARN ir_block_create_storep(ir_block*, lex_ctx_t, ir_value *target, ir_value *what);
|
||||
ir_value* ir_block_create_load_from_ent(ir_block*, lex_ctx_t, const char *label, ir_value *ent, ir_value *field, int outype);
|
||||
ir_value* ir_block_create_load_from_ent(ir_block*, lex_ctx_t, const char *label, ir_value *ent, ir_value *field, qc_type outype);
|
||||
ir_value* ir_block_create_fieldaddress(ir_block*, lex_ctx_t, const char *label, ir_value *entity, ir_value *field);
|
||||
bool GMQCC_WARN ir_block_create_state_op(ir_block*, lex_ctx_t, ir_value *frame, ir_value *think);
|
||||
|
||||
/* This is to create an instruction of the form
|
||||
* <outtype>%label := opcode a, b
|
||||
*/
|
||||
ir_instr* ir_block_create_phi(ir_block*, lex_ctx_t, const char *label, int vtype);
|
||||
ir_instr* ir_block_create_phi(ir_block*, lex_ctx_t, const char *label, qc_type vtype);
|
||||
ir_value* ir_phi_value(ir_instr*);
|
||||
void ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
|
||||
ir_instr* ir_block_create_call(ir_block*, lex_ctx_t, const char *label, ir_value *func, bool noreturn);
|
||||
|
@ -175,27 +187,36 @@ bool GMQCC_WARN ir_block_create_goto(ir_block*, lex_ctx_t, ir_block *to);
|
|||
|
||||
/* function */
|
||||
struct ir_function {
|
||||
char *name;
|
||||
int outtype;
|
||||
int *params;
|
||||
ir_block **blocks;
|
||||
ir_flag_t flags;
|
||||
int builtin;
|
||||
void* operator new(std::size_t);
|
||||
void operator delete(void*);
|
||||
|
||||
ir_function(ir_builder *owner, qc_type returntype);
|
||||
~ir_function();
|
||||
|
||||
ir_builder *owner;
|
||||
|
||||
std::string name;
|
||||
qc_type outtype;
|
||||
int *params = nullptr;
|
||||
ir_flag_t flags = 0;
|
||||
int builtin = 0;
|
||||
|
||||
std::vector<std::unique_ptr<ir_block>> blocks;
|
||||
|
||||
/*
|
||||
* values generated from operations
|
||||
* which might get optimized away, so anything
|
||||
* in there needs to be deleted in the dtor.
|
||||
*/
|
||||
ir_value **values;
|
||||
ir_value **locals; /* locally defined variables */
|
||||
ir_value *value;
|
||||
std::vector<std::unique_ptr<ir_value>> values;
|
||||
std::vector<std::unique_ptr<ir_value>> locals; /* locally defined variables */
|
||||
ir_value *value = nullptr;
|
||||
|
||||
size_t allocated_locals;
|
||||
size_t globaltemps;
|
||||
size_t allocated_locals = 0;
|
||||
size_t globaltemps = 0;
|
||||
|
||||
ir_block* first;
|
||||
ir_block* last;
|
||||
ir_block* first = nullptr;
|
||||
ir_block* last = nullptr;
|
||||
|
||||
lex_ctx_t context;
|
||||
|
||||
|
@ -206,19 +227,17 @@ struct ir_function {
|
|||
*
|
||||
* remember the ID:
|
||||
*/
|
||||
qcint_t code_function_def;
|
||||
qcint_t code_function_def = -1;
|
||||
|
||||
/* for temp allocation */
|
||||
size_t run_id;
|
||||
|
||||
ir_builder *owner;
|
||||
size_t run_id = 0;
|
||||
|
||||
/* vararg support: */
|
||||
size_t max_varargs;
|
||||
size_t max_varargs = 0;
|
||||
};
|
||||
|
||||
|
||||
ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype, bool param);
|
||||
ir_value* ir_function_create_local(ir_function *self, const std::string& name, qc_type vtype, bool param);
|
||||
bool GMQCC_WARN ir_function_finalize(ir_function*);
|
||||
ir_block* ir_function_create_block(lex_ctx_t ctx, ir_function*, const char *label);
|
||||
|
||||
|
@ -227,33 +246,42 @@ ir_block* ir_function_create_block(lex_ctx_t ctx, ir_function*, const char
|
|||
#define IR_MAX_VINSTR_TEMPS 1
|
||||
|
||||
struct ir_builder {
|
||||
char *name;
|
||||
ir_function **functions;
|
||||
ir_value **globals;
|
||||
ir_value **fields;
|
||||
ir_value **const_floats; /* for reusing them in vector-splits, TODO: sort this or use a radix-tree */
|
||||
void* operator new(std::size_t);
|
||||
void operator delete(void*);
|
||||
ir_builder(const std::string& modulename);
|
||||
~ir_builder();
|
||||
|
||||
std::string name;
|
||||
std::vector<std::unique_ptr<ir_function>> functions;
|
||||
std::vector<std::unique_ptr<ir_value>> globals;
|
||||
std::vector<std::unique_ptr<ir_value>> fields;
|
||||
// for reusing them in vector-splits, TODO: sort this or use a radix-tree
|
||||
std::vector<ir_value*> const_floats;
|
||||
|
||||
ht htfunctions;
|
||||
ht htglobals;
|
||||
ht htfields;
|
||||
|
||||
ir_value **extparams;
|
||||
ir_value **extparam_protos;
|
||||
std::vector<std::unique_ptr<ir_value>> extparams;
|
||||
std::vector<std::unique_ptr<ir_value>> extparam_protos;
|
||||
|
||||
/* the highest func->allocated_locals */
|
||||
size_t max_locals;
|
||||
size_t max_globaltemps;
|
||||
uint32_t first_common_local;
|
||||
uint32_t first_common_globaltemp;
|
||||
// the highest func->allocated_locals
|
||||
size_t max_locals = 0;
|
||||
size_t max_globaltemps = 0;
|
||||
uint32_t first_common_local = 0;
|
||||
uint32_t first_common_globaltemp = 0;
|
||||
|
||||
const char **filenames;
|
||||
qcint_t *filestrings;
|
||||
/* we cache the #IMMEDIATE string here */
|
||||
qcint_t str_immediate;
|
||||
/* there should just be this one nil */
|
||||
std::vector<const char*> filenames;
|
||||
std::vector<qcint_t> filestrings;
|
||||
|
||||
// we cache the #IMMEDIATE string here
|
||||
qcint_t str_immediate = 0;
|
||||
|
||||
// there should just be this one nil
|
||||
ir_value *nil;
|
||||
ir_value *reserved_va_count;
|
||||
ir_value *coverage_func;
|
||||
ir_value *reserved_va_count = nullptr;
|
||||
ir_value *coverage_func = nullptr;
|
||||
|
||||
/* some virtual instructions require temps, and their code is isolated
|
||||
* so that we don't need to keep track of their liveness.
|
||||
*/
|
||||
|
@ -263,11 +291,9 @@ struct ir_builder {
|
|||
code_t *code;
|
||||
};
|
||||
|
||||
ir_builder* ir_builder_new(const char *modulename);
|
||||
void ir_builder_delete(ir_builder*);
|
||||
ir_function* ir_builder_create_function(ir_builder*, const char *name, int outtype);
|
||||
ir_value* ir_builder_create_global(ir_builder*, const char *name, int vtype);
|
||||
ir_value* ir_builder_create_field(ir_builder*, const char *name, int vtype);
|
||||
ir_function* ir_builder_create_function(ir_builder*, const std::string& name, qc_type outtype);
|
||||
ir_value* ir_builder_create_global(ir_builder*, const std::string& name, qc_type vtype);
|
||||
ir_value* ir_builder_create_field(ir_builder*, const std::string& name, qc_type vtype);
|
||||
ir_value* ir_builder_get_va_count(ir_builder*);
|
||||
bool ir_builder_generate(ir_builder *self, const char *filename);
|
||||
void ir_builder_dump(ir_builder*, int (*oprintf)(const char*, ...));
|
||||
|
|
|
@ -65,7 +65,7 @@ static void lex_token_new(lex_file *lex)
|
|||
if (lex->tok.value)
|
||||
vec_shrinkto(lex->tok.value, 0);
|
||||
|
||||
lex->tok.constval.t = 0;
|
||||
lex->tok.constval.t = TYPE_VOID;
|
||||
lex->tok.ctx.line = lex->sline;
|
||||
lex->tok.ctx.file = lex->name;
|
||||
lex->tok.ctx.column = lex->column;
|
||||
|
|
2
lexer.h
2
lexer.h
|
@ -9,7 +9,7 @@ struct token {
|
|||
vec3_t v;
|
||||
int i;
|
||||
qcfloat_t f;
|
||||
int t; /* type */
|
||||
qc_type t; /* type */
|
||||
} constval;
|
||||
lex_ctx_t ctx;
|
||||
};
|
||||
|
|
28
parser.cpp
28
parser.cpp
|
@ -6144,7 +6144,7 @@ static bool parser_set_coverage_func(parser_t *parser, ir_builder *ir) {
|
|||
if (!func) {
|
||||
if (OPTS_OPTION_BOOL(OPTION_COVERAGE)) {
|
||||
con_out("coverage support requested but no coverage() builtin declared\n");
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -6157,7 +6157,7 @@ static bool parser_set_coverage_func(parser_t *parser, ir_builder *ir) {
|
|||
char ty[1024];
|
||||
ast_type_to_string(expr, ty, sizeof(ty));
|
||||
con_out("invalid type for coverage(): %s\n", ty);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -6175,7 +6175,7 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
return false;
|
||||
}
|
||||
|
||||
ir = ir_builder_new("gmqcc_out");
|
||||
ir = new ir_builder("gmqcc_out");
|
||||
if (!ir) {
|
||||
con_out("failed to allocate builder\n");
|
||||
return false;
|
||||
|
@ -6190,7 +6190,7 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
field->hasvalue = false;
|
||||
if (!ast_global_codegen((ast_value*)field, ir, true)) {
|
||||
con_out("failed to generate field %s\n", field->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
if (hasvalue) {
|
||||
|
@ -6217,7 +6217,7 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
}
|
||||
if (!ast_global_codegen(asvalue, ir, false)) {
|
||||
con_out("failed to generate global %s\n", asvalue->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6230,12 +6230,12 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
f->varargs->count = parser->max_param_count - f->function_type->type_params.size();
|
||||
if (!parser_create_array_setter_impl(parser, f->varargs)) {
|
||||
con_out("failed to generate vararg setter for %s\n", f->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
if (!parser_create_array_getter_impl(parser, f->varargs)) {
|
||||
con_out("failed to generate vararg getter for %s\n", f->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -6267,7 +6267,7 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
asvalue->name);
|
||||
}
|
||||
if (!ast_generate_accessors(asvalue, ir)) {
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6278,7 +6278,7 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
if (asvalue->vtype != TYPE_ARRAY)
|
||||
continue;
|
||||
if (!ast_generate_accessors(asvalue, ir)) {
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6286,13 +6286,13 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
!ast_global_codegen(parser->reserved_version, ir, false))
|
||||
{
|
||||
con_out("failed to generate reserved::version");
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
for (auto &f : parser->functions) {
|
||||
if (!ast_function_codegen(f, ir)) {
|
||||
con_out("failed to generate function %s\n", f->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6304,7 +6304,7 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
for (auto &it : parser->functions) {
|
||||
if (!ir_function_finalize(it->ir_func)) {
|
||||
con_out("failed to finalize function %s\n", it->name);
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6322,10 +6322,10 @@ bool parser_finish(parser_t *parser, const char *output)
|
|||
|
||||
if (!ir_builder_generate(ir, output)) {
|
||||
con_out("*** failed to generate output file\n");
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ir_builder_delete(ir);
|
||||
delete ir;
|
||||
return retval;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue