summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/Optimizer/IroDump.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_and_linker/FrontEnd/Optimizer/IroDump.c')
-rw-r--r--compiler_and_linker/FrontEnd/Optimizer/IroDump.c660
1 files changed, 660 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/Optimizer/IroDump.c b/compiler_and_linker/FrontEnd/Optimizer/IroDump.c
new file mode 100644
index 0000000..d21496f
--- /dev/null
+++ b/compiler_and_linker/FrontEnd/Optimizer/IroDump.c
@@ -0,0 +1,660 @@
+#include "IroDump.h"
+#include "IroCSE.h"
+#include "IroFlowgraph.h"
+#include "IroLinearForm.h"
+#include "IroPropagate.h"
+#include "IroUtil.h"
+#include "IroVars.h"
+#include "compiler/CFunc.h"
+#include "compiler/CInt64.h"
+#include "compiler/CParser.h"
+#include "compiler/objects.h"
+
+static FILE *DumpFile;
+static char *nodenames[MAXEXPR];
+
+char *IRO_NodeName(ENodeType nodetype) {
+ return nodenames[nodetype];
+}
+
+void IRO_InitializeNodeNamesArray(void) {
+ int i;
+ for (i = 0; i < MAXEXPR; i++)
+ nodenames[i] = "";
+
+ nodenames[EPOSTINC] = "EPOSTINC";
+ nodenames[EPOSTDEC] = "EPOSTDEC";
+ nodenames[EPREINC] = "EPREINC";
+ nodenames[EPREDEC] = "EPREDEC";
+ nodenames[EINDIRECT] = "EINDIRECT";
+ nodenames[EMONMIN] = "EMONMIN";
+ nodenames[EBINNOT] = "EBINNOT";
+ nodenames[ELOGNOT] = "ELOGNOT";
+ nodenames[EFORCELOAD] = "EFORCELOAD";
+ nodenames[EMUL] = "EMUL";
+ nodenames[EMULV] = "EMULV";
+ nodenames[EDIV] = "EDIV";
+ nodenames[EMODULO] = "EMODULO";
+ nodenames[EADDV] = "EADDV";
+ nodenames[ESUBV] = "ESUBV";
+ nodenames[EADD] = "EADD";
+ nodenames[ESUB] = "ESUB";
+ nodenames[ESHL] = "ESHL";
+ nodenames[ESHR] = "ESHR";
+ nodenames[ELESS] = "ELESS";
+ nodenames[EGREATER] = "EGREATER";
+ nodenames[ELESSEQU] = "ELESSEQU";
+ nodenames[EGREATEREQU] = "EGREATEREQU";
+ nodenames[EEQU] = "EEQU";
+ nodenames[ENOTEQU] = "ENOTEQU";
+ nodenames[EAND] = "EAND";
+ nodenames[EXOR] = "EXOR";
+ nodenames[EOR] = "EOR";
+ nodenames[ELAND] = "ELAND";
+ nodenames[ELOR] = "ELOR";
+ nodenames[EASS] = "EASS";
+ nodenames[EMULASS] = "EMULASS";
+ nodenames[EDIVASS] = "EDIVASS";
+ nodenames[EMODASS] = "EMODASS";
+ nodenames[EADDASS] = "EADDASS";
+ nodenames[ESUBASS] = "ESUBASS";
+ nodenames[ESHLASS] = "ESHLASS";
+ nodenames[ESHRASS] = "ESHRASS";
+ nodenames[EANDASS] = "EANDASS";
+ nodenames[EXORASS] = "EXORASS";
+ nodenames[EORASS] = "EORASS";
+ nodenames[ECOMMA] = "ECOMMA";
+ nodenames[EPMODULO] = "EPMODULO";
+ nodenames[EROTL] = "EROTL";
+ nodenames[EROTR] = "EROTR";
+ nodenames[EBCLR] = "EBCLR";
+ nodenames[EBTST] = "EBTST";
+ nodenames[EBSET] = "EBSET";
+ nodenames[ETYPCON] = "ETYPCON";
+ nodenames[EBITFIELD] = "EBITFIELD";
+ nodenames[EINTCONST] = "EINTCONST";
+ nodenames[EFLOATCONST] = "EFLOATCONST";
+ nodenames[ESTRINGCONST] = "ESTRINGCONST";
+ nodenames[ECOND] = "ECOND";
+ nodenames[EFUNCCALL] = "EFUNCCALL";
+ nodenames[EFUNCCALLP] = "EFUNCCALLP";
+ nodenames[EOBJREF] = "EOBJREF";
+ nodenames[EMFPOINTER] = "EMFPOINTER";
+ nodenames[ENULLCHECK] = "ENULLCHECK";
+ nodenames[EPRECOMP] = "EPRECOMP";
+ nodenames[ETEMP] = "ETEMP";
+ nodenames[EARGOBJ] = "EARGOBJ";
+ nodenames[ELOCOBJ] = "ELOCOBJ";
+ nodenames[ELABEL] = "ELABEL";
+ nodenames[ESETCONST] = "ESETCONST";
+ nodenames[ENEWEXCEPTION] = "ENEWEXCEPTION";
+ nodenames[ENEWEXCEPTIONARRAY] = "ENEWEXCEPTIONARRAY";
+ nodenames[EOBJLIST] = "EOBJLIST";
+ nodenames[EMEMBER] = "EMEMBER";
+ nodenames[ETEMPLDEP] = "ETEMPLDEP";
+ nodenames[EINSTRUCTION] = "EINSTRUCTION";
+ nodenames[EDEFINE] = "EDEFINE";
+ nodenames[EREUSE] = "EREUSE";
+ nodenames[EASSBLK] = "EASSBLK";
+ nodenames[EVECTOR128CONST] = "EVECTOR128CONST";
+ nodenames[ECONDASS] = "ECONDASS";
+}
+
+static void DumpENode(ENode *enode) {
+ char buf[64];
+
+ if (IRO_Log) {
+ switch (enode->type) {
+ case EOBJREF:
+ fprintf(DumpFile, "%s", enode->data.objref->name->name);
+ break;
+ case EINTCONST:
+ CInt64_PrintDec(buf, enode->data.intval);
+ fprintf(DumpFile, "%s", buf);
+ break;
+ case EFLOATCONST:
+ fprintf(DumpFile, "%g", enode->data.floatval.value);
+ break;
+ case EVECTOR128CONST:
+ fprintf(DumpFile, "%.8lX%.8lX%.8lX%.8lX",
+ enode->data.vector128val.ul[0],
+ enode->data.vector128val.ul[1],
+ enode->data.vector128val.ul[2],
+ enode->data.vector128val.ul[3]
+ );
+ break;
+ }
+ }
+}
+
+static void DumpLinearNode(IROLinear *linear) {
+ int i;
+
+ if (IRO_Log) {
+ fprintf(DumpFile, "%4d: ", linear->index);
+ switch (linear->type) {
+ case IROLinearNop:
+ fprintf(DumpFile, "Nop");
+ break;
+ case IROLinearOperand:
+ fprintf(DumpFile, "Operand ");
+ DumpENode(linear->u.node);
+ break;
+ case IROLinearOp1Arg:
+ fprintf(DumpFile, "%s %d", nodenames[linear->nodetype], linear->u.monadic->index);
+ break;
+ case IROLinearOp2Arg:
+ fprintf(DumpFile, "%s %d %d", nodenames[linear->nodetype], linear->u.diadic.left->index, linear->u.diadic.right->index);
+ break;
+ case IROLinearGoto:
+ fprintf(DumpFile, "Goto %s", linear->u.label.label->name->name);
+ break;
+ case IROLinearIf:
+ fprintf(DumpFile, "If %d %s", linear->u.label.x4->index, linear->u.label.label->name->name);
+ break;
+ case IROLinearIfNot:
+ fprintf(DumpFile, "IfNot %d %s", linear->u.label.x4->index, linear->u.label.label->name->name);
+ break;
+ case IROLinearReturn:
+ fprintf(DumpFile, "Return ");
+ if (linear->u.monadic)
+ fprintf(DumpFile, "%d", linear->u.monadic->index);
+ break;
+ case IROLinearLabel:
+ fprintf(DumpFile, "Label %s", linear->u.label.label->name->name);
+ break;
+ case IROLinearSwitch:
+ fprintf(DumpFile, "Switch %d", linear->u.swtch.x4->index);
+ break;
+ case IROLinearOp3Arg:
+ fprintf(DumpFile, "%s %d %d %d",
+ nodenames[linear->nodetype],
+ linear->u.args3.a->index,
+ linear->u.args3.b->index,
+ linear->u.args3.c->index);
+ break;
+ case IROLinearFunccall:
+ fprintf(DumpFile, "Funccall %d(", linear->u.funccall.linear8->index);
+ for (i = 0; i < linear->u.funccall.argCount; i++) {
+ fprintf(DumpFile, "%d", linear->u.funccall.args[i]->index);
+ if (i < (linear->u.funccall.argCount - 1))
+ fprintf(DumpFile, ",");
+ }
+ fprintf(DumpFile, ")");
+ break;
+ case IROLinearBeginCatch:
+ fprintf(DumpFile, "BeginCatch %d", linear->u.ctch.linear->index);
+ break;
+ case IROLinearEndCatch:
+ fprintf(DumpFile, "EndCatch %d", linear->u.monadic->index);
+ break;
+ case IROLinearEndCatchDtor:
+ fprintf(DumpFile, "EndCatchDtor %d", linear->u.monadic->index);
+ break;
+ case IROLinearEnd:
+ fprintf(DumpFile, "End");
+ break;
+ }
+
+ if (linear->flags & IROLF_Assigned) fprintf(DumpFile, " <assigned>");
+ if (linear->flags & IROLF_Used) fprintf(DumpFile, " <used>");
+ if (linear->flags & IROLF_Ind) fprintf(DumpFile, " <ind>");
+ if (linear->flags & IROLF_Subs) fprintf(DumpFile, " <subs>");
+ if (linear->flags & IROLF_LoopInvariant) fprintf(DumpFile, " <loop invariant>");
+ if (linear->flags & IROLF_BeginLoop) fprintf(DumpFile, " <begin loop>");
+ if (linear->flags & IROLF_EndLoop) fprintf(DumpFile, " <end loop>");
+ if (linear->flags & IROLF_Ris) fprintf(DumpFile, " <ris>");
+ if (linear->flags & IROLF_Immind) fprintf(DumpFile, " <immind>");
+ if (linear->flags & IROLF_Reffed) fprintf(DumpFile, " <reffed>");
+ if (linear->flags & IROLF_VecOp) fprintf(DumpFile, " <vec op>");
+ if (linear->flags & IROLF_VecOpBase) fprintf(DumpFile, " <vec op_base>");
+ if (linear->flags & IROLF_CounterLoop) fprintf(DumpFile, " <counter loop>");
+ if (linear->flags & IROLF_BitfieldIndirect) fprintf(DumpFile, " <bitfield_indirect>");
+ if (linear->flags & IROLF_CouldError) fprintf(DumpFile, " <could_error>");
+
+ if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS))
+ fprintf(DumpFile, " <volatile>");
+
+ if (IS_LINEAR_ENODE(linear, EOBJREF)) {
+ VarRecord *var = IRO_FindVar(linear->u.node->data.objref, 0, 1);
+ if (var && is_volatile_object(var->object))
+ fprintf(DumpFile, " <volatile obj>");
+ }
+
+ fprintf(DumpFile, "\n");
+ }
+}
+
+static void DumpAct(IROLinear *linear, Boolean isFirst) {
+ if (!isFirst)
+ DumpLinearNode(linear);
+}
+
+void IRO_DumpIntTree(IROLinear *linear) {
+ IRO_WalkTree(linear, DumpAct);
+}
+
+void IRO_DumpLinearList(IROLinear *linear) {
+ if (!IRO_Log)
+ return;
+
+ while (linear) {
+ DumpLinearNode(linear);
+ linear = linear->next;
+ }
+ fprintf(DumpFile, "\n");
+}
+
+static void DumpList(int num, UInt16 *list) {
+ int i;
+
+ if (IRO_Log) {
+ for (i = 0; i < num; i++)
+ fprintf(DumpFile, "%d ", list[i]);
+ fprintf(DumpFile, "\n");
+ }
+}
+
+void IRO_DumpBits(char *name, BitVector *bv) {
+ SInt32 i;
+ SInt32 rangeStart;
+ Boolean inRange = 0;
+ Boolean isFirst = 1;
+
+ if (!IRO_Log)
+ return;
+
+ fprintf(DumpFile, name);
+ if (!bv) {
+ fprintf(DumpFile, "NULL");
+ } else {
+ for (i = 0; i < (bv->size * 32); i++) {
+ if (Bv_IsBitSet(i, bv)) {
+ if (!inRange) {
+ if (!isFirst)
+ fputc(',', DumpFile);
+ isFirst = 0;
+ fprintf(DumpFile, "%d", i);
+ inRange = 1;
+ rangeStart = i;
+ }
+ } else {
+ if (inRange) {
+ inRange = 0;
+ if (i != (rangeStart + 1))
+ fprintf(DumpFile, "-%d", i - 1);
+ }
+ }
+ }
+
+ if (inRange && i != (rangeStart + 1))
+ fprintf(DumpFile, "-%d", i - 1);
+ }
+
+ fprintf(DumpFile, "\n");
+}
+
+void IRO_DumpAfterPhase(char *str, Boolean flag) {
+#ifdef CW_ENABLE_IRO_DEBUG
+ if (copts.debuglisting)
+ flag = 1;
+#endif
+ if (flag) {
+ IRO_Dump("Dumping function %s after %s \n", FunctionName ? FunctionName->name->name : "Init-code", str);
+ IRO_Dump("--------------------------------------------------------------------------------\n");
+ IRO_DumpFlowgraph();
+ }
+}
+
+void IRO_LogForFunction(char *name) {
+ if (FunctionName) {
+ if (!strcmp(FunctionName->name->name, name))
+ IRO_Log = 1;
+ else
+ IRO_Log = 0;
+ }
+}
+
+void IRO_DumpFlowgraph(void) {
+ IRONode *node;
+ IROLinear *linear;
+
+ if (IRO_Log && DumpFile) {
+ fprintf(DumpFile, "\nFlowgraph\n");
+ for (node = IRO_FirstNode; node; node = node->nextnode) {
+ fprintf(DumpFile, "Flowgraph node %d First=%d, Last=%d\n", node->index, node->first->index, node->last->index);
+
+ fprintf(DumpFile, "Succ = ");
+ DumpList(node->numsucc, node->succ);
+ fprintf(DumpFile, "Pred = ");
+ DumpList(node->numpred, node->pred);
+
+ fprintf(DumpFile, "MustReach = %d, MustReach1=%d\n", node->mustreach, node->mustreach1);
+ fprintf(DumpFile, "LoopDepth = %d\n", node->loopdepth);
+
+ IRO_DumpBits("Dom: ", node->dom);
+ if ((linear = node->first)) {
+ while (1) {
+ DumpLinearNode(linear);
+ if (linear == node->last)
+ break;
+ linear = linear->next;
+ }
+ }
+
+ fprintf(DumpFile, "\n\n");
+ }
+ fprintf(DumpFile, "\n");
+ fflush(DumpFile);
+ }
+}
+
+void IRO_DumpNode(IRONode *node) {
+ IROLinear *linear;
+
+ if (IRO_Log) {
+ if (!DumpFile)
+ return;
+
+ while (node) {
+ fprintf(DumpFile, "Flowgraph node %d First=%d, Last=%d\n", node->index, node->first->index,
+ node->last->index);
+
+ fprintf(DumpFile, "Succ = ");
+ DumpList(node->numsucc, node->succ);
+ fprintf(DumpFile, "Pred = ");
+ DumpList(node->numpred, node->pred);
+
+ fprintf(DumpFile, "MustReach = %d MustReach1 = %d\n", node->mustreach, node->mustreach1);
+ fprintf(DumpFile, "LoopDepth = %d\n", node->loopdepth);
+
+ IRO_DumpBits("Dom: ", node->dom);
+ if ((linear = node->first)) {
+ while (1) {
+ DumpLinearNode(linear);
+ if (linear == node->last)
+ break;
+ linear = linear->next;
+ }
+ }
+
+ fprintf(DumpFile, "\n\n");
+ node = node->nextnode;
+ }
+
+ fprintf(DumpFile, "\n");
+ fflush(DumpFile);
+ }
+}
+
+void IRO_DumpAssignments(void) {
+ IROAssign *assign;
+
+ if (IRO_Log) {
+ fprintf(DumpFile, "\nAssignments\n\n");
+ for (assign = IRO_FirstAssign; assign; assign = assign->next) {
+ fprintf(DumpFile, "%5d ", assign->index);
+ DumpLinearNode(assign->linear);
+ fprintf(DumpFile, "\n");
+ }
+ fprintf(DumpFile, "\n");
+ }
+}
+
+void IRO_DumpVars(void) {
+ VarRecord *var;
+
+ if (IRO_Log) {
+ fprintf(DumpFile, "\nVariables\n");
+ for (var = IRO_FirstVar; var; var = var->next) {
+ fprintf(DumpFile, "%5d %s %s\n", var->index, var->object->name->name, var->xB ? "<addressed>" : "");
+ }
+ fprintf(DumpFile, "\n");
+ }
+}
+
+void IRO_DumpDf(void) {
+ IRONode *node;
+
+ if (IRO_Log) {
+ for (node = IRO_FirstNode; node; node = node->nextnode) {
+ fprintf(DumpFile, "Node %d\n", node->index);
+ if (node->x16) IRO_DumpBits("In: ", node->x16);
+ if (node->x1E) IRO_DumpBits("Gen: ", node->x1E);
+ if (node->x22) IRO_DumpBits("Kill: ", node->x22);
+ if (node->x1A) IRO_DumpBits("Out: ", node->x1A);
+ if (node->x2A) IRO_DumpBits("AA: ", node->x2A);
+ fprintf(DumpFile, "\n");
+ }
+ fprintf(DumpFile, "\n");
+ }
+}
+
+void IRO_DumpExprs(void) {
+ IROExpr *expr;
+
+ if (IRO_Log) {
+ fprintf(DumpFile, "Expressions\n\n");
+ for (expr = IRO_FirstExpr; expr; expr = expr->next) {
+ fprintf(DumpFile, "%4d: %d FN:%d CE:%d NS:%d ", expr->index, expr->linear->index, expr->node->index, expr->couldError, expr->notSubable);
+ IRO_DumpBits("Depends: ", expr->depends);
+ fprintf(DumpFile, "\n");
+ }
+ fprintf(DumpFile, "\n");
+ }
+}
+
+void IRO_SetupDump(void) {
+#ifdef CW_ENABLE_IRO_DEBUG
+ IRO_Log = 1;
+#endif
+
+ if (IRO_Log) {
+ if ((DumpFile = fopen("OPT.LOG", "wt")) == NULL)
+ IRO_Log = 0;
+ }
+}
+
+void IRO_CleanupDump(void) {
+ if (DumpFile)
+ fclose(DumpFile);
+}
+
+void IRO_Dump(char *format, ...) {
+ va_list va;
+ if (IRO_Log) {
+ va_start(va, format);
+ vfprintf(DumpFile, format, va);
+ va_end(va);
+ }
+}
+
+void IRO_DumpAddr(IROAddrRecord *rec) {
+ IROElmList *list;
+
+ if (IRO_Log && DumpFile) {
+ fprintf(DumpFile, "\n");
+ fprintf(DumpFile, "Address :\n");
+ IRO_DumpIntTree(rec->linear);
+ fprintf(DumpFile, "\n");
+ fprintf(DumpFile, "BaseTerms:\n");
+ for (list = rec->objRefs; list; list = list->next) {
+ IRO_DumpIntTree(list->element);
+ fprintf(DumpFile, "\n");
+ }
+ fprintf(DumpFile, "VarTerms:\n");
+ for (list = rec->misc; list; list = list->next) {
+ IRO_DumpIntTree(list->element);
+ fprintf(DumpFile, "\n");
+ }
+ fprintf(DumpFile, "ConstTerms:\n");
+ for (list = rec->ints; list; list = list->next) {
+ IRO_DumpIntTree(list->element);
+ fprintf(DumpFile, "\n");
+ }
+ }
+}
+
+static void IRO_DumpType(Type *type) {
+ char buf[256];
+ IRO_SpellType(type, buf);
+ fprintf(DumpFile, " (%s)", buf);
+}
+
+void IRO_SpellType(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:
+ if (IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(type))) {
+ switch (TYPE_STRUCT(type)->stype) {
+ case STRUCT_VECTOR_UCHAR:
+ strcpy(buf, "vector unsigned char ");
+ break;
+ case STRUCT_VECTOR_SCHAR:
+ strcpy(buf, "vector signed char ");
+ break;
+ case STRUCT_VECTOR_BCHAR:
+ strcpy(buf, "vector bool char ");
+ break;
+ case STRUCT_VECTOR_USHORT:
+ strcpy(buf, "vector unsigned short ");
+ break;
+ case STRUCT_VECTOR_SSHORT:
+ strcpy(buf, "vector signed short ");
+ break;
+ case STRUCT_VECTOR_BSHORT:
+ strcpy(buf, "vector bool short ");
+ break;
+ case STRUCT_VECTOR_UINT:
+ strcpy(buf, "vector unsigned long ");
+ break;
+ case STRUCT_VECTOR_SINT:
+ strcpy(buf, "vector signed long ");
+ break;
+ case STRUCT_VECTOR_BINT:
+ strcpy(buf, "vector bool long ");
+ break;
+ case STRUCT_VECTOR_FLOAT:
+ strcpy(buf, "vector float ");
+ break;
+ case STRUCT_VECTOR_PIXEL:
+ 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:
+ IRO_SpellType(TYPE_FUNC(type)->functype, mybuf);
+ strcpy(buf, "freturns(");
+ strcat(buf, mybuf);
+ strcat(buf, ")");
+ break;
+ case TYPEBITFIELD:
+ IRO_SpellType(TYPE_BITFIELD(type)->bitfieldtype, mybuf);
+ sprintf(buf, "bitfield(%s){%d:%d}", mybuf, TYPE_BITFIELD(type)->offset, TYPE_BITFIELD(type)->bitlength);
+ break;
+ case TYPELABEL:
+ strcpy(buf, "label");
+ break;
+ case TYPEPOINTER:
+ IRO_SpellType(TPTR_TARGET(type), mybuf);
+ strcpy(buf, "pointer(");
+ strcat(buf, mybuf);
+ strcat(buf, ")");
+ break;
+ case TYPEARRAY:
+ IRO_SpellType(TPTR_TARGET(type), mybuf);
+ strcpy(buf, "array(");
+ strcat(buf, mybuf);
+ strcat(buf, ")");
+ break;
+ case TYPEMEMBERPOINTER:
+ IRO_SpellType(TYPE_MEMBER_POINTER(type)->ty2, mybuf);
+ IRO_SpellType(TYPE_MEMBER_POINTER(type)->ty1, mybuf2);
+ strcpy(buf, "memberpointer(");
+ strcat(buf, mybuf);
+ strcat(buf, ",");
+ strcat(buf, mybuf2);
+ strcat(buf, ")");
+ break;
+ }
+}
+