bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap) { const char *msgtype = "warning"; int lvl = LVL_WARNING; char warn_name[1024]; if (!OPTS_WARN(warntype)) return false; warn_name[0] = '-'; warn_name[1] = 'W'; (void)util_strtononcmd(opts_warn_list[warntype].name, warn_name+2, sizeof(warn_name)-2); ++compile_warnings; if (OPTS_WERROR(warntype)) { if (!compile_Werrors) first_werror = ctx; ++compile_Werrors; msgtype = "Werror"; if (OPTS_FLAG(BAIL_ON_WERROR)) { msgtype = "error"; ++compile_errors; } lvl = LVL_ERROR; } con_vprintmsg_c(lvl, ctx.file, ctx.line, ctx.column, msgtype, fmt, ap, warn_name); return OPTS_WERROR(warntype) && OPTS_FLAG(BAIL_ON_WERROR); }
static GMQCC_INLINE bool fold_immediate_true(fold_t *fold, ast_value *v) { switch (v->expression.vtype) { case TYPE_FLOAT: return !!v->constval.vfloat; case TYPE_INTEGER: return !!v->constval.vint; case TYPE_VECTOR: if (OPTS_FLAG(CORRECT_LOGIC)) return vec3_pbool(v->constval.vvec); return !!(v->constval.vvec.x); case TYPE_STRING: if (!v->constval.vstring) return false; if (OPTS_FLAG(TRUE_EMPTY_STRINGS)) return true; return !!v->constval.vstring[0]; default: compile_error(fold_ctx(fold), "internal error: fold_immediate_true on invalid type"); break; } return !!v->constval.vfunc; }
static GMQCC_INLINE ast_expression *fold_op_not(fold_t *fold, ast_value *a) { if (isfloat(a)) { if (fold_can_1(a)) return fold_constgen_float(fold, !fold_immvalue_float(a)); } else if (isvector(a)) { if (fold_can_1(a)) return fold_constgen_float(fold, vec3_notf(fold_immvalue_vector(a))); } else if (isstring(a)) { if (fold_can_1(a)) { if (OPTS_FLAG(TRUE_EMPTY_STRINGS)) return fold_constgen_float(fold, !fold_immvalue_string(a)); else return fold_constgen_float(fold, !fold_immvalue_string(a) || !*fold_immvalue_string(a)); } } return NULL; }
static GMQCC_INLINE ast_expression *fold_op_andor(fold_t *fold, ast_value *a, ast_value *b, float expr) { if (fold_can_2(a, b)) { if (OPTS_FLAG(PERL_LOGIC)) { if (expr) return (fold_immediate_true(fold, a)) ? (ast_expression*)a : (ast_expression*)b; else return (fold_immediate_true(fold, a)) ? (ast_expression*)b : (ast_expression*)a; } else { return fold_constgen_float ( fold, ((expr) ? (fold_immediate_true(fold, a) || fold_immediate_true(fold, b)) : (fold_immediate_true(fold, a) && fold_immediate_true(fold, b))) ? 1 : 0 ); } } return NULL; }
void code_push_statement(code_t *code, prog_section_statement_t *stmt_in, lex_ctx_t ctx) { prog_section_statement_t stmt = *stmt_in; if (OPTS_FLAG(TYPELESS_STORES)) { switch (stmt.opcode) { case INSTR_LOAD_S: case INSTR_LOAD_ENT: case INSTR_LOAD_FLD: case INSTR_LOAD_FNC: stmt.opcode = INSTR_LOAD_F; break; case INSTR_STORE_S: case INSTR_STORE_ENT: case INSTR_STORE_FLD: case INSTR_STORE_FNC: stmt.opcode = INSTR_STORE_F; break; case INSTR_STOREP_S: case INSTR_STOREP_ENT: case INSTR_STOREP_FLD: case INSTR_STOREP_FNC: stmt.opcode = INSTR_STOREP_F; break; } } if (OPTS_FLAG(SORT_OPERANDS)) { uint16_t pair; switch (stmt.opcode) { case INSTR_MUL_F: case INSTR_MUL_V: case INSTR_ADD_F: case INSTR_EQ_F: case INSTR_EQ_S: case INSTR_EQ_E: case INSTR_EQ_FNC: case INSTR_NE_F: case INSTR_NE_V: case INSTR_NE_S: case INSTR_NE_E: case INSTR_NE_FNC: case INSTR_AND: case INSTR_OR: case INSTR_BITAND: case INSTR_BITOR: if (stmt.o1.u1 < stmt.o2.u1) { uint16_t a = stmt.o2.u1; stmt.o1.u1 = stmt.o2.u1; stmt.o2.u1 = a; } break; case INSTR_MUL_VF: pair = INSTR_MUL_FV; goto case_pair_gen; case INSTR_MUL_FV: pair = INSTR_MUL_VF; goto case_pair_gen; case INSTR_LT: pair = INSTR_GT; goto case_pair_gen; case INSTR_GT: pair = INSTR_LT; goto case_pair_gen; case INSTR_LE: pair = INSTR_GT; goto case_pair_gen; case INSTR_GE: pair = INSTR_LE; case_pair_gen: if (stmt.o1.u1 < stmt.o2.u1) { uint16_t x = stmt.o1.u1; stmt.o1.u1 = stmt.o2.u1; stmt.o2.u1 = x; stmt.opcode = pair; } break; } } vec_push(code->statements, stmt); vec_push(code->linenums, (int)ctx.line); vec_push(code->columnnums, (int)ctx.column); }
static void code_create_header(code_t *code, prog_header_t *code_header, const char *filename, const char *lnofile) { size_t i; code_header->statements.offset = sizeof(prog_header_t); code_header->statements.length = vec_size(code->statements); code_header->defs.offset = code_header->statements.offset + (sizeof(prog_section_statement_t) * vec_size(code->statements)); code_header->defs.length = vec_size(code->defs); code_header->fields.offset = code_header->defs.offset + (sizeof(prog_section_def_t) * vec_size(code->defs)); code_header->fields.length = vec_size(code->fields); code_header->functions.offset = code_header->fields.offset + (sizeof(prog_section_field_t) * vec_size(code->fields)); code_header->functions.length = vec_size(code->functions); code_header->globals.offset = code_header->functions.offset + (sizeof(prog_section_function_t) * vec_size(code->functions)); code_header->globals.length = vec_size(code->globals); code_header->strings.offset = code_header->globals.offset + (sizeof(int32_t) * vec_size(code->globals)); code_header->strings.length = vec_size(code->chars); code_header->version = 6; code_header->skip = 0; if (OPTS_OPTION_BOOL(OPTION_FORCECRC)) code_header->crc16 = OPTS_OPTION_U16(OPTION_FORCED_CRC); else code_header->crc16 = code->crc; code_header->entfield = code->entfields; if (OPTS_FLAG(DARKPLACES_STRING_TABLE_BUG)) { /* >= + P */ vec_push(code->chars, '\0'); /* > */ vec_push(code->chars, '\0'); /* = */ vec_push(code->chars, '\0'); /* P */ } /* ensure all data is in LE format */ util_swap_header(code_header); /* * These are not part of the header but we ensure LE format here to save on duplicated * code. */ util_swap_statements (code->statements); util_swap_defs_fields(code->defs); util_swap_defs_fields(code->fields); util_swap_functions (code->functions); util_swap_globals (code->globals); if (!OPTS_OPTION_BOOL(OPTION_QUIET)) { if (lnofile) con_out("writing '%s' and '%s'...\n", filename, lnofile); else con_out("writing '%s'\n", filename); } if (!OPTS_OPTION_BOOL(OPTION_QUIET) && !OPTS_OPTION_BOOL(OPTION_PP_ONLY)) { char buffer[1024]; con_out("\nOptimizations:\n"); for (i = 0; i < COUNT_OPTIMIZATIONS; ++i) { if (opts_optimizationcount[i]) { util_optimizationtostr(opts_opt_list[i].name, buffer, sizeof(buffer)); con_out( " %s: %u\n", buffer, (unsigned int)opts_optimizationcount[i] ); } } } }