2022-12-29 12:32:55 +00:00
|
|
|
#include "compiler/uDump.h"
|
|
|
|
#include "compiler/CFunc.h"
|
|
|
|
#include "compiler/CInt64.h"
|
|
|
|
#include "compiler/CMachine.h"
|
|
|
|
#include "compiler/CMangler.h"
|
2023-01-14 13:20:48 +00:00
|
|
|
#include "compiler/CParser.h"
|
2022-12-29 12:32:55 +00:00
|
|
|
#include "compiler/Exceptions.h"
|
|
|
|
#include "compiler/Switch.h"
|
|
|
|
#include "compiler/enode.h"
|
|
|
|
#include "compiler/objects.h"
|
|
|
|
#include "compiler/types.h"
|
|
|
|
|
|
|
|
static FILE *outfile;
|
|
|
|
|
|
|
|
// forward decls
|
|
|
|
static void spell(Type *type, char *buf);
|
|
|
|
|
|
|
|
static void WritePString(FILE *file, char *str, int len) {
|
|
|
|
while (len--) {
|
|
|
|
switch (*str) {
|
|
|
|
case 0:
|
|
|
|
fputs("\\x00", file);
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
fputs("\\a", file);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
fputs("\\b", file);
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
fputs("\\f", file);
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
fputs("\\n", file);
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
fputs("\\r", file);
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
fputs("\\t", file);
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
fputs("\\v", file);
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
case '\'':
|
|
|
|
case '?':
|
|
|
|
case '\\':
|
|
|
|
fputc('\\', file);
|
|
|
|
default:
|
|
|
|
fputc(*str, file);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WriteCString(FILE *file, char *str) {
|
|
|
|
WritePString(file, str, strlen(str));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void StaticSetupDumpIR(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetupDumpIR(void) {
|
|
|
|
// unknown args
|
|
|
|
StaticSetupDumpIR();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CleanupDumpIR(void) {
|
2023-01-19 13:00:09 +00:00
|
|
|
#ifdef CW_ENABLE_PCODE_DEBUG
|
2023-01-14 13:20:48 +00:00
|
|
|
// this code is not based on the original as we don't have it
|
|
|
|
if (outfile) {
|
|
|
|
fclose(outfile);
|
|
|
|
outfile = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2022-12-29 12:32:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DumpIR(Statement *statements, Object *func) {
|
2023-01-19 13:00:09 +00:00
|
|
|
#ifdef CW_ENABLE_PCODE_DEBUG
|
2023-01-14 13:20:48 +00:00
|
|
|
// this code is not based on the original as we don't have it
|
|
|
|
if (copts.debuglisting) {
|
|
|
|
if (!outfile)
|
|
|
|
outfile = fopen("irdump.txt", "a");
|
|
|
|
|
|
|
|
fputs("--- BEGIN IR DUMP ---\r", outfile);
|
|
|
|
while (statements) {
|
|
|
|
switch (statements->type) {
|
|
|
|
case ST_NOP:
|
|
|
|
fputs("ST_NOP\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_LABEL:
|
|
|
|
fputs("ST_LABEL\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_GOTO:
|
|
|
|
fputs("ST_GOTO\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_EXPRESSION:
|
|
|
|
fputs("ST_EXPRESSION\r", outfile);
|
|
|
|
DumpExpression(statements->expr, 1);
|
|
|
|
break;
|
|
|
|
case ST_SWITCH:
|
|
|
|
fputs("ST_SWITCH\r", outfile);
|
|
|
|
DumpExpression(statements->expr, 1);
|
|
|
|
break;
|
|
|
|
case ST_IFGOTO:
|
|
|
|
fputs("ST_IFGOTO\r", outfile);
|
|
|
|
DumpExpression(statements->expr, 1);
|
|
|
|
break;
|
|
|
|
case ST_IFNGOTO:
|
|
|
|
fputs("ST_IFNGOTO\r", outfile);
|
|
|
|
DumpExpression(statements->expr, 1);
|
|
|
|
break;
|
|
|
|
case ST_RETURN:
|
|
|
|
fputs("ST_RETURN\r", outfile);
|
|
|
|
if (statements->expr)
|
|
|
|
DumpExpression(statements->expr, 1);
|
|
|
|
break;
|
|
|
|
case ST_OVF:
|
|
|
|
fputs("ST_OVF\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_EXIT:
|
|
|
|
fputs("ST_EXIT\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_ENTRY:
|
|
|
|
fputs("ST_ENTRY\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_BEGINCATCH:
|
|
|
|
fputs("ST_BEGINCATCH\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_ENDCATCH:
|
|
|
|
fputs("ST_ENDCATCH\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_ENDCATCHDTOR:
|
|
|
|
fputs("ST_ENDCATCHDTOR\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_GOTOEXPR:
|
|
|
|
fputs("ST_GOTOEXPR\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_ASM:
|
|
|
|
fputs("ST_ASM\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_BEGINLOOP:
|
|
|
|
fputs("ST_BEGINLOOP\r", outfile);
|
|
|
|
break;
|
|
|
|
case ST_ENDLOOP:
|
|
|
|
fputs("ST_ENDLOOP\r", outfile);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
statements = statements->next;
|
|
|
|
}
|
|
|
|
fputs("--- END IR DUMP ---\r", outfile);
|
|
|
|
fflush(outfile);
|
|
|
|
}
|
|
|
|
#endif
|
2022-12-29 12:32:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DumpExpression(ENode *expr, int indent) {
|
|
|
|
static int bt;
|
|
|
|
static int i;
|
|
|
|
static char *nodenames[] = {
|
|
|
|
"EPOSTINC",
|
|
|
|
"EPOSTDEC",
|
|
|
|
"EPREINC",
|
|
|
|
"EPREDEC",
|
|
|
|
"EINDIRECT",
|
|
|
|
"EMONMIN",
|
|
|
|
"EBINNOT",
|
|
|
|
"ELOGNOT",
|
|
|
|
"EFORCELOAD",
|
|
|
|
"EMUL",
|
|
|
|
"EMULV",
|
|
|
|
"EDIV",
|
|
|
|
"EMODULO",
|
|
|
|
"EADDV",
|
|
|
|
"ESUBV",
|
|
|
|
"EADD",
|
|
|
|
"ESUB",
|
|
|
|
"ESHL",
|
|
|
|
"ESHR",
|
|
|
|
"ELESS",
|
|
|
|
"EGREATER",
|
|
|
|
"ELESSEQU",
|
|
|
|
"EGREATEREQU",
|
|
|
|
"EEQU",
|
|
|
|
"ENOTEQU",
|
|
|
|
"EAND",
|
|
|
|
"EXOR",
|
|
|
|
"EOR",
|
|
|
|
"ELAND",
|
|
|
|
"ELOR",
|
|
|
|
"EASS",
|
|
|
|
"EMULASS",
|
|
|
|
"EDIVASS",
|
|
|
|
"EMODASS",
|
|
|
|
"EADDASS",
|
|
|
|
"ESUBASS",
|
|
|
|
"ESHLASS",
|
|
|
|
"ESHRASS",
|
|
|
|
"EANDASS",
|
|
|
|
"EXORASS",
|
|
|
|
"EORASS",
|
|
|
|
"ECOMMA",
|
|
|
|
"EPMODULO",
|
|
|
|
"EROTL",
|
|
|
|
"EROTR",
|
|
|
|
"EBCLR",
|
|
|
|
"EBTST",
|
|
|
|
"EBSET",
|
|
|
|
"ETYPCON",
|
|
|
|
"EBITFIELD",
|
|
|
|
"EINTCONST",
|
|
|
|
"EFLOATCONST",
|
|
|
|
"ESTRINGCONST",
|
|
|
|
"ECOND",
|
|
|
|
"EFUNCCALL",
|
|
|
|
"EFUNCCALLP",
|
|
|
|
"EOBJREF",
|
|
|
|
"EMFPOINTER",
|
|
|
|
"ENULLCHECK",
|
|
|
|
"EPRECOMP",
|
|
|
|
"ETEMP",
|
|
|
|
"EARGOBJ",
|
|
|
|
"ELOCOBJ",
|
|
|
|
"ELABEL",
|
|
|
|
"ESETCONST",
|
|
|
|
"ENEWEXCEPTION",
|
|
|
|
"ENEWEXCEPTIONARRAY",
|
|
|
|
"EINITTRYCATCH",
|
|
|
|
"EOBJLIST",
|
|
|
|
"EMEMBER",
|
|
|
|
"ETEMPLDEP",
|
|
|
|
"EINSTRUCTION",
|
|
|
|
"EDEFINE",
|
|
|
|
"EREUSE",
|
|
|
|
"EASSBLK",
|
|
|
|
"EVECTOR128CONST",
|
|
|
|
"ECONDASS",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
char buf[64];
|
|
|
|
ENodeList *list;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
for (i = 0; i < indent; i++)
|
|
|
|
fputc('\t', outfile);
|
|
|
|
|
|
|
|
if (expr->flags)
|
|
|
|
fprintf(outfile, "%s {%02X}", nodenames[expr->type], expr->flags);
|
|
|
|
else
|
|
|
|
fprintf(outfile, "%s", nodenames[expr->type]);
|
|
|
|
|
|
|
|
switch (expr->type) {
|
|
|
|
case EINTCONST:
|
2023-01-14 13:20:48 +00:00
|
|
|
if (expr->rtype->size > 4) {
|
|
|
|
fprintf(outfile,
|
|
|
|
"[0x%.8" PRIX32 "%.8" PRIX32 "]",
|
|
|
|
expr->data.intval.hi, expr->data.intval.lo);
|
|
|
|
} else {
|
|
|
|
fprintf(outfile,
|
|
|
|
"[%" PRId32 "]",
|
|
|
|
expr->data.intval.lo);
|
|
|
|
}
|
2022-12-29 12:32:55 +00:00
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EFLOATCONST:
|
|
|
|
CMach_PrintFloat(buf, expr->data.floatval);
|
|
|
|
fprintf(outfile, "[%s]", buf);
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case ESTRINGCONST:
|
|
|
|
if (expr->data.string.ispascal) {
|
|
|
|
fputs("[\"", outfile);
|
|
|
|
WritePString(outfile, expr->data.string.data, expr->data.string.size);
|
|
|
|
fputs("\"]", outfile);
|
|
|
|
} else {
|
|
|
|
fputs("[\"", outfile);
|
|
|
|
WriteCString(outfile, expr->data.string.data);
|
|
|
|
fputs("\"]", outfile);
|
|
|
|
}
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EVECTOR128CONST:
|
2023-01-14 13:20:48 +00:00
|
|
|
fprintf(outfile,
|
|
|
|
"[0x%.8" PRIX32 "%.8" PRIX32 "%.8" PRIX32 "%.8" PRIX32 "]",
|
2022-12-29 12:32:55 +00:00
|
|
|
expr->data.vector128val.ul[0],
|
|
|
|
expr->data.vector128val.ul[1],
|
|
|
|
expr->data.vector128val.ul[2],
|
|
|
|
expr->data.vector128val.ul[3]);
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case ECOND:
|
|
|
|
case ECONDASS:
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
DumpExpression(expr->data.cond.cond, indent + 1);
|
|
|
|
DumpExpression(expr->data.cond.expr1, indent + 1);
|
|
|
|
expr = expr->data.cond.expr2;
|
|
|
|
indent++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EFUNCCALL:
|
|
|
|
case EFUNCCALLP:
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
DumpExpression(expr->data.funccall.funcref, indent + 1);
|
|
|
|
for (list = expr->data.funccall.args; list; list = list->next)
|
|
|
|
DumpExpression(list->node, indent + 1);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EOBJREF:
|
|
|
|
switch (expr->data.objref->datatype) {
|
|
|
|
case DFUNC:
|
|
|
|
fprintf(outfile, "[%s{PR}]", CMangler_GetLinkName(expr->data.objref)->name);
|
|
|
|
break;
|
|
|
|
case DDATA:
|
|
|
|
fprintf(outfile, "[%s{RW}]", CMangler_GetLinkName(expr->data.objref)->name);
|
|
|
|
break;
|
|
|
|
case DNONLAZYPTR:
|
|
|
|
fprintf(outfile, "[%s{NL}]", CMangler_GetLinkName(expr->data.objref)->name);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(outfile, "[%s]", expr->data.objref->name->name);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
ENODE_CASE_DIADIC_1:
|
|
|
|
case ELAND:
|
|
|
|
case ELOR:
|
|
|
|
ENODE_CASE_ASSIGN:
|
|
|
|
case ECOMMA:
|
|
|
|
case EPMODULO:
|
|
|
|
case EROTL:
|
|
|
|
case EROTR:
|
|
|
|
case EBTST:
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
DumpExpression(expr->data.diadic.left, indent + 1);
|
|
|
|
expr = expr->data.diadic.right;
|
|
|
|
indent++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
ENODE_CASE_MONADIC:
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
expr = expr->data.monadic;
|
|
|
|
indent++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EMFPOINTER:
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
DumpExpression(expr->data.mfpointer.accessnode, indent + 1);
|
|
|
|
expr = expr->data.mfpointer.mfpointer;
|
|
|
|
indent++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ENULLCHECK:
|
2023-01-14 13:20:48 +00:00
|
|
|
fprintf(outfile, " unique [%" PRId32 "]", expr->data.nullcheck.precompid);
|
2022-12-29 12:32:55 +00:00
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
DumpExpression(expr->data.nullcheck.nullcheckexpr, indent + 1);
|
|
|
|
expr = expr->data.nullcheck.condexpr;
|
|
|
|
indent++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EPRECOMP:
|
2023-01-14 13:20:48 +00:00
|
|
|
fprintf(outfile, " unique [%" PRId32 "]", expr->data.precompid);
|
2022-12-29 12:32:55 +00:00
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case ELABEL:
|
|
|
|
fprintf(outfile, "[%s]", expr->data.label->uniquename->name);
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case ETEMP:
|
|
|
|
DumpType(expr->data.temp.type);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EINITTRYCATCH:
|
|
|
|
DumpType(expr->rtype);
|
|
|
|
fprintf(outfile, "\r");
|
|
|
|
if (expr->data.itc.initexpr)
|
|
|
|
DumpExpression(expr->data.itc.initexpr, indent + 1);
|
|
|
|
if (expr->data.itc.tryexpr)
|
|
|
|
DumpExpression(expr->data.itc.tryexpr, indent + 1);
|
|
|
|
if (expr->data.itc.catchexpr)
|
|
|
|
DumpExpression(expr->data.itc.catchexpr, indent + 1);
|
|
|
|
if (expr->data.itc.result)
|
|
|
|
DumpExpression(expr->data.itc.result, indent + 1);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case EDEFINE:
|
2023-01-14 13:20:48 +00:00
|
|
|
fprintf(outfile, "[%.8" PRIX32 "]", expr);
|
2022-12-29 12:32:55 +00:00
|
|
|
DumpType(expr->rtype);
|
|
|
|
fputs("\r", outfile);
|
|
|
|
expr = expr->data.monadic;
|
|
|
|
indent++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EREUSE:
|
2023-01-14 13:20:48 +00:00
|
|
|
fprintf(outfile, "[%.8" PRIX32 "]", expr->data.monadic);
|
2022-12-29 12:32:55 +00:00
|
|
|
DumpType(expr->rtype);
|
|
|
|
fputs("\r", outfile);
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DumpSwitch(SwitchInfo *info) {
|
|
|
|
char buf[32];
|
|
|
|
SwitchCase *cs;
|
|
|
|
|
|
|
|
for (cs = info->cases; cs; cs = cs->next) {
|
|
|
|
CInt64_PrintDec(buf, cs->min);
|
|
|
|
CInt64_PrintDec(buf, cs->min);
|
|
|
|
fprintf(outfile, "\t\t%11s: %s\r", buf, cs->label->uniquename->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(outfile, "\t\t default: %s\r", info->defaultlabel->uniquename->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DumpType(Type *type) {
|
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
spell(type, buf);
|
|
|
|
fprintf(outfile, " (%s)", buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void spell(Type *type, char *buf) {
|
|
|
|
char mybuf[256];
|
|
|
|
char mybuf2[256];
|
|
|
|
|
|
|
|
switch (type->type) {
|
|
|
|
case TYPEVOID:
|
|
|
|
strcpy(buf, "void");
|
|
|
|
break;
|
|
|
|
case TYPEINT:
|
|
|
|
switch (TYPE_INTEGRAL(type)->integral) {
|
|
|
|
case IT_BOOL:
|
|
|
|
strcpy(buf, "bool");
|
|
|
|
break;
|
|
|
|
case IT_CHAR:
|
|
|
|
strcpy(buf, "char");
|
|
|
|
break;
|
|
|
|
case IT_WCHAR_T:
|
|
|
|
strcpy(buf, "wchar_t");
|
|
|
|
break;
|
|
|
|
case IT_SCHAR:
|
|
|
|
strcpy(buf, "signed char");
|
|
|
|
break;
|
|
|
|
case IT_UCHAR:
|
|
|
|
strcpy(buf, "unsigned char");
|
|
|
|
break;
|
|
|
|
case IT_SHORT:
|
|
|
|
strcpy(buf, "short");
|
|
|
|
break;
|
|
|
|
case IT_USHORT:
|
|
|
|
strcpy(buf, "unsigned short");
|
|
|
|
break;
|
|
|
|
case IT_INT:
|
|
|
|
strcpy(buf, "int");
|
|
|
|
break;
|
|
|
|
case IT_UINT:
|
|
|
|
strcpy(buf, "unsigned int");
|
|
|
|
break;
|
|
|
|
case IT_LONG:
|
|
|
|
strcpy(buf, "long");
|
|
|
|
break;
|
|
|
|
case IT_ULONG:
|
|
|
|
strcpy(buf, "unsigned long");
|
|
|
|
break;
|
|
|
|
case IT_LONGLONG:
|
|
|
|
strcpy(buf, "long long");
|
|
|
|
break;
|
|
|
|
case IT_ULONGLONG:
|
|
|
|
strcpy(buf, "unsigned long long");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPEFLOAT:
|
|
|
|
switch (TYPE_INTEGRAL(type)->integral) {
|
|
|
|
case IT_FLOAT:
|
|
|
|
strcpy(buf, "float");
|
|
|
|
break;
|
|
|
|
case IT_SHORTDOUBLE:
|
|
|
|
strcpy(buf, "short double");
|
|
|
|
break;
|
|
|
|
case IT_DOUBLE:
|
|
|
|
strcpy(buf, "double");
|
|
|
|
break;
|
|
|
|
case IT_LONGDOUBLE:
|
|
|
|
strcpy(buf, "long double");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPEENUM:
|
|
|
|
strcpy(buf, "enum ");
|
|
|
|
if (TYPE_ENUM(type)->enumname)
|
|
|
|
strcat(buf, TYPE_ENUM(type)->enumname->name);
|
|
|
|
break;
|
|
|
|
case TYPESTRUCT:
|
2023-01-11 22:29:53 +00:00
|
|
|
if (IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(type))) {
|
2022-12-29 12:32:55 +00:00
|
|
|
switch (TYPE_STRUCT(type)->stype) {
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_UCHAR:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector unsigned char ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_SCHAR:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector signed char ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_BCHAR:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector bool char ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_USHORT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector unsigned short ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_SSHORT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector signed short ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_BSHORT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector bool short ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_UINT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector unsigned int ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_SINT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector signed int ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_BINT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector bool int ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_FLOAT:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector float ");
|
|
|
|
break;
|
2023-01-18 17:19:20 +00:00
|
|
|
case STRUCT_VECTOR_PIXEL:
|
2022-12-29 12:32:55 +00:00
|
|
|
strcpy(buf, "vector pixel ");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
strcpy(buf, "struct ");
|
|
|
|
if (TYPE_STRUCT(type)->name)
|
|
|
|
strcat(buf, TYPE_STRUCT(type)->name->name);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TYPECLASS:
|
|
|
|
strcpy(buf, "class ");
|
|
|
|
if (TYPE_CLASS(type)->classname)
|
|
|
|
strcat(buf, TYPE_CLASS(type)->classname->name);
|
|
|
|
break;
|
|
|
|
case TYPEFUNC:
|
|
|
|
spell(TYPE_FUNC(type)->functype, mybuf);
|
|
|
|
strcpy(buf, "freturns(");
|
|
|
|
strcat(buf, mybuf);
|
|
|
|
strcat(buf, ")");
|
|
|
|
break;
|
|
|
|
case TYPEBITFIELD:
|
|
|
|
spell(TYPE_BITFIELD(type)->bitfieldtype, mybuf);
|
|
|
|
sprintf(buf,
|
|
|
|
"bitfield(%s){%d:%d}",
|
|
|
|
mybuf,
|
|
|
|
TYPE_BITFIELD(type)->unkA,
|
|
|
|
TYPE_BITFIELD(type)->unkB);
|
|
|
|
break;
|
|
|
|
case TYPELABEL:
|
|
|
|
strcpy(buf, "label");
|
|
|
|
break;
|
|
|
|
case TYPEPOINTER:
|
|
|
|
spell(TPTR_TARGET(type), mybuf);
|
|
|
|
strcpy(buf, "pointer(");
|
|
|
|
strcat(buf, mybuf);
|
|
|
|
strcat(buf, ")");
|
|
|
|
break;
|
|
|
|
case TYPEARRAY:
|
|
|
|
spell(TPTR_TARGET(type), mybuf);
|
|
|
|
strcpy(buf, "array(");
|
|
|
|
strcat(buf, mybuf);
|
|
|
|
strcat(buf, ")");
|
|
|
|
break;
|
|
|
|
case TYPEMEMBERPOINTER:
|
|
|
|
spell(TYPE_MEMBER_POINTER(type)->ty2, mybuf);
|
|
|
|
spell(TYPE_MEMBER_POINTER(type)->ty1, mybuf2);
|
|
|
|
strcpy(buf, "memberpointer(");
|
|
|
|
strcat(buf, mybuf);
|
|
|
|
strcat(buf, ",");
|
|
|
|
strcat(buf, mybuf2);
|
|
|
|
strcat(buf, ")");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DumpStack(ExceptionAction *act) {
|
|
|
|
while (act) {
|
|
|
|
fprintf(outfile, "\t\t:");
|
|
|
|
switch (act->type) {
|
|
|
|
case EAT_DESTROYLOCAL:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DESTROYLOCAL %s(&%s)%s",
|
|
|
|
CMangler_GetLinkName(act->data.destroy_local.dtor)->name,
|
|
|
|
act->data.destroy_local.local->name->name,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYLOCALCOND:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DESTROYLOCALCOND%s",
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYLOCALOFFSET:
|
|
|
|
fprintf(outfile,
|
2023-01-14 13:20:48 +00:00
|
|
|
"EAT_DESTROYLOCALOFFSET %s(&%s+%" PRId32 ")%s",
|
2022-12-29 12:32:55 +00:00
|
|
|
CMangler_GetLinkName(act->data.destroy_local_offset.dtor)->name,
|
|
|
|
act->data.destroy_local_offset.local->name->name,
|
|
|
|
act->data.destroy_local_offset.offset,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYLOCALPOINTER:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DESTROYLOCALPOINTER%s",
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYLOCALARRAY:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DESTROYLOCALARRAY%s",
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYBASE:
|
|
|
|
fprintf(outfile,
|
2023-01-14 13:20:48 +00:00
|
|
|
"EAT_DESTROYBASE %s(this+%" PRId32 ")%s",
|
2022-12-29 12:32:55 +00:00
|
|
|
CMangler_GetLinkName(act->data.destroy_base.dtor)->name,
|
|
|
|
act->data.destroy_base.offset,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYMEMBER:
|
|
|
|
fprintf(outfile,
|
2023-01-14 13:20:48 +00:00
|
|
|
"EAT_DESTROYMEMBER %s(%s+%" PRId32 ")%s",
|
2022-12-29 12:32:55 +00:00
|
|
|
CMangler_GetLinkName(act->data.destroy_member.dtor)->name,
|
|
|
|
act->data.destroy_member.objectptr->name->name,
|
|
|
|
act->data.destroy_member.offset,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYMEMBERCOND:
|
|
|
|
fprintf(outfile,
|
2023-01-14 13:20:48 +00:00
|
|
|
"EAT_DESTROYMEMBERCOND if(%s) %s(this+%" PRId32 ")%s",
|
2022-12-29 12:32:55 +00:00
|
|
|
act->data.destroy_member_cond.cond->name->name,
|
|
|
|
CMangler_GetLinkName(act->data.destroy_member_cond.dtor)->name,
|
|
|
|
act->data.destroy_member_cond.offset,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DESTROYMEMBERARRAY:
|
|
|
|
fprintf(outfile,
|
2023-01-14 13:20:48 +00:00
|
|
|
"EAT_DESTROYMEMBERARRAY %s(this+%" PRId32 ")[%" PRId32 "] size: %" PRId32 "%s",
|
2022-12-29 12:32:55 +00:00
|
|
|
CMangler_GetLinkName(act->data.destroy_member_array.dtor)->name,
|
|
|
|
act->data.destroy_member_array.offset,
|
|
|
|
act->data.destroy_member_array.elements,
|
|
|
|
act->data.destroy_member_array.element_size,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DELETEPOINTER:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DELETEPOINTER(%s)%s",
|
|
|
|
act->data.delete_pointer.pointerobject->name->name,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DELETELOCALPOINTER:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DELETELOCALPOINTER(%s)%s",
|
|
|
|
act->data.delete_pointer.pointerobject->name->name,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_DELETEPOINTERCOND:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_DELETEPOINTERCOND if (%s)(%s)%s",
|
|
|
|
act->data.delete_pointer_cond.cond->name->name,
|
|
|
|
act->data.delete_pointer_cond.pointerobject->name->name,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_CATCHBLOCK:
|
|
|
|
fprintf(outfile, "EAT_CATCHBLOCK ");
|
|
|
|
if (act->data.catch_block.catch_type) {
|
|
|
|
if (act->data.catch_block.catch_object)
|
|
|
|
fprintf(outfile, "[%s]", act->data.catch_block.catch_object->name->name);
|
|
|
|
else
|
|
|
|
fprintf(outfile, "[]");
|
|
|
|
DumpType(act->data.catch_block.catch_type);
|
|
|
|
} else {
|
|
|
|
fprintf(outfile, "[...] ");
|
|
|
|
}
|
|
|
|
fprintf(outfile,
|
|
|
|
" Label: %s%s",
|
|
|
|
act->data.catch_block.catch_label->uniquename->name,
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_SPECIFICATION:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_SPECIFICATION%s",
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_ACTIVECATCHBLOCK:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_ACTIVECATCHBLOCK%s",
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
case EAT_TERMINATE:
|
|
|
|
fprintf(outfile,
|
|
|
|
"EAT_TERMINATE%s",
|
|
|
|
"\r");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
act = act->prev;
|
|
|
|
}
|
|
|
|
}
|