mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-23 20:33:05 +00:00
Make compiler and virtual-machine compile as C++ code, also removed gmqcc_voidptr hack.
This commit is contained in:
parent
d35d953a91
commit
c3964cf29d
9 changed files with 40 additions and 65 deletions
6
ast.c
6
ast.c
|
@ -1098,9 +1098,9 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu
|
||||||
* on all the globals.
|
* on all the globals.
|
||||||
*/
|
*/
|
||||||
if (!self->ir_v) {
|
if (!self->ir_v) {
|
||||||
char typename[1024];
|
char tname[1024]; /* typename is reserved in C++ */
|
||||||
ast_type_to_string((ast_expression*)self, typename, sizeof(typename));
|
ast_type_to_string((ast_expression*)self, tname, sizeof(tname));
|
||||||
compile_error(ast_ctx(self), "ast_value used before generated %s %s", typename, self->name);
|
compile_error(ast_ctx(self), "ast_value used before generated %s %s", tname, self->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*out = self->ir_v;
|
*out = self->ir_v;
|
||||||
|
|
3
exec.c
3
exec.c
|
@ -169,8 +169,9 @@ void prog_delete(qc_program *prog)
|
||||||
|
|
||||||
char* prog_getstring(qc_program *prog, qcint str)
|
char* prog_getstring(qc_program *prog, qcint str)
|
||||||
{
|
{
|
||||||
|
/* cast for return required for C++ */
|
||||||
if (str < 0 || str >= (qcint)vec_size(prog->strings))
|
if (str < 0 || str >= (qcint)vec_size(prog->strings))
|
||||||
return "<<<invalid string>>>";
|
return (char*)"<<<invalid string>>>";
|
||||||
return prog->strings + str;
|
return prog->strings + str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
ftepp.c
11
ftepp.c
|
@ -1010,14 +1010,15 @@ static char *ftepp_include_find(ftepp_t *ftepp, const char *file)
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftepp_directive_warning(ftepp_t *ftepp) {
|
static bool ftepp_directive_warning(ftepp_t *ftepp) {
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
|
|
||||||
if (!ftepp_skipspace(ftepp))
|
if (!ftepp_skipspace(ftepp))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
/* handle the odd non string constant case so it works like C */
|
/* handle the odd non string constant case so it works like C */
|
||||||
if (ftepp->token != TOKEN_STRINGCONST) {
|
if (ftepp->token != TOKEN_STRINGCONST) {
|
||||||
|
bool store = false;
|
||||||
vec_upload(message, "#warning", 8);
|
vec_upload(message, "#warning", 8);
|
||||||
ftepp_next(ftepp);
|
ftepp_next(ftepp);
|
||||||
while (ftepp->token != TOKEN_EOL) {
|
while (ftepp->token != TOKEN_EOL) {
|
||||||
|
@ -1025,13 +1026,13 @@ static void ftepp_directive_warning(ftepp_t *ftepp) {
|
||||||
ftepp_next(ftepp);
|
ftepp_next(ftepp);
|
||||||
}
|
}
|
||||||
vec_push(message, '\0');
|
vec_push(message, '\0');
|
||||||
(void)!!ftepp_warn(ftepp, WARN_CPP, message);
|
store = ftepp_warn(ftepp, WARN_CPP, message);
|
||||||
vec_free(message);
|
vec_free(message);
|
||||||
return;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
|
unescape (ftepp_tokval(ftepp), ftepp_tokval(ftepp));
|
||||||
(void)!!ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp));
|
return ftepp_warn(ftepp, WARN_CPP, "#warning %s", ftepp_tokval(ftepp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ftepp_directive_error(ftepp_t *ftepp) {
|
static void ftepp_directive_error(ftepp_t *ftepp) {
|
||||||
|
|
36
gmqcc.h
36
gmqcc.h
|
@ -260,40 +260,12 @@ size_t util_strtononcmd (const char *, char *, size_t);
|
||||||
|
|
||||||
uint16_t util_crc16(uint16_t crc, const char *data, size_t len);
|
uint16_t util_crc16(uint16_t crc, const char *data, size_t len);
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're compiling as C++ code we need to fix some subtle issues regarding casts between mem_a/mem_d
|
|
||||||
* since C++ doesn't allow implicit conversions between void*
|
|
||||||
*/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/*
|
|
||||||
* void * will be implicitally converted to gmqcc_voidptr using gmqcc_voidptr(void*). This is what
|
|
||||||
* essentially allows us to allow implicit conversion to whatever pointer type we're trying to assign
|
|
||||||
* to because it acks as a default assignment constructor.
|
|
||||||
*/
|
|
||||||
class gmqcc_voidptr {
|
|
||||||
void *m_pointer;
|
|
||||||
public:
|
|
||||||
gmqcc_voidptr(void *pointer) :
|
|
||||||
m_pointer(pointer)
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
GMQCC_INLINE operator T *() {
|
|
||||||
return m_pointer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
# define GMQCC_IMPLICIT_POINTER(X) (gmqcc_voidptr(X))
|
|
||||||
#else
|
|
||||||
# define GMQCC_IMPLICIT_POINTER(X) (X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOTRACK
|
#ifdef NOTRACK
|
||||||
# define mem_a(x) GMQCC_IMPLICIT_POINTER(malloc (x))
|
# define mem_a(x) malloc (x)
|
||||||
# define mem_d(x) free ((void*)x)
|
# define mem_d(x) free ((void*)x)
|
||||||
# define mem_r(x, n) realloc((void*)x, n)
|
# define mem_r(x, n) realloc((void*)x, n)
|
||||||
#else
|
#else
|
||||||
# define mem_a(x) GMQCC_IMPLICIT_POINTER(util_memory_a((x), __LINE__, __FILE__))
|
# define mem_a(x) util_memory_a((x), __LINE__, __FILE__)
|
||||||
# define mem_d(x) util_memory_d((void*)(x), __LINE__, __FILE__)
|
# define mem_d(x) util_memory_d((void*)(x), __LINE__, __FILE__)
|
||||||
# define mem_r(x, n) util_memory_r((void*)(x), (n), __LINE__, __FILE__)
|
# define mem_r(x, n) util_memory_r((void*)(x), (n), __LINE__, __FILE__)
|
||||||
#endif
|
#endif
|
||||||
|
@ -371,12 +343,12 @@ typedef struct hash_table_t {
|
||||||
*/
|
*/
|
||||||
hash_table_t *util_htnew (size_t size);
|
hash_table_t *util_htnew (size_t size);
|
||||||
void util_htset (hash_table_t *ht, const char *key, void *value);
|
void util_htset (hash_table_t *ht, const char *key, void *value);
|
||||||
void *util_htget (hash_table_t *ht, const char *key);
|
|
||||||
void util_htdel (hash_table_t *ht);
|
void util_htdel (hash_table_t *ht);
|
||||||
size_t util_hthash(hash_table_t *ht, const char *key);
|
size_t util_hthash(hash_table_t *ht, const char *key);
|
||||||
void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
|
|
||||||
void util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
|
void util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
|
||||||
|
|
||||||
|
void *util_htget (hash_table_t *ht, const char *key);
|
||||||
|
void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
|
||||||
/*===================================================================*/
|
/*===================================================================*/
|
||||||
/*============================ file.c ===============================*/
|
/*============================ file.c ===============================*/
|
||||||
/*===================================================================*/
|
/*===================================================================*/
|
||||||
|
|
6
ir.c
6
ir.c
|
@ -1123,7 +1123,7 @@ static char *ir_strdup(const char *str)
|
||||||
{
|
{
|
||||||
if (str && !*str) {
|
if (str && !*str) {
|
||||||
/* actually dup empty strings */
|
/* actually dup empty strings */
|
||||||
char *out = mem_a(1);
|
char *out = (char*)mem_a(1);
|
||||||
*out = 0;
|
*out = 0;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -1543,7 +1543,7 @@ ir_instr* ir_block_create_phi(ir_block *self, lex_ctx ctx, const char *label, in
|
||||||
ir_value *out;
|
ir_value *out;
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
if (!ir_check_unreachable(self))
|
if (!ir_check_unreachable(self))
|
||||||
return false;
|
return NULL;
|
||||||
in = ir_instr_new(ctx, self, VINSTR_PHI);
|
in = ir_instr_new(ctx, self, VINSTR_PHI);
|
||||||
if (!in)
|
if (!in)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1590,7 +1590,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i
|
||||||
ir_value *out;
|
ir_value *out;
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
if (!ir_check_unreachable(self))
|
if (!ir_check_unreachable(self))
|
||||||
return false;
|
return NULL;
|
||||||
in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
|
in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
|
||||||
if (!in)
|
if (!in)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
2
main.c
2
main.c
|
@ -536,7 +536,7 @@ int main(int argc, char **argv) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
operators_free = true;
|
operators_free = true;
|
||||||
newops = mem_a(sizeof(operators[0]) * operator_count);
|
newops = (oper_info*)mem_a(sizeof(operators[0]) * operator_count);
|
||||||
memcpy(newops, operators, sizeof(operators[0]) * operator_count);
|
memcpy(newops, operators, sizeof(operators[0]) * operator_count);
|
||||||
memcpy(&newops[operator_count-2], &operators[operator_count-1], sizeof(newops[0]));
|
memcpy(&newops[operator_count-2], &operators[operator_count-1], sizeof(newops[0]));
|
||||||
memcpy(&newops[operator_count-1], &operators[operator_count-2], sizeof(newops[0]));
|
memcpy(&newops[operator_count-1], &operators[operator_count-2], sizeof(newops[0]));
|
||||||
|
|
2
opts.c
2
opts.c
|
@ -64,7 +64,7 @@ void opts_init(const char *output, int standard, size_t arraysize) {
|
||||||
opts_setdefault();
|
opts_setdefault();
|
||||||
|
|
||||||
opts.output = output;
|
opts.output = output;
|
||||||
opts.standard = standard;
|
opts.standard = (opts_std_t)standard; /* C++ ... y u no like me? */
|
||||||
opts.max_array_size = arraysize;
|
opts.max_array_size = arraysize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
parser.c
29
parser.c
|
@ -32,6 +32,7 @@
|
||||||
#define PARSER_HT_SIZE 1024
|
#define PARSER_HT_SIZE 1024
|
||||||
#define TYPEDEF_HT_SIZE 16
|
#define TYPEDEF_HT_SIZE 16
|
||||||
|
|
||||||
|
enum parser_pot { POT_PAREN, POT_TERNARY1, POT_TERNARY2 };
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lex_file *lex;
|
lex_file *lex;
|
||||||
int tok;
|
int tok;
|
||||||
|
@ -90,7 +91,7 @@ typedef struct {
|
||||||
* If we reach a 'comma' operator in a ternary without a paren,
|
* If we reach a 'comma' operator in a ternary without a paren,
|
||||||
* we shall trigger -Wternary-precedence.
|
* we shall trigger -Wternary-precedence.
|
||||||
*/
|
*/
|
||||||
enum { POT_PAREN, POT_TERNARY1, POT_TERNARY2 } *pot;
|
enum parser_pot *pot;
|
||||||
|
|
||||||
/* pragma flags */
|
/* pragma flags */
|
||||||
bool noref;
|
bool noref;
|
||||||
|
@ -234,7 +235,7 @@ static char *parser_strdup(const char *str)
|
||||||
{
|
{
|
||||||
if (str && !*str) {
|
if (str && !*str) {
|
||||||
/* actually dup empty strings */
|
/* actually dup empty strings */
|
||||||
char *out = mem_a(1);
|
char *out = (char*)mem_a(1);
|
||||||
*out = 0;
|
*out = 0;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -296,12 +297,12 @@ static ast_value* parser_const_vector_0(parser_t *parser)
|
||||||
|
|
||||||
static ast_expression* parser_find_field(parser_t *parser, const char *name)
|
static ast_expression* parser_find_field(parser_t *parser, const char *name)
|
||||||
{
|
{
|
||||||
return util_htget(parser->htfields, name);
|
return ( ast_expression*)util_htget(parser->htfields, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ast_expression* parser_find_global(parser_t *parser, const char *name)
|
static ast_expression* parser_find_global(parser_t *parser, const char *name)
|
||||||
{
|
{
|
||||||
return util_htget(parser->htglobals, name);
|
return (ast_expression*)util_htget(parser->htglobals, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ast_expression* parser_find_param(parser_t *parser, const char *name)
|
static ast_expression* parser_find_param(parser_t *parser, const char *name)
|
||||||
|
@ -328,7 +329,7 @@ static ast_expression* parser_find_local(parser_t *parser, const char *name, siz
|
||||||
*isparam = false;
|
*isparam = false;
|
||||||
for (i = vec_size(parser->variables); i > upto;) {
|
for (i = vec_size(parser->variables); i > upto;) {
|
||||||
--i;
|
--i;
|
||||||
if ( (e = util_htgeth(parser->variables[i], name, hash)) )
|
if ( (e = (ast_expression*)util_htgeth(parser->variables[i], name, hash)) )
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
*isparam = true;
|
*isparam = true;
|
||||||
|
@ -1479,7 +1480,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
|
||||||
val = parser_const_string(parser, parser_tokval(parser), true);
|
val = parser_const_string(parser, parser_tokval(parser), true);
|
||||||
wantop = true;
|
wantop = true;
|
||||||
if (!val)
|
if (!val)
|
||||||
return false;
|
return NULL;
|
||||||
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
||||||
DEBUGSHUNTDO(con_out("push string\n"));
|
DEBUGSHUNTDO(con_out("push string\n"));
|
||||||
|
|
||||||
|
@ -1556,7 +1557,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
|
||||||
wantop = true;
|
wantop = true;
|
||||||
val = parser_const_float(parser, (parser_token(parser)->constval.f));
|
val = parser_const_float(parser, (parser_token(parser)->constval.f));
|
||||||
if (!val)
|
if (!val)
|
||||||
return false;
|
return NULL;
|
||||||
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
||||||
DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
|
DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
|
||||||
}
|
}
|
||||||
|
@ -1569,7 +1570,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
|
||||||
wantop = true;
|
wantop = true;
|
||||||
val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
|
val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
|
||||||
if (!val)
|
if (!val)
|
||||||
return false;
|
return NULL;
|
||||||
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
||||||
DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
|
DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
|
||||||
}
|
}
|
||||||
|
@ -1582,7 +1583,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
|
||||||
wantop = true;
|
wantop = true;
|
||||||
val = parser_const_string(parser, parser_tokval(parser), false);
|
val = parser_const_string(parser, parser_tokval(parser), false);
|
||||||
if (!val)
|
if (!val)
|
||||||
return false;
|
return NULL;
|
||||||
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
||||||
DEBUGSHUNTDO(con_out("push string\n"));
|
DEBUGSHUNTDO(con_out("push string\n"));
|
||||||
}
|
}
|
||||||
|
@ -1595,7 +1596,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
|
||||||
wantop = true;
|
wantop = true;
|
||||||
val = parser_const_vector(parser, parser_token(parser)->constval.v);
|
val = parser_const_vector(parser, parser_token(parser)->constval.v);
|
||||||
if (!val)
|
if (!val)
|
||||||
return false;
|
return NULL;
|
||||||
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
|
||||||
DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
|
DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
|
||||||
parser_token(parser)->constval.v.x,
|
parser_token(parser)->constval.v.x,
|
||||||
|
@ -2966,7 +2967,7 @@ static bool create_vector_members(ast_value *var, ast_member **me)
|
||||||
size_t len = strlen(var->name);
|
size_t len = strlen(var->name);
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
char *name = mem_a(len+3);
|
char *name = (char*)mem_a(len+3);
|
||||||
memcpy(name, var->name, len);
|
memcpy(name, var->name, len);
|
||||||
name[len+0] = '_';
|
name[len+0] = '_';
|
||||||
name[len+1] = 'x'+i;
|
name[len+1] = 'x'+i;
|
||||||
|
@ -3703,9 +3704,9 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
vec_push(params, param);
|
vec_push(params, param);
|
||||||
if (param->expression.vtype >= TYPE_VARIANT) {
|
if (param->expression.vtype >= TYPE_VARIANT) {
|
||||||
char typename[1024];
|
char tname[1024]; /* typename is reserved in C++ */
|
||||||
ast_type_to_string((ast_expression*)param, typename, sizeof(typename));
|
ast_type_to_string((ast_expression*)param, tname, sizeof(tname));
|
||||||
parseerror(parser, "type not supported as part of a parameter list: %s", typename);
|
parseerror(parser, "type not supported as part of a parameter list: %s", tname);
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
util.c
10
util.c
|
@ -42,7 +42,7 @@ struct memblock_t {
|
||||||
static struct memblock_t *mem_start = NULL;
|
static struct memblock_t *mem_start = NULL;
|
||||||
|
|
||||||
void *util_memory_a(size_t byte, unsigned int line, const char *file) {
|
void *util_memory_a(size_t byte, unsigned int line, const char *file) {
|
||||||
struct memblock_t *info = malloc(sizeof(struct memblock_t) + byte);
|
struct memblock_t *info = (struct memblock_t*)malloc(sizeof(struct memblock_t) + byte);
|
||||||
void *data = (void*)(info+1);
|
void *data = (void*)(info+1);
|
||||||
if (!info) return NULL;
|
if (!info) return NULL;
|
||||||
info->line = line;
|
info->line = line;
|
||||||
|
@ -170,7 +170,7 @@ char *util_strdup(const char *s) {
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((len = strlen(s)) && (ptr = mem_a(len+1))) {
|
if ((len = strlen(s)) && (ptr = (char*)mem_a(len+1))) {
|
||||||
memcpy(ptr, s, len);
|
memcpy(ptr, s, len);
|
||||||
ptr[len] = '\0';
|
ptr[len] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ GMQCC_INLINE size_t util_hthash(hash_table_t *ht, const char *key) {
|
||||||
|
|
||||||
hash_node_t *_util_htnewpair(const char *key, void *value) {
|
hash_node_t *_util_htnewpair(const char *key, void *value) {
|
||||||
hash_node_t *node;
|
hash_node_t *node;
|
||||||
if (!(node = mem_a(sizeof(hash_node_t))))
|
if (!(node = (hash_node_t*)mem_a(sizeof(hash_node_t))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(node->key = util_strdup(key))) {
|
if (!(node->key = util_strdup(key))) {
|
||||||
|
@ -452,10 +452,10 @@ hash_table_t *util_htnew(size_t size) {
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(hashtable = mem_a(sizeof(hash_table_t))))
|
if (!(hashtable = (hash_table_t*)mem_a(sizeof(hash_table_t))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(hashtable->table = mem_a(sizeof(hash_node_t*) * size))) {
|
if (!(hashtable->table = (hash_node_t**)mem_a(sizeof(hash_node_t*) * size))) {
|
||||||
mem_d(hashtable);
|
mem_d(hashtable);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue