Add support for char/short/bitfields. Fix up some other stuff for better C compat.
This commit is contained in:
parent
0650610667
commit
affb96a3b3
11 changed files with 1334 additions and 425 deletions
|
@ -1259,6 +1259,19 @@ ELSE()
|
||||||
#SET(INSTALLTARGS ${INSTALLTARGS} httpserver)
|
#SET(INSTALLTARGS ${INSTALLTARGS} httpserver)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
SET(FTE_TOOL_QCVM false CACHE BOOL "Compile standalone qcvm.")
|
||||||
|
IF(FTE_TOOL_QCVM)
|
||||||
|
ADD_EXECUTABLE(qcvm
|
||||||
|
engine/qclib/test.c
|
||||||
|
|
||||||
|
engine/qclib/hash.c
|
||||||
|
${FTE_QCVM_FILES}
|
||||||
|
)
|
||||||
|
SET_TARGET_PROPERTIES(qcvm PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_REVISON}")
|
||||||
|
TARGET_LINK_LIBRARIES(qcvm ${FTEQCC_LIBS} ${SYS_LIBS})
|
||||||
|
SET(INSTALLTARGS ${INSTALLTARGS} qcvm)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
SET(FTE_TOOL_QCC true CACHE BOOL "Compile commandline qc compiler.")
|
SET(FTE_TOOL_QCC true CACHE BOOL "Compile commandline qc compiler.")
|
||||||
IF(FTE_TOOL_QCC)
|
IF(FTE_TOOL_QCC)
|
||||||
ADD_EXECUTABLE(fteqcc
|
ADD_EXECUTABLE(fteqcc
|
||||||
|
|
|
@ -468,7 +468,7 @@ reeval:
|
||||||
ptr = QCPOINTERM(i);
|
ptr = QCPOINTERM(i);
|
||||||
*(unsigned char *)ptr = (char)OPA->_float;
|
*(unsigned char *)ptr = (char)OPA->_float;
|
||||||
break;
|
break;
|
||||||
case OP_STOREP_B: //store (byte) character in a string
|
case OP_STOREP_I8: //store (byte) character in a string
|
||||||
i = OPB->_int + (OPC->_int)*sizeof(pbyte);
|
i = OPB->_int + (OPC->_int)*sizeof(pbyte);
|
||||||
errorif (QCPOINTERWRITEFAIL(i, sizeof(pbyte)))
|
errorif (QCPOINTERWRITEFAIL(i, sizeof(pbyte)))
|
||||||
{
|
{
|
||||||
|
@ -483,6 +483,21 @@ reeval:
|
||||||
ptr = QCPOINTERM(i);
|
ptr = QCPOINTERM(i);
|
||||||
*(pbyte *)ptr = (pbyte)OPA->_int;
|
*(pbyte *)ptr = (pbyte)OPA->_int;
|
||||||
break;
|
break;
|
||||||
|
case OP_STOREP_I16: //store short to a pointer
|
||||||
|
i = OPB->_int + (OPC->_int)*sizeof(short);
|
||||||
|
errorif (QCPOINTERWRITEFAIL(i, sizeof(short)))
|
||||||
|
{
|
||||||
|
if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(short), sizeof(short))))
|
||||||
|
{
|
||||||
|
if (i == -1)
|
||||||
|
break;
|
||||||
|
QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ptr = QCPOINTERM(i);
|
||||||
|
*(short *)ptr = (short)OPA->_int;
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_STOREF_F:
|
case OP_STOREF_F:
|
||||||
case OP_STOREF_I:
|
case OP_STOREF_I:
|
||||||
|
@ -1106,7 +1121,7 @@ reeval:
|
||||||
ptr = QCPOINTERM(i);
|
ptr = QCPOINTERM(i);
|
||||||
OPC->_float = *(unsigned char *)ptr;
|
OPC->_float = *(unsigned char *)ptr;
|
||||||
break;
|
break;
|
||||||
case OP_LOADP_B: //load character from a string/pointer
|
case OP_LOADP_U8: //load character from a string/pointer
|
||||||
i = (unsigned int)OPA->_int + (int)OPB->_int;
|
i = (unsigned int)OPA->_int + (int)OPB->_int;
|
||||||
errorif (QCPOINTERREADFAIL(i, sizeof(pbyte)))
|
errorif (QCPOINTERREADFAIL(i, sizeof(pbyte)))
|
||||||
{
|
{
|
||||||
|
@ -1124,6 +1139,60 @@ reeval:
|
||||||
ptr = QCPOINTERM(i);
|
ptr = QCPOINTERM(i);
|
||||||
OPC->_int = *(pbyte *)ptr;
|
OPC->_int = *(pbyte *)ptr;
|
||||||
break;
|
break;
|
||||||
|
case OP_LOADP_I8: //load character from a string/pointer
|
||||||
|
i = (unsigned int)OPA->_int + (int)OPB->_int;
|
||||||
|
errorif (QCPOINTERREADFAIL(i, sizeof(pbyte)))
|
||||||
|
{
|
||||||
|
if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int, sizeof(pbyte))))
|
||||||
|
{
|
||||||
|
if (i == -1)
|
||||||
|
{
|
||||||
|
OPC->_int = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ptr = QCPOINTERM(i);
|
||||||
|
OPC->_int = *(char *)ptr;
|
||||||
|
break;
|
||||||
|
case OP_LOADP_U16: //load character from a string/pointer
|
||||||
|
i = (unsigned int)OPA->_int + (int)OPB->_int*2;
|
||||||
|
errorif (QCPOINTERREADFAIL(i, sizeof(short)))
|
||||||
|
{
|
||||||
|
if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int*2, sizeof(short))))
|
||||||
|
{
|
||||||
|
if (i == -1)
|
||||||
|
{
|
||||||
|
OPC->_int = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ptr = QCPOINTERM(i);
|
||||||
|
OPC->_int = *(unsigned short *)ptr;
|
||||||
|
break;
|
||||||
|
case OP_LOADP_I16: //load character from a string/pointer
|
||||||
|
i = (unsigned int)OPA->_int + (int)OPB->_int*2;
|
||||||
|
errorif (QCPOINTERREADFAIL(i, sizeof(short)))
|
||||||
|
{
|
||||||
|
if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int*2, sizeof(short))))
|
||||||
|
{
|
||||||
|
if (i == -1)
|
||||||
|
{
|
||||||
|
OPC->_int = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ptr = QCPOINTERM(i);
|
||||||
|
OPC->_int = *(short *)ptr;
|
||||||
|
break;
|
||||||
case OP_LOADP_I:
|
case OP_LOADP_I:
|
||||||
case OP_LOADP_F:
|
case OP_LOADP_F:
|
||||||
case OP_LOADP_FLD:
|
case OP_LOADP_FLD:
|
||||||
|
@ -1653,6 +1722,8 @@ reeval:
|
||||||
case OP_CONV_FI64: OPC->i64 = OPA->_float; break;
|
case OP_CONV_FI64: OPC->i64 = OPA->_float; break;
|
||||||
case OP_CONV_I64D: OPC->_double = OPA->i64; break;
|
case OP_CONV_I64D: OPC->_double = OPA->i64; break;
|
||||||
case OP_CONV_DI64: OPC->i64 = OPA->_double; break;
|
case OP_CONV_DI64: OPC->i64 = OPA->_double; break;
|
||||||
|
case OP_CONV_U64D: OPC->_double = OPA->u64; break;
|
||||||
|
case OP_CONV_DU64: OPC->u64 = OPA->_double; break;
|
||||||
case OP_ADD_D: OPC->_double = OPA->_double + OPB->_double; break;
|
case OP_ADD_D: OPC->_double = OPA->_double + OPB->_double; break;
|
||||||
case OP_SUB_D: OPC->_double = OPA->_double - OPB->_double; break;
|
case OP_SUB_D: OPC->_double = OPA->_double - OPB->_double; break;
|
||||||
case OP_MUL_D: OPC->_double = OPA->_double * OPB->_double; break;
|
case OP_MUL_D: OPC->_double = OPA->_double * OPB->_double; break;
|
||||||
|
@ -1662,8 +1733,11 @@ reeval:
|
||||||
case OP_EQ_D: OPC->_int = OPA->_double == OPB->_double; break;
|
case OP_EQ_D: OPC->_int = OPA->_double == OPB->_double; break;
|
||||||
case OP_NE_D: OPC->_int = OPA->_double != OPB->_double; break;
|
case OP_NE_D: OPC->_int = OPA->_double != OPB->_double; break;
|
||||||
|
|
||||||
|
case OP_BITEXTEND_I: OPC->_int = ( signed int)(OPA->_int << (32-(OPB->_uint&0xff)-(OPB->_uint>>8))) >> (32-(OPB->_uint&0xff)); break; //shift it up and down. should sign extend.
|
||||||
|
case OP_BITEXTEND_U: OPC->_uint = (unsigned int)(OPA->_uint << (32-(OPB->_uint&0xff)-(OPB->_uint>>8))) >> (32-(OPB->_uint&0xff)); break; //shift it up and down. should clear the bits.
|
||||||
|
case OP_BITCOPY_I: i=((1<<(OPB->_uint&0xff))-1);OPC->_int=(OPC->_int&~(i<<(OPB->_uint>>8)))|(((OPA->_int&i)<<(OPB->_uint>>8)));break; //replaces the specified bits (uses the same format bitextend uses to select its input to extend)
|
||||||
|
case OP_CONV_UF: OPC->_float = OPA->_uint; break;
|
||||||
|
case OP_CONV_FU: OPC->_uint = OPA->_float; break;
|
||||||
|
|
||||||
case OP_UNUSED:
|
case OP_UNUSED:
|
||||||
case OP_POP:
|
case OP_POP:
|
||||||
|
|
|
@ -339,8 +339,8 @@ enum qcop_e {
|
||||||
OP_STOREF_I, //1 non-string reference/int
|
OP_STOREF_I, //1 non-string reference/int
|
||||||
|
|
||||||
//r5744+
|
//r5744+
|
||||||
OP_STOREP_B,//((char*)b)[(int)c] = (int)a
|
OP_STOREP_I8, //((char*)b)[(int)c] = (int)a
|
||||||
OP_LOADP_B, //(int)c = *(char*)
|
OP_LOADP_U8, //(int)c = *(unsigned char*)
|
||||||
|
|
||||||
//r5768+
|
//r5768+
|
||||||
//opcodes for 32bit uints
|
//opcodes for 32bit uints
|
||||||
|
@ -397,6 +397,18 @@ enum qcop_e {
|
||||||
OP_EQ_D,
|
OP_EQ_D,
|
||||||
OP_NE_D,
|
OP_NE_D,
|
||||||
|
|
||||||
|
//r6614+
|
||||||
|
OP_STOREP_I16, //((short*)b)[(int)c] = (int)a
|
||||||
|
OP_LOADP_I16, //(int)c = *(signed short*)a (sign extends)
|
||||||
|
OP_LOADP_U16, //(unsigned int)c = *(unsigned short*)a
|
||||||
|
OP_LOADP_I8, //(unsigned int)c = *(signed char*)a (sign extends)
|
||||||
|
OP_BITEXTEND_I, //sign extend (for signed bitfields)
|
||||||
|
OP_BITEXTEND_U, //zero extend (for unsigned bitfields)
|
||||||
|
OP_BITCOPY_I, //copy lower bits from the input to some part of the output
|
||||||
|
OP_CONV_UF, //OPC.f=(float)OPA.i -- 0xffffffffu*0.5=0 otherwise.
|
||||||
|
OP_CONV_FU, //OPC.i=(int)OPA.f
|
||||||
|
OP_CONV_U64D, //OPC.d=(double)OPA.u64 -- useful mostly so decompilers don't do weird stuff.
|
||||||
|
OP_CONV_DU64, //OPC.u64=(uint64_t)OPA.d
|
||||||
|
|
||||||
OP_NUMREALOPS,
|
OP_NUMREALOPS,
|
||||||
|
|
||||||
|
@ -531,8 +543,8 @@ enum qcop_e {
|
||||||
//uint64 opcodes. they match the int32 ones so emulation is basically swapping them over.
|
//uint64 opcodes. they match the int32 ones so emulation is basically swapping them over.
|
||||||
OP_BITNOT_I64, //BITXOR ~0
|
OP_BITNOT_I64, //BITXOR ~0
|
||||||
OP_BITCLR_I64,
|
OP_BITCLR_I64,
|
||||||
OP_GE_I64, //LT_I64
|
OP_GE_I64, //LE_I64
|
||||||
OP_GT_I64, //LE_I64
|
OP_GT_I64, //LT_I64
|
||||||
|
|
||||||
OP_ADD_U64,
|
OP_ADD_U64,
|
||||||
OP_SUB_U64,
|
OP_SUB_U64,
|
||||||
|
@ -544,8 +556,8 @@ enum qcop_e {
|
||||||
OP_BITNOT_U64, //BITXOR ~0
|
OP_BITNOT_U64, //BITXOR ~0
|
||||||
OP_BITCLR_U64,
|
OP_BITCLR_U64,
|
||||||
OP_LSHIFT_U64I,
|
OP_LSHIFT_U64I,
|
||||||
OP_GE_U64, //LT_U64
|
OP_GE_U64, //LE_U64
|
||||||
OP_GT_U64, //LE_U64
|
OP_GT_U64, //LT_U64
|
||||||
OP_EQ_U64,
|
OP_EQ_U64,
|
||||||
OP_NE_U64,
|
OP_NE_U64,
|
||||||
|
|
||||||
|
@ -557,6 +569,8 @@ enum qcop_e {
|
||||||
OP_BITCLR_D,
|
OP_BITCLR_D,
|
||||||
OP_LSHIFT_DI,
|
OP_LSHIFT_DI,
|
||||||
OP_RSHIFT_DI,
|
OP_RSHIFT_DI,
|
||||||
|
OP_GE_D, //LE_D
|
||||||
|
OP_GT_D, //LT_D
|
||||||
|
|
||||||
OP_WSTATE, //for the 'w' part of CWSTATE. will probably never be used, but hey, hexen2...
|
OP_WSTATE, //for the 'w' part of CWSTATE. will probably never be used, but hey, hexen2...
|
||||||
|
|
||||||
|
@ -618,7 +632,12 @@ typedef struct statement32_s
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct QCC_def_s *sym;
|
struct QCC_def_s *sym;
|
||||||
unsigned int ofs;
|
union
|
||||||
|
{
|
||||||
|
unsigned int ofs;
|
||||||
|
// unsigned int bofs;
|
||||||
|
signed int jumpofs;
|
||||||
|
};
|
||||||
struct QCC_type_s *cast; //the entire sref is considered null if there is no cast, although it *MAY* have an ofs specified if its part of a jump instruction
|
struct QCC_type_s *cast; //the entire sref is considered null if there is no cast, although it *MAY* have an ofs specified if its part of a jump instruction
|
||||||
} QCC_sref_t;
|
} QCC_sref_t;
|
||||||
typedef struct qcc_statement_s
|
typedef struct qcc_statement_s
|
||||||
|
|
|
@ -562,6 +562,7 @@ static int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int
|
||||||
}
|
}
|
||||||
|
|
||||||
prinst.pr_xfunction = f;
|
prinst.pr_xfunction = f;
|
||||||
|
prinst.spushed = 0;
|
||||||
return f->first_statement - 1; // offset the s++
|
return f->first_statement - 1; // offset the s++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,6 +1912,7 @@ typedef struct {
|
||||||
int fnum;
|
int fnum;
|
||||||
int progsnum;
|
int progsnum;
|
||||||
int statement;
|
int statement;
|
||||||
|
int spushed;
|
||||||
} qcthreadstack_t;
|
} qcthreadstack_t;
|
||||||
typedef struct qcthread_s {
|
typedef struct qcthread_s {
|
||||||
int fstackdepth;
|
int fstackdepth;
|
||||||
|
@ -1947,6 +1949,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf)
|
||||||
thread->fstack[i-ed].fnum = prinst.pr_stack[i].f - pr_progstate[prinst.pr_stack[i].progsnum].functions;
|
thread->fstack[i-ed].fnum = prinst.pr_stack[i].f - pr_progstate[prinst.pr_stack[i].progsnum].functions;
|
||||||
thread->fstack[i-ed].progsnum = prinst.pr_stack[i].progsnum;
|
thread->fstack[i-ed].progsnum = prinst.pr_stack[i].progsnum;
|
||||||
thread->fstack[i-ed].statement = prinst.pr_stack[i].s;
|
thread->fstack[i-ed].statement = prinst.pr_stack[i].s;
|
||||||
|
thread->fstack[i-ed].spushed = prinst.pr_stack[i].pushed;
|
||||||
|
|
||||||
if (i+1 == prinst.pr_depth)
|
if (i+1 == prinst.pr_depth)
|
||||||
f = prinst.pr_xfunction;
|
f = prinst.pr_xfunction;
|
||||||
|
@ -1996,7 +1999,7 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
mfunction_t *f, *oldf;
|
mfunction_t *f, *oldf;
|
||||||
int i,l,ls, olds;
|
int i,l,ls, olds, oldp;
|
||||||
progsnum_t initial_progs;
|
progsnum_t initial_progs;
|
||||||
int oldexitdepth;
|
int oldexitdepth;
|
||||||
int *glob;
|
int *glob;
|
||||||
|
@ -2033,12 +2036,14 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
|
||||||
prinst.pr_stack[prinst.pr_depth].f = prinst.pr_xfunction;
|
prinst.pr_stack[prinst.pr_depth].f = prinst.pr_xfunction;
|
||||||
prinst.pr_stack[prinst.pr_depth].s = prinst.pr_xstatement;
|
prinst.pr_stack[prinst.pr_depth].s = prinst.pr_xstatement;
|
||||||
prinst.pr_stack[prinst.pr_depth].progsnum = initial_progs;
|
prinst.pr_stack[prinst.pr_depth].progsnum = initial_progs;
|
||||||
|
prinst.pr_stack[prinst.pr_depth].pushed = prinst.spushed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prinst.pr_stack[prinst.pr_depth].progsnum = thread->fstack[i].progsnum;
|
prinst.pr_stack[prinst.pr_depth].progsnum = thread->fstack[i].progsnum;
|
||||||
prinst.pr_stack[prinst.pr_depth].f = pr_progstate[thread->fstack[i].progsnum].functions + thread->fstack[i].fnum;
|
prinst.pr_stack[prinst.pr_depth].f = pr_progstate[thread->fstack[i].progsnum].functions + thread->fstack[i].fnum;
|
||||||
prinst.pr_stack[prinst.pr_depth].s = thread->fstack[i].statement;
|
prinst.pr_stack[prinst.pr_depth].s = thread->fstack[i].statement;
|
||||||
|
prinst.pr_stack[prinst.pr_depth].pushed = thread->fstack[i].spushed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i+1 == thread->fstackdepth)
|
if (i+1 == thread->fstackdepth)
|
||||||
|
@ -2080,6 +2085,7 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
|
||||||
// PR_EnterFunction (progfuncs, f, initial_progs);
|
// PR_EnterFunction (progfuncs, f, initial_progs);
|
||||||
oldf = prinst.pr_xfunction;
|
oldf = prinst.pr_xfunction;
|
||||||
olds = prinst.pr_xstatement;
|
olds = prinst.pr_xstatement;
|
||||||
|
oldp = prinst.spushed;
|
||||||
prinst.pr_xfunction = f;
|
prinst.pr_xfunction = f;
|
||||||
s = thread->xstatement;
|
s = thread->xstatement;
|
||||||
|
|
||||||
|
@ -2098,6 +2104,7 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
|
||||||
prinst.exitdepth = oldexitdepth;
|
prinst.exitdepth = oldexitdepth;
|
||||||
prinst.pr_xfunction = oldf;
|
prinst.pr_xfunction = oldf;
|
||||||
prinst.pr_xstatement = olds;
|
prinst.pr_xstatement = olds;
|
||||||
|
prinst.spushed = oldp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDECL PR_AbortStack (pubprogfuncs_t *ppf)
|
void PDECL PR_AbortStack (pubprogfuncs_t *ppf)
|
||||||
|
|
|
@ -95,7 +95,8 @@ ev_union, //not really sure why this is separate from struct
|
||||||
ev_accessor,//some weird type to provide class-like functions over a basic type.
|
ev_accessor,//some weird type to provide class-like functions over a basic type.
|
||||||
ev_enum, //just a numeric type
|
ev_enum, //just a numeric type
|
||||||
ev_typedef, //so typedefs can refer to their original type (primarily for structs).
|
ev_typedef, //so typedefs can refer to their original type (primarily for structs).
|
||||||
ev_boolean, //exists to optimise if(-0) workarounds. engine just sees int/float.
|
ev_boolean, //exists to optimise if(-0) workarounds. engine just sees int/float. uses parentclass
|
||||||
|
ev_bitfld, //erk... structs only... converted to their parentclass on read.
|
||||||
} etype_t;
|
} etype_t;
|
||||||
enum {
|
enum {
|
||||||
DEBUG_TRACE_OFF, //debugging should be off.
|
DEBUG_TRACE_OFF, //debugging should be off.
|
||||||
|
|
|
@ -66,6 +66,12 @@ extern progfuncs_t *qccprogfuncs;
|
||||||
#define LIKEPRINTF(x)
|
#define LIKEPRINTF(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ >= 199901L
|
||||||
|
#define qc_inlinestatic static inline
|
||||||
|
#else
|
||||||
|
#define qc_inlinestatic static
|
||||||
|
#endif
|
||||||
|
|
||||||
void *qccHunkAlloc(size_t mem);
|
void *qccHunkAlloc(size_t mem);
|
||||||
void qccClearHunk(void);
|
void qccClearHunk(void);
|
||||||
|
|
||||||
|
@ -373,7 +379,8 @@ struct QCC_typeparam_s
|
||||||
pbool optional:1; //argument may safely be omitted, for builtin functions. for qc functions use the defltvalue instead.
|
pbool optional:1; //argument may safely be omitted, for builtin functions. for qc functions use the defltvalue instead.
|
||||||
pbool isvirtual:1; //const, with implicit initialisation only. valid for structs
|
pbool isvirtual:1; //const, with implicit initialisation only. valid for structs
|
||||||
unsigned char out; //0=in,1==inout,2=out
|
unsigned char out; //0=in,1==inout,2=out
|
||||||
unsigned int ofs; //FIXME: make byte offsets, for bytes/shorts.
|
unsigned int ofs; //word offset.
|
||||||
|
unsigned int bitofs; //for bitfields (and chars/shorts).
|
||||||
unsigned int arraysize;
|
unsigned int arraysize;
|
||||||
char *paramname;
|
char *paramname;
|
||||||
};
|
};
|
||||||
|
@ -403,6 +410,8 @@ typedef struct QCC_type_s
|
||||||
pbool typedefed:1; //name is in the typenames list.
|
pbool typedefed:1; //name is in the typenames list.
|
||||||
pbool vargs:1; //function has vargs
|
pbool vargs:1; //function has vargs
|
||||||
pbool vargcount:1; //function has special varg count param
|
pbool vargcount:1; //function has special varg count param
|
||||||
|
unsigned int bits;//valid for bitfields (and structs).
|
||||||
|
unsigned int align:7;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *aname;
|
const char *aname;
|
||||||
|
|
||||||
|
@ -487,6 +496,7 @@ struct temp_s {
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
struct QCC_function_s *lastfunc;
|
struct QCC_function_s *lastfunc;
|
||||||
|
unsigned int lastline;
|
||||||
unsigned int laststatement;
|
unsigned int laststatement;
|
||||||
};
|
};
|
||||||
extern size_t tempsused;
|
extern size_t tempsused;
|
||||||
|
@ -506,6 +516,7 @@ typedef struct
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
QCC_sref_t base;
|
QCC_sref_t base;
|
||||||
|
unsigned int bitofs; //for bitfields.
|
||||||
QCC_sref_t index;
|
QCC_sref_t index;
|
||||||
QCC_type_t *cast; //entity.float is float, not pointer.
|
QCC_type_t *cast; //entity.float is float, not pointer.
|
||||||
struct accessor_s *accessor; //the accessor field of base that we're trying to use
|
struct accessor_s *accessor; //the accessor field of base that we're trying to use
|
||||||
|
@ -526,7 +537,7 @@ extern int QCC_packid;
|
||||||
extern const unsigned int type_size[];
|
extern const unsigned int type_size[];
|
||||||
//extern QCC_def_t *def_for_type[9];
|
//extern QCC_def_t *def_for_type[9];
|
||||||
|
|
||||||
extern QCC_type_t *type_void, *type_string, *type_float, *type_double, *type_vector, *type_entity, *type_field, *type_function, *type_floatfunction, *type_pointer, *type_floatpointer, *type_intpointer, *type_bint, *type_bfloat, *type_integer, *type_uint, *type_int64, *type_uint64, *type_invalid, *type_variant, *type_floatfield;
|
extern QCC_type_t *type_void, *type_string, *type_float, *type_double, *type_vector, *type_entity, *type_field, *type_function, *type_floatfunction, *type_pointer, *type_floatpointer, *type_intpointer, *type_bint, *type_bfloat, *type_sint8, *type_uint8, *type_sint16, *type_uint16, *type_integer, *type_uint, *type_int64, *type_uint64, *type_invalid, *type_variant, *type_floatfield;
|
||||||
extern char *basictypenames[];
|
extern char *basictypenames[];
|
||||||
|
|
||||||
struct QCC_function_s
|
struct QCC_function_s
|
||||||
|
@ -769,7 +780,7 @@ void QCC_PR_Lex (void);
|
||||||
QCC_type_t *QCC_PR_NewType (const char *name, int basictype, pbool typedefed); //note: name must be hunk/immediate
|
QCC_type_t *QCC_PR_NewType (const char *name, int basictype, pbool typedefed); //note: name must be hunk/immediate
|
||||||
QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type);
|
QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type);
|
||||||
QCC_type_t *QCC_GenArrayType(QCC_type_t *type, unsigned int arraysize);
|
QCC_type_t *QCC_GenArrayType(QCC_type_t *type, unsigned int arraysize);
|
||||||
QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail);
|
QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail, pbool ignoreptr);
|
||||||
QCC_sref_t QCC_PR_ParseDefaultInitialiser(QCC_type_t *type);
|
QCC_sref_t QCC_PR_ParseDefaultInitialiser(QCC_type_t *type);
|
||||||
extern pbool type_inlinefunction;
|
extern pbool type_inlinefunction;
|
||||||
QCC_type_t *QCC_TypeForName(const char *name);
|
QCC_type_t *QCC_TypeForName(const char *name);
|
||||||
|
@ -777,7 +788,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype);
|
||||||
QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype);
|
QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype);
|
||||||
QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s *args, int numargs);
|
QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s *args, int numargs);
|
||||||
char *QCC_PR_ParseName (void);
|
char *QCC_PR_ParseName (void);
|
||||||
struct QCC_typeparam_s *QCC_PR_FindStructMember(QCC_type_t *t, const char *membername, unsigned int *out_ofs);
|
struct QCC_typeparam_s *QCC_PR_FindStructMember(QCC_type_t *t, const char *membername, unsigned int *out_ofs, unsigned int *out_bitofs);
|
||||||
QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto);
|
QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto);
|
||||||
|
|
||||||
const char *QCC_VarAtOffset(QCC_sref_t ref);
|
const char *QCC_VarAtOffset(QCC_sref_t ref);
|
||||||
|
|
|
@ -39,6 +39,7 @@ const unsigned int type_size[] = {1, //void
|
||||||
0, //ev_enum...
|
0, //ev_enum...
|
||||||
0, //ev_typedef
|
0, //ev_typedef
|
||||||
1, //ev_bool...
|
1, //ev_bool...
|
||||||
|
0, //bitfld...
|
||||||
};
|
};
|
||||||
|
|
||||||
char *basictypenames[] = {
|
char *basictypenames[] = {
|
||||||
|
@ -60,7 +61,9 @@ char *basictypenames[] = {
|
||||||
"union",
|
"union",
|
||||||
"accessor",
|
"accessor",
|
||||||
"enum",
|
"enum",
|
||||||
"bool"
|
"typedef",
|
||||||
|
"bool",
|
||||||
|
"bitfield",
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -93,9 +93,13 @@ QCC_type_t *type_field; //.void
|
||||||
QCC_type_t *type_function; //void()
|
QCC_type_t *type_function; //void()
|
||||||
QCC_type_t *type_floatfunction; //float()
|
QCC_type_t *type_floatfunction; //float()
|
||||||
QCC_type_t *type_pointer; //??? * - careful with this one
|
QCC_type_t *type_pointer; //??? * - careful with this one
|
||||||
|
QCC_type_t *type_sint8; //char - these small types are technically ev_bitfield, but typedefed and aligned.
|
||||||
|
QCC_type_t *type_uint8; //unsigned char
|
||||||
|
QCC_type_t *type_sint16; //short
|
||||||
|
QCC_type_t *type_uint16; //unsigned short
|
||||||
QCC_type_t *type_integer; //int32
|
QCC_type_t *type_integer; //int32
|
||||||
QCC_type_t *type_uint; //uint32
|
QCC_type_t *type_uint; //uint32
|
||||||
QCC_type_t *type_int64; //int64
|
QCC_type_t *type_int64; //int64
|
||||||
QCC_type_t *type_uint64; //uint64
|
QCC_type_t *type_uint64; //uint64
|
||||||
QCC_type_t *type_variant; //__variant
|
QCC_type_t *type_variant; //__variant
|
||||||
QCC_type_t *type_invalid; //technically void, but shouldn't really ever be used.
|
QCC_type_t *type_invalid; //technically void, but shouldn't really ever be used.
|
||||||
|
@ -1611,8 +1615,33 @@ int QCC_PR_LexEscapedCodepoint(void)
|
||||||
c = '\\';
|
c = '\\';
|
||||||
else if (c == '\'')
|
else if (c == '\'')
|
||||||
c = '\'';
|
c = '\'';
|
||||||
else if (c >= '0' && c <= '9') //WARNING: This is not octal, but uses 'yellow' numbers instead (as on hud).
|
else if (c >= '0' && c <= '9')
|
||||||
c = 0xe012 + c - '0';
|
{
|
||||||
|
if (flag_qcfuncs)
|
||||||
|
c = 0xe012 + c - '0'; //WARNING: This is not an octal code, but uses 'yellow' numbers instead (as on hud).
|
||||||
|
else //C compat
|
||||||
|
{
|
||||||
|
int d = c, base = 8;
|
||||||
|
c = 0;
|
||||||
|
|
||||||
|
if (d >= '0' && d < '0'+base)
|
||||||
|
c = c*base + (d - '0');
|
||||||
|
else
|
||||||
|
QCC_PR_ParseError(ERR_BADCHARACTERCODE, "Bad character code \\%c", d);
|
||||||
|
|
||||||
|
d = (unsigned char)*pr_file_p++;
|
||||||
|
if (d >= '0' && d < '0'+base)
|
||||||
|
c = c*base + (d - '0');
|
||||||
|
else
|
||||||
|
pr_file_p --; //oops. only one char valid...
|
||||||
|
|
||||||
|
d = (unsigned char)*pr_file_p++;
|
||||||
|
if (d >= '0' && d < '0'+base)
|
||||||
|
c = c*base + (d - '0');
|
||||||
|
else
|
||||||
|
pr_file_p --; //oops. only twoish chars valid...
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (c == '\r')
|
else if (c == '\r')
|
||||||
{ //sigh
|
{ //sigh
|
||||||
c = *pr_file_p++;
|
c = *pr_file_p++;
|
||||||
|
@ -2081,6 +2110,7 @@ static void QCC_PR_LexNumber (void)
|
||||||
}
|
}
|
||||||
else if (c == 'f' || c == 'F')
|
else if (c == 'f' || c == 'F')
|
||||||
{
|
{
|
||||||
|
pr_immediate_type = type_float;
|
||||||
pr_file_p++;
|
pr_file_p++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2139,7 +2169,7 @@ static void QCC_PR_LexNumber (void)
|
||||||
{ //length suffix was first.
|
{ //length suffix was first.
|
||||||
//long-long?
|
//long-long?
|
||||||
if (*pr_file_p == c)
|
if (*pr_file_p == c)
|
||||||
pr_token[tokenlen++] = *pr_file_p++;
|
islong++, pr_token[tokenlen++] = *pr_file_p++;
|
||||||
//check for signed suffix...
|
//check for signed suffix...
|
||||||
c = *pr_file_p;
|
c = *pr_file_p;
|
||||||
isunsigned = (c == 'u')||(c=='U');
|
isunsigned = (c == 'u')||(c=='U');
|
||||||
|
@ -2157,13 +2187,13 @@ static void QCC_PR_LexNumber (void)
|
||||||
islong = true;
|
islong = true;
|
||||||
//long-long?
|
//long-long?
|
||||||
if (*pr_file_p == c)
|
if (*pr_file_p == c)
|
||||||
pr_token[tokenlen++] = *pr_file_p++;
|
islong++, pr_token[tokenlen++] = *pr_file_p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pr_token[tokenlen++] = 0;
|
pr_token[tokenlen++] = 0;
|
||||||
num *= sign;
|
num *= sign;
|
||||||
if (islong)
|
if (islong >= (flag_ILP32?2:1))
|
||||||
{
|
{ //enough longs for our 64bit type.
|
||||||
pr_immediate_type = (isunsigned)?type_uint64:type_int64;
|
pr_immediate_type = (isunsigned)?type_uint64:type_int64;
|
||||||
pr_immediate.i64 = num;
|
pr_immediate.i64 = num;
|
||||||
}
|
}
|
||||||
|
@ -2190,7 +2220,16 @@ static void QCC_PR_LexNumber (void)
|
||||||
{
|
{
|
||||||
//float f = num;
|
//float f = num;
|
||||||
if (flag_assume_integer)// || (base != 10 && sign > 0 && (long long)f != (long long)num))
|
if (flag_assume_integer)// || (base != 10 && sign > 0 && (long long)f != (long long)num))
|
||||||
pr_immediate_type = type_integer;
|
{
|
||||||
|
if (num > UINT64_C(0x7fffffffffffffff))
|
||||||
|
pr_immediate_type = type_uint64;
|
||||||
|
else if (num > 0xffffffffu)
|
||||||
|
pr_immediate_type = type_int64;
|
||||||
|
else if (num > 0x7fffffffu)
|
||||||
|
pr_immediate_type = type_uint;
|
||||||
|
else
|
||||||
|
pr_immediate_type = type_integer;
|
||||||
|
}
|
||||||
else if (flag_qccx && base == 16)
|
else if (flag_qccx && base == 16)
|
||||||
{
|
{
|
||||||
pr_immediate_type = type_float;
|
pr_immediate_type = type_float;
|
||||||
|
@ -2200,9 +2239,10 @@ static void QCC_PR_LexNumber (void)
|
||||||
pr_immediate_type = type_float;
|
pr_immediate_type = type_float;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_immediate_type == type_integer)
|
if (pr_immediate_type == type_int64 || pr_immediate_type == type_uint64)
|
||||||
|
pr_immediate.i64 = num*sign;
|
||||||
|
else if (pr_immediate_type == type_integer || pr_immediate_type == type_uint)
|
||||||
{
|
{
|
||||||
pr_immediate_type = type_integer;
|
|
||||||
qccxhex:
|
qccxhex:
|
||||||
pr_immediate._int = num*sign;
|
pr_immediate._int = num*sign;
|
||||||
|
|
||||||
|
@ -3376,12 +3416,18 @@ static char *QCC_PR_CheckBuiltinCompConst(char *constname, char *retbuf, size_t
|
||||||
}
|
}
|
||||||
if (!strcmp(constname, "__LINE__"))
|
if (!strcmp(constname, "__LINE__"))
|
||||||
{
|
{
|
||||||
QC_snprintfz(retbuf, retbufsize, "%i", pr_source_line);
|
int line = pr_source_line;
|
||||||
|
if (currentchunk && currentchunk->cnst) //if we're in a macro, use the line the macro was on.
|
||||||
|
line = currentchunk->currentlinenumber;
|
||||||
|
QC_snprintfz(retbuf, retbufsize, "%i", line);
|
||||||
return retbuf;
|
return retbuf;
|
||||||
}
|
}
|
||||||
if (!strcmp(constname, "__LINESTR__"))
|
if (!strcmp(constname, "__LINESTR__"))
|
||||||
{
|
{
|
||||||
QC_snprintfz(retbuf, retbufsize, "\"%i\"", pr_source_line);
|
int line = pr_source_line;
|
||||||
|
if (currentchunk && currentchunk->cnst) //if we're in a macro, use the line the macro was on.
|
||||||
|
line = currentchunk->currentlinenumber;
|
||||||
|
QC_snprintfz(retbuf, retbufsize, "\"%i\"", line);
|
||||||
return retbuf;
|
return retbuf;
|
||||||
}
|
}
|
||||||
if (!strcmp(constname, "__FUNC__") || !strcmp(constname, "__func__"))
|
if (!strcmp(constname, "__FUNC__") || !strcmp(constname, "__func__"))
|
||||||
|
@ -4252,7 +4298,17 @@ Gets the next token
|
||||||
void QCC_PR_Expect (const char *string)
|
void QCC_PR_Expect (const char *string)
|
||||||
{
|
{
|
||||||
if (STRCMP (string, pr_token))
|
if (STRCMP (string, pr_token))
|
||||||
QCC_PR_ParseError (ERR_EXPECTED, "expected %s%s%s, found %s%s%s", col_location, string, col_none, col_name, pr_token, col_none);
|
{
|
||||||
|
if (pr_token_type == tt_immediate && pr_immediate_type == type_string)
|
||||||
|
{
|
||||||
|
if (pr_immediate_strlen > 32)
|
||||||
|
QCC_PR_ParseError (ERR_EXPECTED, "expected %s%s%s, found string immediate", col_location, string, col_none);
|
||||||
|
else
|
||||||
|
QCC_PR_ParseError (ERR_EXPECTED, "expected %s%s%s, found %s\"%s\"%s", col_location, string, col_none, col_name, pr_token, col_none);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QCC_PR_ParseError (ERR_EXPECTED, "expected %s%s%s, found %s%s%s", col_location, string, col_none, col_name, pr_token, col_none);
|
||||||
|
}
|
||||||
QCC_PR_Lex ();
|
QCC_PR_Lex ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4530,7 +4586,7 @@ static int typecmp_strict(QCC_type_t *a, QCC_type_t *b)
|
||||||
if (a->vargcount != b->vargcount)
|
if (a->vargcount != b->vargcount)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (a->size != b->size)
|
if (a->size != b->size || a->bits != b->bits || a->align != b->align)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (a->accessors != b->accessors)
|
if (a->accessors != b->accessors)
|
||||||
|
@ -4579,7 +4635,7 @@ int typecmp(QCC_type_t *a, QCC_type_t *b)
|
||||||
if (a->vargcount != b->vargcount)
|
if (a->vargcount != b->vargcount)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (a->size != b->size)
|
if (a->size != b->size || a->bits != b->bits)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if ((a->type == ev_entity && a->parentclass) || a->type == ev_struct || a->type == ev_union)
|
if ((a->type == ev_entity && a->parentclass) || a->type == ev_struct || a->type == ev_union)
|
||||||
|
@ -4957,6 +5013,10 @@ void QCC_PR_SkipToSemicolon (void)
|
||||||
} while (pr_token_type != tt_eof);
|
} while (pr_token_type != tt_eof);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qc_inlinestatic QCC_eval_t *QCC_SRef_Data(QCC_sref_t ref)
|
||||||
|
{
|
||||||
|
return (QCC_eval_t*)&ref.sym->symboldata[ref.ofs];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
|
@ -5033,7 +5093,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
|
||||||
|
|
||||||
if (QCC_PR_CheckToken ("..."))
|
if (QCC_PR_CheckToken ("..."))
|
||||||
{
|
{
|
||||||
t = QCC_PR_ParseType(false, true); //the evil things I do...
|
t = QCC_PR_ParseType(false, true, false); //the evil things I do...
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
ftype->vargs = true;
|
ftype->vargs = true;
|
||||||
|
@ -5078,7 +5138,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = QCC_PR_ParseType(false, false);
|
t = QCC_PR_ParseType(false, false, false);
|
||||||
}
|
}
|
||||||
paramlist[numparms].defltvalue.cast = NULL;
|
paramlist[numparms].defltvalue.cast = NULL;
|
||||||
paramlist[numparms].ofs = 0;
|
paramlist[numparms].ofs = 0;
|
||||||
|
@ -5225,7 +5285,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
||||||
{
|
{
|
||||||
name = QCC_PR_ParseName();
|
name = QCC_PR_ParseName();
|
||||||
QCC_PR_Expect(":");
|
QCC_PR_Expect(":");
|
||||||
nptype = QCC_PR_ParseType(true, false);
|
nptype = QCC_PR_ParseType(true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nptype)
|
if (!nptype)
|
||||||
|
@ -5238,6 +5298,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
||||||
paramlist[numparms].optional = false;
|
paramlist[numparms].optional = false;
|
||||||
paramlist[numparms].isvirtual = false;
|
paramlist[numparms].isvirtual = false;
|
||||||
paramlist[numparms].ofs = 0;
|
paramlist[numparms].ofs = 0;
|
||||||
|
paramlist[numparms].bitofs = 0;
|
||||||
paramlist[numparms].arraysize = 0;
|
paramlist[numparms].arraysize = 0;
|
||||||
paramlist[numparms].type = nptype;
|
paramlist[numparms].type = nptype;
|
||||||
|
|
||||||
|
@ -5437,7 +5498,7 @@ struct accessor_s *QCC_PR_ParseAccessorMember(QCC_type_t *classtype, pbool isinl
|
||||||
f = QCC_PR_ParseImmediateStatements (def.sym, functype, false);
|
f = QCC_PR_ParseImmediateStatements (def.sym, functype, false);
|
||||||
pr_classtype = NULL;
|
pr_classtype = NULL;
|
||||||
pr_scope = NULL;
|
pr_scope = NULL;
|
||||||
def.sym->symboldata[def.ofs].function = f - functions;
|
QCC_SRef_Data(def)->function = f - functions;
|
||||||
f->def = def.sym;
|
f->def = def.sym;
|
||||||
def.sym->initialized = 1;
|
def.sym->initialized = 1;
|
||||||
}
|
}
|
||||||
|
@ -5495,7 +5556,7 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
QCC_type_t *newt, *type, *newparm;
|
QCC_type_t *newt, *type, *newparm;
|
||||||
struct QCC_typeparam_s *parms = NULL, *oldparm;
|
struct QCC_typeparam_s *parms = NULL, *oldparm;
|
||||||
int numparms = 0;
|
int numparms = 0;
|
||||||
int ofs;
|
int ofs, bitofs;
|
||||||
unsigned int arraysize;
|
unsigned int arraysize;
|
||||||
char *parmname;
|
char *parmname;
|
||||||
|
|
||||||
|
@ -5503,6 +5564,8 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
pbool isstatic = false;
|
pbool isstatic = false;
|
||||||
pbool isvirt = false;
|
pbool isvirt = false;
|
||||||
pbool definedsomething = false;
|
pbool definedsomething = false;
|
||||||
|
unsigned int bitsize;
|
||||||
|
unsigned int bitalign = 0; //alignment of largest element...
|
||||||
|
|
||||||
if (QCC_PR_CheckToken("{"))
|
if (QCC_PR_CheckToken("{"))
|
||||||
{
|
{
|
||||||
|
@ -5555,6 +5618,7 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
newt->size = newt->parentclass->size;
|
newt->size = newt->parentclass->size;
|
||||||
else
|
else
|
||||||
newt->size=0;
|
newt->size=0;
|
||||||
|
bitsize = newt->size<<5;
|
||||||
|
|
||||||
type = NULL;
|
type = NULL;
|
||||||
|
|
||||||
|
@ -5624,7 +5688,7 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
// isignored = true;
|
// isignored = true;
|
||||||
|
|
||||||
//now parse the actual type.
|
//now parse the actual type.
|
||||||
newparm = QCC_PR_ParseType(false, false);
|
newparm = QCC_PR_ParseType(false, false, true);
|
||||||
definedsomething = false;
|
definedsomething = false;
|
||||||
}
|
}
|
||||||
type = newparm;
|
type = newparm;
|
||||||
|
@ -5679,8 +5743,26 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
|
|
||||||
if (QCC_PR_CheckToken(":"))
|
if (QCC_PR_CheckToken(":"))
|
||||||
{
|
{
|
||||||
QCC_PR_IntConstExpr();
|
int bits = QCC_PR_IntConstExpr();
|
||||||
QCC_PR_ParseWarning(WARN_IGNOREDKEYWORD, "bitfields are not supported");
|
if (bits > 64)
|
||||||
|
QCC_PR_ParseWarning(ERR_BADNOTTYPE, "too many bits");
|
||||||
|
else if (type->type == ev_integer || type->type == ev_uint || type->type == ev_int64 || type->type == ev_uint64)
|
||||||
|
{
|
||||||
|
QCC_type_t *bitfld;
|
||||||
|
//prmote to bigger if big.
|
||||||
|
if (bits > 32 && type->type == ev_integer)
|
||||||
|
type = type_int64;
|
||||||
|
if (bits > 32 && type->type == ev_uint)
|
||||||
|
type = type_uint64;
|
||||||
|
bitfld = QCC_PR_NewType("bitfld", ev_bitfld, false);
|
||||||
|
bitfld->bits = bits;
|
||||||
|
bitfld->size = type->size;
|
||||||
|
bitfld->parentclass = type;
|
||||||
|
bitfld->align = type->align; //use the parent's alignment, for some reason.
|
||||||
|
type = bitfld;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QCC_PR_ParseWarning(ERR_BADNOTTYPE, "bitfields must be integer types");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isnonvirt || isvirt) && type->type != ev_function)
|
if ((isnonvirt || isvirt) && type->type != ev_function)
|
||||||
|
@ -5727,25 +5809,59 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
parms = realloc(parms, sizeof(*parms) * (numparms+4));
|
parms = realloc(parms, sizeof(*parms) * (numparms+4));
|
||||||
oldparm = QCC_PR_FindStructMember(newt, parmname, &ofs);
|
oldparm = QCC_PR_FindStructMember(newt, parmname, &ofs, &bitofs);
|
||||||
|
if (type->align)
|
||||||
|
{
|
||||||
|
if (bitalign < type->align)
|
||||||
|
bitalign = type->align; //bigger than that...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bitalign = 32; //struct must be word aligned.
|
||||||
if (oldparm && oldparm->arraysize == arraysize && !typecmp_lax(oldparm->type, type))
|
if (oldparm && oldparm->arraysize == arraysize && !typecmp_lax(oldparm->type, type))
|
||||||
{
|
{
|
||||||
|
ofs <<= 5;
|
||||||
|
ofs += bitofs;
|
||||||
if (!isvirt)
|
if (!isvirt)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (structtype == ev_union)
|
else if (structtype == ev_union)
|
||||||
{
|
{
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
if (type->size*(arraysize?arraysize:1) > newt->size)
|
if (type->bits)
|
||||||
newt->size = type->size*(arraysize?arraysize:1);
|
{
|
||||||
|
if (bitsize < type->bits*(arraysize?arraysize:1))
|
||||||
|
bitsize = type->bits*(arraysize?arraysize:1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bitsize < 32*type->size*(arraysize?arraysize:1))
|
||||||
|
bitsize = 32*type->size*(arraysize?arraysize:1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ofs = newt->size;
|
if (type->bits)
|
||||||
newt->size += type->size*(arraysize?arraysize:1);
|
{
|
||||||
|
if (type->bits < type->align && type->type == ev_bitfld)
|
||||||
|
{ //only realigns when it cross its parent's alignment boundary.
|
||||||
|
if ((bitsize&(type->align-1)) + type->bits > type->align)
|
||||||
|
bitsize = (bitsize+type->align-1)&~(type->align-1); //these must be aligned, so we can take pointers etc.
|
||||||
|
}
|
||||||
|
else if (type->align)
|
||||||
|
bitsize = (bitsize+type->align-1)&~(type->align-1); //these must be aligned, so we can take pointers etc.
|
||||||
|
ofs = bitsize;
|
||||||
|
bitsize += type->bits*(arraysize?arraysize:1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bitsize = (bitsize+31)&~31; //provide padding to keep non-bitfield stuff word aligned
|
||||||
|
ofs = bitsize;
|
||||||
|
bitsize += 32 * type->size*(arraysize?arraysize:1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parms[numparms].ofs = ofs;
|
parms[numparms].ofs = ofs>>5;
|
||||||
|
parms[numparms].bitofs = ofs - (parms[numparms].ofs<<5);
|
||||||
parms[numparms].arraysize = arraysize;
|
parms[numparms].arraysize = arraysize;
|
||||||
parms[numparms].out = false;
|
parms[numparms].out = false;
|
||||||
parms[numparms].optional = false;
|
parms[numparms].optional = false;
|
||||||
|
@ -5756,7 +5872,7 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
numparms++;
|
numparms++;
|
||||||
|
|
||||||
/*if (type->type == ev_vector && arraysize == 0)
|
/*if (type->type == ev_vector && arraysize == 0)
|
||||||
{ //add in vec_x/y/z members too.
|
{ //add in vec_x/y/z members too...?
|
||||||
int c;
|
int c;
|
||||||
for (c = 0; c < 3; c++)
|
for (c = 0; c < 3; c++)
|
||||||
{
|
{
|
||||||
|
@ -5773,6 +5889,17 @@ static QCC_type_t *QCC_PR_ParseStruct(etype_t structtype)
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bitalign) //compute tail padding.
|
||||||
|
bitsize = (bitsize+bitalign-1)&~(bitalign-1);
|
||||||
|
|
||||||
|
newt->size = (bitsize+31)>>5; //FIXME: change to bytes, for pointers.
|
||||||
|
newt->align = bitalign;
|
||||||
|
if (bitalign&31)
|
||||||
|
newt->bits = bitsize;
|
||||||
|
else
|
||||||
|
newt->bits = 0; //all word aligned. nothing special going on sizewise (maybe inside though).
|
||||||
|
|
||||||
if (!numparms)
|
if (!numparms)
|
||||||
QCC_PR_ParseError(ERR_NOTANAME, "%s %s has no members", structtype==ev_union?"union":"struct", newt->name);
|
QCC_PR_ParseError(ERR_NOTANAME, "%s %s has no members", structtype==ev_union?"union":"struct", newt->name);
|
||||||
|
|
||||||
|
@ -5942,7 +6069,7 @@ QCC_type_t *QCC_PR_ParseEntClass(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
basetype = QCC_PR_ParseType(false, false);
|
basetype = QCC_PR_ParseType(false, false, false);
|
||||||
|
|
||||||
if (!basetype)
|
if (!basetype)
|
||||||
QCC_PR_ParseError(ERR_INTERNAL, "In class %s, expected type, found %s", classname, pr_token);
|
QCC_PR_ParseError(ERR_INTERNAL, "In class %s, expected type, found %s", classname, pr_token);
|
||||||
|
@ -6187,6 +6314,7 @@ QCC_type_t *QCC_PR_ParseEntClass(void)
|
||||||
|
|
||||||
parms = realloc(parms, sizeof(*parms) * (numparms+1));
|
parms = realloc(parms, sizeof(*parms) * (numparms+1));
|
||||||
parms[numparms].ofs = 0;
|
parms[numparms].ofs = 0;
|
||||||
|
parms[numparms].bitofs = 0;
|
||||||
parms[numparms].out = false;
|
parms[numparms].out = false;
|
||||||
parms[numparms].optional = false;
|
parms[numparms].optional = false;
|
||||||
parms[numparms].isvirtual = isvirt;
|
parms[numparms].isvirtual = isvirt;
|
||||||
|
@ -6376,7 +6504,7 @@ pbool type_inlinefunction;
|
||||||
/*newtype=true: creates a new type always
|
/*newtype=true: creates a new type always
|
||||||
silentfail=true: function is permitted to return NULL if it was not given a type, otherwise never returns NULL
|
silentfail=true: function is permitted to return NULL if it was not given a type, otherwise never returns NULL
|
||||||
*/
|
*/
|
||||||
QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail, pbool ignoreptr)
|
||||||
{
|
{
|
||||||
QCC_type_t *newt;
|
QCC_type_t *newt;
|
||||||
QCC_type_t *type;
|
QCC_type_t *type;
|
||||||
|
@ -6404,7 +6532,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
||||||
QCC_PR_Lex ();
|
QCC_PR_Lex ();
|
||||||
|
|
||||||
type = QCC_PR_NewType("FIELD_TYPE", ev_field, false);
|
type = QCC_PR_NewType("FIELD_TYPE", ev_field, false);
|
||||||
type->aux_type = QCC_PR_ParseType (false, false);
|
type->aux_type = QCC_PR_ParseType (false, false, ignoreptr);
|
||||||
type->size = type->aux_type->size;
|
type->size = type->aux_type->size;
|
||||||
|
|
||||||
newt = QCC_PR_FindType (type);
|
newt = QCC_PR_FindType (type);
|
||||||
|
@ -6424,7 +6552,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
||||||
if (QCC_PR_CheckToken ("..")) //so we don't end up with the user specifying '. .vector blah' (hexen2 added the .. token for array ranges)
|
if (QCC_PR_CheckToken ("..")) //so we don't end up with the user specifying '. .vector blah' (hexen2 added the .. token for array ranges)
|
||||||
{
|
{
|
||||||
newt = QCC_PR_NewType("FIELD_TYPE", ev_field, false);
|
newt = QCC_PR_NewType("FIELD_TYPE", ev_field, false);
|
||||||
newt->aux_type = QCC_PR_ParseType (false, false);
|
newt->aux_type = QCC_PR_ParseType (false, false, ignoreptr);
|
||||||
|
|
||||||
newt->size = newt->aux_type->size;
|
newt->size = newt->aux_type->size;
|
||||||
|
|
||||||
|
@ -6448,7 +6576,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
||||||
//however, we can't cope parsing that with regular types, so we support that ONLY when . was already specified.
|
//however, we can't cope parsing that with regular types, so we support that ONLY when . was already specified.
|
||||||
//this is pretty much an evil syntax hack.
|
//this is pretty much an evil syntax hack.
|
||||||
pbool ptr = QCC_PR_CheckToken ("*");
|
pbool ptr = QCC_PR_CheckToken ("*");
|
||||||
type = QCC_PR_ParseType(false, false);
|
type = QCC_PR_ParseType(false, false, ignoreptr);
|
||||||
if (!type)
|
if (!type)
|
||||||
QCC_PR_ParseError(0, "Expected type\n");
|
QCC_PR_ParseError(0, "Expected type\n");
|
||||||
if (ptr)
|
if (ptr)
|
||||||
|
@ -6496,7 +6624,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
||||||
|
|
||||||
if (QCC_PR_CheckToken(":"))
|
if (QCC_PR_CheckToken(":"))
|
||||||
{
|
{
|
||||||
type = QCC_PR_ParseType(false, false);
|
type = QCC_PR_ParseType(false, false, false);
|
||||||
if (type)
|
if (type)
|
||||||
TypeName(type, parentname, sizeof(parentname));
|
TypeName(type, parentname, sizeof(parentname));
|
||||||
else
|
else
|
||||||
|
@ -6667,9 +6795,9 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
||||||
else if (bits > 32)
|
else if (bits > 32)
|
||||||
type = (isunsigned?type_uint64:type_int64);
|
type = (isunsigned?type_uint64:type_int64);
|
||||||
else if (bits <= 8)
|
else if (bits <= 8)
|
||||||
type = (isunsigned?type_uint:type_integer), QCC_PR_ParseWarning (WARN_IGNOREDKEYWORD, "chars are not supported, using int"); //permitted
|
type = (isunsigned?type_uint8:type_sint8);
|
||||||
else if (bits <= 16)
|
else if (bits <= 16)
|
||||||
type = (isunsigned?type_uint:type_integer), QCC_PR_ParseWarning (WARN_IGNOREDKEYWORD, "shorts are not supported, using int"); //permitted
|
type = (isunsigned?type_uint16:type_sint16);
|
||||||
else
|
else
|
||||||
type = (isunsigned?type_uint:type_integer);
|
type = (isunsigned?type_uint:type_integer);
|
||||||
}
|
}
|
||||||
|
@ -6689,11 +6817,14 @@ wasctype:
|
||||||
if (!type)
|
if (!type)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (QCC_PR_CheckToken("*"))
|
if (!ignoreptr)
|
||||||
{
|
{
|
||||||
if (QCC_PR_CheckKeyword(keyword_const, "const"))
|
while (QCC_PR_CheckToken("*"))
|
||||||
QCC_PR_ParseWarning (WARN_IGNOREDKEYWORD, "ignoring unsupported const keyword");
|
{
|
||||||
type = QCC_PointerTypeTo(type);
|
if (QCC_PR_CheckKeyword(keyword_const, "const"))
|
||||||
|
QCC_PR_ParseWarning (WARN_IGNOREDKEYWORD, "ignoring unsupported const keyword");
|
||||||
|
type = QCC_PointerTypeTo(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag_qcfuncs && QCC_PR_CheckToken ("(")) //this is followed by parameters. Must be a function.
|
if (flag_qcfuncs && QCC_PR_CheckToken ("(")) //this is followed by parameters. Must be a function.
|
||||||
|
|
|
@ -1372,7 +1372,7 @@ static void QCC_FinaliseDef(QCC_def_t *def)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->symbolheader != def)
|
if (def->symbolheader != def)
|
||||||
{
|
{ //finalise the parent/root symbol first.
|
||||||
def->symbolheader->used |= def->used;
|
def->symbolheader->used |= def->used;
|
||||||
QCC_FinaliseDef(def->symbolheader);
|
QCC_FinaliseDef(def->symbolheader);
|
||||||
def->referenced = true;
|
def->referenced = true;
|
||||||
|
@ -1474,11 +1474,6 @@ static void QCC_FinaliseDef(QCC_def_t *def)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* globalspertype[def->type->type].size += def->symbolsize;
|
|
||||||
globalspertype[def->type->type].entries += 1;
|
|
||||||
globalspertype[def->type->type].vars += !def->constant;
|
|
||||||
globalspertype[def->type->type].consts += def->constant;
|
|
||||||
*/
|
|
||||||
if (def->ofs)
|
if (def->ofs)
|
||||||
{
|
{
|
||||||
if (def->symbolheader == def)
|
if (def->symbolheader == def)
|
||||||
|
@ -1529,22 +1524,41 @@ static void QCC_FinaliseDef(QCC_def_t *def)
|
||||||
def->reloc->used = true;
|
def->reloc->used = true;
|
||||||
QCC_FinaliseDef(def->reloc);
|
QCC_FinaliseDef(def->reloc);
|
||||||
if (def->type->type == ev_function/*misordered inits/copies*/ || def->type->type == ev_integer/*dp-style global index*/)
|
if (def->type->type == ev_function/*misordered inits/copies*/ || def->type->type == ev_integer/*dp-style global index*/)
|
||||||
qcc_pr_globals[def->ofs]._int += qcc_pr_globals[def->reloc->ofs]._int;
|
{
|
||||||
|
//printf("func Reloc %s %s@%i==%x -> %s@%i==%x==%s\n", def->symbolheader->name, def->name,def->ofs, def->symboldata->_int, def->reloc->name,def->reloc->ofs, def->reloc->symboldata->_int, functions[def->reloc->symboldata->_int].name);
|
||||||
|
def->symboldata->_int += def->reloc->symboldata->_int;
|
||||||
|
}
|
||||||
else if (def->type->type == ev_pointer/*signal to the engine to fix up the offset*/)
|
else if (def->type->type == ev_pointer/*signal to the engine to fix up the offset*/)
|
||||||
{
|
{
|
||||||
if (qcc_pr_globals[def->ofs]._int & 0x80000000)
|
//printf("Reloc %s %s@%i==%x -> %s@%i==%x\n", def->symbolheader->name, def->name,def->ofs, def->symboldata->_int, def->reloc->name,def->reloc->ofs, def->symboldata->_int+def->reloc->ofs*VMWORDSIZE);
|
||||||
QCC_Error(ERR_INTERNAL, "dupe reloc, type... %s", def->type->name);
|
if (def->symboldata->_int & 0x80000000)
|
||||||
else if (flag_undefwordsize)
|
QCC_PR_ParseWarning(0, "dupe reloc, %s", def->type->name);
|
||||||
QCC_PR_ParseWarning(ERR_BADEXTENSION, "pointer relocs are disabled for this target.");
|
else
|
||||||
qcc_pr_globals[def->ofs]._int += def->reloc->ofs;
|
{
|
||||||
qcc_pr_globals[def->ofs]._int *= VMWORDSIZE;
|
if (flag_undefwordsize)
|
||||||
|
QCC_PR_ParseWarning(ERR_BADEXTENSION, "pointer relocs are disabled for this target.");
|
||||||
|
def->symboldata->_int += def->reloc->ofs*VMWORDSIZE;
|
||||||
|
|
||||||
qcc_pr_globals[def->ofs]._int |= 0x80000000;
|
def->symboldata->_int |= 0x80000000; //we're using this as a hint to the engine to let it know that there's no dupes.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
QCC_Error(ERR_INTERNAL, "unknown reloc type... %s", def->type->name);
|
QCC_Error(ERR_INTERNAL, "unknown reloc type... %s", def->type->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QCC_def_t *prev, *sub;
|
||||||
|
for (prev = def, sub = prev->next; sub && prev != def->deftail; sub = (prev=sub)->next)
|
||||||
|
{
|
||||||
|
if (sub->reloc && !sub->used)
|
||||||
|
{ //make sure any children are finalised properly if they're relocs.
|
||||||
|
sub->used = true;
|
||||||
|
sub->referenced = true;
|
||||||
|
QCC_FinaliseDef(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DUMP_GLOBALMAP
|
#ifdef DEBUG_DUMP_GLOBALMAP
|
||||||
if (!def->referenced)
|
if (!def->referenced)
|
||||||
externs->Printf("Unreferenced ");
|
externs->Printf("Unreferenced ");
|
||||||
|
@ -2160,7 +2174,7 @@ static pbool QCC_WriteData (int crc)
|
||||||
if (def->symbolheader->used)
|
if (def->symbolheader->used)
|
||||||
{
|
{
|
||||||
char typestr[256];
|
char typestr[256];
|
||||||
QCC_sref_t sr = {def, 0, def->type};
|
QCC_sref_t sr = {def, {0}, def->type};
|
||||||
QCC_PR_Warning(WARN_NOTREFERENCED, def->filen, def->s_line, "%s %s%s%s = %s used, but not referenced.", TypeName(def->type, typestr, sizeof(typestr)), col_symbol, def->name, col_none, QCC_VarAtOffset(sr));
|
QCC_PR_Warning(WARN_NOTREFERENCED, def->filen, def->s_line, "%s %s%s%s = %s used, but not referenced.", TypeName(def->type, typestr, sizeof(typestr)), col_symbol, def->name, col_none, QCC_VarAtOffset(sr));
|
||||||
}
|
}
|
||||||
/*if (opt_unreferenced && def->type->type != ev_field)
|
/*if (opt_unreferenced && def->type->type != ev_field)
|
||||||
|
@ -2224,7 +2238,7 @@ static pbool QCC_WriteData (int crc)
|
||||||
def->name = ""; //reloc, can't strip it (engine needs to fix em up), but can clear its name.
|
def->name = ""; //reloc, can't strip it (engine needs to fix em up), but can clear its name.
|
||||||
else if (def->scope && !def->scope->privatelocals && !def->isstatic)
|
else if (def->scope && !def->scope->privatelocals && !def->isstatic)
|
||||||
continue; //def is a local, which got shared and should be 0...
|
continue; //def is a local, which got shared and should be 0...
|
||||||
else if ((def->scope||def->constant||flag_noreflection) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings)))
|
else if ((def->scope||def->constant||(flag_noreflection&&strncmp(def->name, "autocvar_", 9))) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings)))
|
||||||
{
|
{
|
||||||
if (opt_constant_names)
|
if (opt_constant_names)
|
||||||
{
|
{
|
||||||
|
@ -3580,6 +3594,7 @@ QCC_type_t *QCC_PR_NewType (const char *name, int basictype, pbool typedefed)
|
||||||
qcc_typeinfo[numtypeinfos].params = NULL;
|
qcc_typeinfo[numtypeinfos].params = NULL;
|
||||||
qcc_typeinfo[numtypeinfos].size = type_size[basictype];
|
qcc_typeinfo[numtypeinfos].size = type_size[basictype];
|
||||||
qcc_typeinfo[numtypeinfos].typedefed = typedefed;
|
qcc_typeinfo[numtypeinfos].typedefed = typedefed;
|
||||||
|
qcc_typeinfo[numtypeinfos].align = 32; //assume this alignment for now. some types allow tighter alignment, though mostly only in structs.
|
||||||
|
|
||||||
qcc_typeinfo[numtypeinfos].filen = s_filen;
|
qcc_typeinfo[numtypeinfos].filen = s_filen;
|
||||||
qcc_typeinfo[numtypeinfos].line = pr_source_line;
|
qcc_typeinfo[numtypeinfos].line = pr_source_line;
|
||||||
|
@ -3621,22 +3636,27 @@ static void QCC_PR_BeginCompilation (void *memory, int memsize)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type_void = QCC_PR_NewType("void", ev_void, true);
|
type_void = QCC_PR_NewType("void", ev_void, true);
|
||||||
type_string = QCC_PR_NewType("string", ev_string, true);
|
type_string = QCC_PR_NewType(flag_qcfuncs?"string":"__string", ev_string, true);
|
||||||
type_float = QCC_PR_NewType("float", ev_float, true);
|
type_float = QCC_PR_NewType("float", ev_float, true);
|
||||||
type_double = QCC_PR_NewType("__double", ev_double, true);
|
type_double = QCC_PR_NewType("__double", ev_double, true);
|
||||||
type_vector = QCC_PR_NewType("vector", ev_vector, true);
|
type_vector = QCC_PR_NewType(flag_qcfuncs?"vector":"__vector", ev_vector, true);
|
||||||
type_entity = QCC_PR_NewType("entity", ev_entity, true);
|
type_entity = QCC_PR_NewType(flag_qcfuncs?"entity":"__entity", ev_entity, true);
|
||||||
type_field = QCC_PR_NewType("__field", ev_field, false);
|
type_field = QCC_PR_NewType("__field", ev_field, false);
|
||||||
type_field->aux_type = type_void;
|
type_field->aux_type = type_void;
|
||||||
type_function = QCC_PR_NewType("__function", ev_function, false);
|
type_function = QCC_PR_NewType("__function", ev_function, false);
|
||||||
type_function->aux_type = type_void;
|
type_function->aux_type = type_void;
|
||||||
type_pointer = QCC_PR_NewType("__pointer", ev_pointer, false);
|
type_pointer = QCC_PR_NewType("__pointer", ev_pointer, false);
|
||||||
type_integer = QCC_PR_NewType("__int", ev_integer, true);
|
type_integer = QCC_PR_NewType("__int32", ev_integer, true);
|
||||||
type_uint = QCC_PR_NewType("__uint", ev_uint, true);
|
type_uint = QCC_PR_NewType("__uint32", ev_uint, true);
|
||||||
type_int64 = QCC_PR_NewType("__int64", ev_int64, true);
|
type_int64 = QCC_PR_NewType("__int64", ev_int64, true);
|
||||||
type_uint64 = QCC_PR_NewType("__uint64", ev_uint64, true);
|
type_uint64 = QCC_PR_NewType("__uint64", ev_uint64, true);
|
||||||
type_variant = QCC_PR_NewType("__variant", ev_variant, true);
|
type_variant = QCC_PR_NewType("__variant", ev_variant, true);
|
||||||
|
|
||||||
|
type_sint8 = QCC_PR_NewType("__int8", ev_bitfld, true); type_sint8 ->parentclass = type_integer; type_sint8 ->size = type_sint8 ->parentclass->size; type_sint8 ->align = type_sint8 ->bits = 8;
|
||||||
|
type_uint8 = QCC_PR_NewType("__uint8", ev_bitfld, true); type_uint8 ->parentclass = type_uint; type_uint8 ->size = type_uint8 ->parentclass->size; type_uint8 ->align = type_uint8 ->bits = 8;
|
||||||
|
type_sint16 = QCC_PR_NewType("__int16", ev_bitfld, true); type_sint16->parentclass = type_integer; type_sint16->size = type_sint16->parentclass->size; type_sint16->align = type_sint16->bits = 16;
|
||||||
|
type_uint16 = QCC_PR_NewType("__uint16", ev_bitfld, true); type_uint16->parentclass = type_uint; type_uint16->size = type_uint16->parentclass->size; type_uint16->align = type_uint16->bits = 16;
|
||||||
|
|
||||||
type_invalid = QCC_PR_NewType("invalid", ev_void, false);
|
type_invalid = QCC_PR_NewType("invalid", ev_void, false);
|
||||||
|
|
||||||
type_floatfield = QCC_PR_NewType("__fieldfloat", ev_field, false);
|
type_floatfield = QCC_PR_NewType("__fieldfloat", ev_field, false);
|
||||||
|
@ -3650,10 +3670,8 @@ static void QCC_PR_BeginCompilation (void *memory, int memsize)
|
||||||
type_floatfunction = QCC_PR_NewType("__floatfunction", ev_function, false);
|
type_floatfunction = QCC_PR_NewType("__floatfunction", ev_function, false);
|
||||||
type_floatfunction->aux_type = type_float;
|
type_floatfunction->aux_type = type_float;
|
||||||
|
|
||||||
type_bfloat = QCC_PR_NewType("__bfloat", ev_boolean, true);
|
type_bfloat = QCC_PR_NewType("__bfloat", ev_boolean, true); type_bfloat->parentclass = type_float; //has value 0.0 or 1.0
|
||||||
type_bfloat->parentclass = type_float;
|
type_bint = QCC_PR_NewType("__bint", ev_boolean, true); type_bint->parentclass = type_uint; //has value 0 or 1
|
||||||
type_bint = QCC_PR_NewType("__bint", ev_boolean, true);
|
|
||||||
type_bint->parentclass = type_uint;
|
|
||||||
|
|
||||||
//type_field->aux_type = type_float;
|
//type_field->aux_type = type_float;
|
||||||
|
|
||||||
|
@ -3662,6 +3680,11 @@ static void QCC_PR_BeginCompilation (void *memory, int memsize)
|
||||||
// QCC_PR_NewType("__int", ev_integer, keyword_integer?true:false);
|
// QCC_PR_NewType("__int", ev_integer, keyword_integer?true:false);
|
||||||
|
|
||||||
QCC_PR_NewType("variant", ev_variant, true);
|
QCC_PR_NewType("variant", ev_variant, true);
|
||||||
|
if (*type_string->name != '_') QCC_PR_NewType("__string", ev_string, true); //make sure some core types __string always work with a double-underscore prefix
|
||||||
|
if (*type_vector->name != '_') QCC_PR_NewType("__vector", ev_vector, true); //make sure some core types __string always work with a double-underscore prefix
|
||||||
|
if (*type_entity->name != '_') QCC_PR_NewType("__entity", ev_entity, true); //make sure some core types __string always work with a double-underscore prefix
|
||||||
|
QCC_PR_NewType("__int", ev_integer, true);
|
||||||
|
QCC_PR_NewType("__uint", ev_uint, true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -4684,6 +4707,7 @@ static void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
flag_assume_double = true; //and any immediates with a decimal points are assumed to be doubles, consistent with C.
|
flag_assume_double = true; //and any immediates with a decimal points are assumed to be doubles, consistent with C.
|
||||||
flag_qcfuncs = false; //there's a few parsing quirks where our attempt to parse qc functions will misparse valid C.
|
flag_qcfuncs = false; //there's a few parsing quirks where our attempt to parse qc functions will misparse valid C.
|
||||||
flag_macroinstrings = false;//hacky preqcc hack.
|
flag_macroinstrings = false;//hacky preqcc hack.
|
||||||
|
flag_boundchecks = false; //nope... not C's style.
|
||||||
|
|
||||||
qccwarningaction[WARN_UNINITIALIZED] = WA_WARN; //C doesn't like that, might as well warn here too.
|
qccwarningaction[WARN_UNINITIALIZED] = WA_WARN; //C doesn't like that, might as well warn here too.
|
||||||
qccwarningaction[WARN_TOOMANYPARAMS] = WA_ERROR; //too many args to function is weeeeird.
|
qccwarningaction[WARN_TOOMANYPARAMS] = WA_ERROR; //too many args to function is weeeeird.
|
||||||
|
@ -4706,6 +4730,8 @@ static void QCC_PR_CommandLinePrecompilerOptions (void)
|
||||||
val = "201112L";
|
val = "201112L";
|
||||||
else if (!stricmp(myargv[i]+5, "c17"))
|
else if (!stricmp(myargv[i]+5, "c17"))
|
||||||
val = "201710L";
|
val = "201710L";
|
||||||
|
else if (!stricmp(myargv[i]+5, "c23"))
|
||||||
|
val = "202311L";
|
||||||
else
|
else
|
||||||
val = NULL;
|
val = NULL;
|
||||||
cnst = QCC_PR_DefineName("__STDC_VERSION__");
|
cnst = QCC_PR_DefineName("__STDC_VERSION__");
|
||||||
|
@ -5448,7 +5474,7 @@ pbool QCC_main (int argc, const char **argv) //as part of the quake engine
|
||||||
|
|
||||||
for (p = 0; compiler_flag[p].enabled; p++)
|
for (p = 0; compiler_flag[p].enabled; p++)
|
||||||
{
|
{
|
||||||
*compiler_flag[p].enabled = compiler_flag[p].flags & FLAG_ASDEFAULT;
|
*compiler_flag[p].enabled = !!(compiler_flag[p].flags & FLAG_ASDEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseonly = autoprototyped = autoprototype = false;
|
parseonly = autoprototyped = autoprototype = false;
|
||||||
|
|
|
@ -13418,8 +13418,8 @@ void PR_DumpPlatform_f(void)
|
||||||
#define globalfloat(need,name) {#name, "float", QW|NQ, "ssqc global"},
|
#define globalfloat(need,name) {#name, "float", QW|NQ, "ssqc global"},
|
||||||
#define globalentity(need,name) {#name, "entity", QW|NQ, "ssqc global"},
|
#define globalentity(need,name) {#name, "entity", QW|NQ, "ssqc global"},
|
||||||
#define globalint(need,name) {#name, "int", QW|NQ, "ssqc global"},
|
#define globalint(need,name) {#name, "int", QW|NQ, "ssqc global"},
|
||||||
#define globaluint(need,name) {#name, "unsigned int", QW|NQ, "ssqc global"},
|
#define globaluint(need,name) {#name, "__uint", QW|NQ, "ssqc global"},
|
||||||
#define globaluint64(need,name) {#name, "unsigned __long", QW|NQ, "ssqc global"},
|
#define globaluint64(need,name) {#name, "__uint64", QW|NQ, "ssqc global"},
|
||||||
#define globalstring(need,name) {#name, "string", QW|NQ, "ssqc global"},
|
#define globalstring(need,name) {#name, "string", QW|NQ, "ssqc global"},
|
||||||
#define globalvec(need,name) {#name, "vector", QW|NQ, "ssqc global"},
|
#define globalvec(need,name) {#name, "vector", QW|NQ, "ssqc global"},
|
||||||
#define globalfunc(need,name,typestr) {#name, typestr, QW|NQ, "ssqc global"},
|
#define globalfunc(need,name,typestr) {#name, typestr, QW|NQ, "ssqc global"},
|
||||||
|
@ -13440,8 +13440,8 @@ void PR_DumpPlatform_f(void)
|
||||||
#define globalvector(name) {#name, "vector", CS},
|
#define globalvector(name) {#name, "vector", CS},
|
||||||
#define globalstring(name) {#name, "string", CS},
|
#define globalstring(name) {#name, "string", CS},
|
||||||
#define globalint(name) {#name, "int", CS},
|
#define globalint(name) {#name, "int", CS},
|
||||||
#define globaluint(name) {#name, "unsigned int", CS},
|
#define globaluint(name) {#name, "__uint", CS},
|
||||||
#define globaluint64(name) {#name, "unsigned __long", CS},
|
#define globaluint64(name) {#name, "__uint64", CS},
|
||||||
csqcglobals
|
csqcglobals
|
||||||
#undef globalfunction
|
#undef globalfunction
|
||||||
#undef globalfloat
|
#undef globalfloat
|
||||||
|
|
Loading…
Reference in a new issue