diff options
Diffstat (limited to '')
-rw-r--r-- | private/os2/client/thunk/thunkcom/codegen.c | 1000 |
1 files changed, 1000 insertions, 0 deletions
diff --git a/private/os2/client/thunk/thunkcom/codegen.c b/private/os2/client/thunk/thunkcom/codegen.c new file mode 100644 index 000000000..44c5dea20 --- /dev/null +++ b/private/os2/client/thunk/thunkcom/codegen.c @@ -0,0 +1,1000 @@ +#define SCCSID "@(#)codegen.c 13.26 90/08/28" + +/* + * Thunk Compiler - Code Generator. + * + * This is a Windows 3.2 specific file + * Microsoft Confidential + * + * Copyright (c) Microsoft Corporation 1987, 1988, 1989 + * + * All Rights Reserved + * + * Written 10/15/88 by Kevin Ross [for OS/2 2.x] + * 10.16.90 Kevin Ruddell ported to Windows 3.2, 16=>32 + * 02.20.91 Kevin Ruddell re-wrote 16=>32 code + */ + + +#include <stdio.h> +#include <stdlib.h> +#include "error.h" +#include "thunk.h" +#include "types.h" +#include "symtab.h" +#include "codegen.h" + +extern CHAR *pszGDISemName; +extern BOOL fLocalHeapUsed; + +static FixupRec *FixUps = NULL; +unsigned int iStackOverhead; +unsigned int iAllocOffset,iBMPOffset,iAliasOffset,iTempStoreOffset, + iReturnValOffset,iSavedRegOffset,iErrorOffset, + iStackThunkIDOffset, iPtrThunkIDOffset; + + +/*** cod_GenerateCode(pmnFirst) + * + * This function generates the appropriate code for all of the + * given mappings. + * + * Entry: pmnFirst - a pointer to a list of mapping nodes. + * + * Exit: code is generated for all mappings. + * + * PCode: + * Scan list and convert names where needed + * Output Assembler File Prolog + * - Define all segments, and groups + * For (each function mapping in pMT) { + * switch (mapping type) { + * case 16 -> 32: gen_Handle1632(pMT); + * break; + * case 32 -> 16: gen_Handle3216(pMT); + * break; + * default: fatal("unknown mapping type"); + * } + * } + * + * History: + * 29-Nov-1988 JulieB Restructured FOR loop for cod_Handle routines + * 28-Nov-1988 JulieB Init gen_LabelCount. Added inline comments. + * 04-Apr-1989 KevinRo Added Undercase/Underscore routine + */ + +void cod_GenerateCode( PMAPNODE pmnFirst) +{ + PMAPNODE pmn; + BOOL fExistsTo16, fExistsTo32; + + fExistsTo16 = cod_ExistsToType( pmnFirst, TYPE_API16); + fExistsTo32 = cod_ExistsToType( pmnFirst, TYPE_API32); + + if( (fExistsTo16 = cod_ExistsToType( pmnFirst, TYPE_API16)) && + (fExistsTo32 = cod_ExistsToType( pmnFirst, TYPE_API32))) { + cod_NotHandled( "both 16=>32 and 32=>16 thunks in same script"); + return; + } + + cod_ConvertNames( pmnFirst); /* Fixup changes in names */ + + if( fExistsTo16) { +// +// YaronS - take this out to reduce size +// + ; +/* +* cod_OutputProlog( pmnFirst); +* +* if( fGlobalCombine) +* cod_CombineFunctions( pmnFirst); +* +* if( DumpTables) +* cod_DumpMapTable( pmnFirst); +* +* for( pmn = pmnFirst; pmn; pmn = pmn->pNextMapping) +* cod_Handle3216( pmn); +* +* cod_OutputEpilog( pmn); +*/ + } else if( fExistsTo32) { + + cod16_Handle16( pmnFirst); + + cod16_Prolog32( pmnFirst); + + for( pmn = pmnFirst; pmn; pmn = pmn->pNextMapping) + cod16_Handle32( pmn); + + cod16_Epilog32( pmnFirst); + } +} + + +/*** cod_ConvertNames(pMN) + * + * + * + * Entry: + * + * Exit: + */ + +void cod_ConvertNames( MapNode *pMT) + +{ + for( ; pMT; pMT = pMT->pNextMapping) { + /* + * If fUnderScore32 is set true, then prefix an underscore to the + * 32-bit function name. + */ + if (fUnderScore32) { + cod_PrefixUnderscore((pMT->pFromNode->iCallType==TYPE_API32) ? + pMT->pFromNode : pMT->pToNode); + } + + /* + * If fUpperCase16 is set true, then force the 16bit function to + * be all upper case. + */ + if (fUpperCase16) { + cod_ToUpper((pMT->pFromNode->iCallType==TYPE_API16) ? + pMT->pFromNode->pchFunctionName : + pMT->pToNode->pchFunctionName); + } + + /* + * If fUpperCase32 is set, then force the 32 bit name to be + * uppercase. + */ + if (fUpperCase32) { + cod_ToUpper((pMT->pFromNode->iCallType==TYPE_API32) ? + pMT->pFromNode->pchFunctionName : + pMT->pToNode->pchFunctionName); + } + } +} + + +/*** cod_StructOffset() + * + * This routine will traverse the StructElems of a typenode, + * calculating both the offset and size of each element of the + * structure. Size is only calculated for elements that are structures. + * + * Entry: pTNode - pointer to the structure element list. + * iPrev - the offset of any previous elements in element list. + * iAlign - the alignment value for the structure. Either + * 1,2 or 4, determines the packing for calculating + * offsets. + * + * Exit: Each element in the structure will have its StructOffset + * field set correctly. + * + * Returns the size of the structure as defined in 'C'. + * + * PCode: + * For (Each element in element list) { + * If (Element is a pointer type) { + * Element offset Aligned Offset + * Next offset = current + 4 * Array size + * If (Element type is structure) + * StructOffset(Element,Zero offset,Current Alignment) + * } Else if (Element is a structure) { + * Save previous offset + * Current offset = + * StructOffset(Element,Current offset,Current Alignment) + * Struct size = Current offset - Previous offset + * } Else { + * Align current offset according to data size + * Struct offset = current offset + * Current offset+= Datasize * ArraySize + * } + * } + * return (CurrentOffset which is same as structure size) + */ + +int cod_StructOffset(TypeNode *pTNode, + int iPrev, + int iAlign) + +{ + TypeNode *pTN; + int iSize=0; + int iLargest; + int tmpAlign; + + /* + * Preset the alignment for the first item in structure. + */ + iLargest = cod_FindLargestSize(pTNode); + tmpAlign = MIN(iLargest,iAlign); + iPrev = Align(iPrev,tmpAlign); + + for (pTN = pTNode; pTN; pTN = pTN->pNextNode) { + if (pTN->iDeleted) { + pTN->iStructOffset = iPrev; + } else if (pTN->iPointerType) { + iPrev = Align(iPrev,tmpAlign); + pTN->iStructOffset = iPrev; + iPrev += DWORD_SIZE * pTN->iArraySize; + + if (pTN->iBaseType == TYPE_STRUCT) { + pTN->iBaseDataSize = cod_StructOffset(pTN->pStructElems,0,iAlign); + } + } else if (pTN->iBaseType == TYPE_STRUCT) { + iSize = iPrev; + pTN->iStructOffset = iPrev; + iPrev = cod_StructOffset(pTN->pStructElems,iPrev,tmpAlign); + + if (pTN->pStructElems) { + pTN->iStructOffset = pTN->pStructElems->iStructOffset; + } + + pTN->iBaseDataSize = (iPrev - pTN->iStructOffset) ; + iPrev += pTN->iBaseDataSize * (pTN->iArraySize - 1); + } else { + switch(pTN->iBaseDataSize) + { + case 1: + /* + * Byte size items are always Byte aligned. + */ + break; + case 2: + if (tmpAlign >= 2) { + /* + * Word size items are always WORD aligned. + */ + iPrev = Align(iPrev,WORD_SIZE); + } + break; + case 4: + iPrev = Align(iPrev,tmpAlign); + break; + default: + fatal("cod_StructOffset: iBaseDataSize = %d", + pTN->iBaseDataSize); + } + pTN->iStructOffset = iPrev; + iPrev += pTN->iBaseDataSize * pTN->iArraySize; + } + } + iPrev = Align( iPrev, tmpAlign); + return (iPrev); +} + + +/*** cod_FindLargestSize(pTN) + * + * This little routine returns the size of the largest item in the + * TypeNode list pTN. The largest size refers to the largest + * value in iBaseDataSize. A pointer is considered the largest, at + * 4 bytes. If an item of 4 byte size is found, this routine returns + * 4 immediately. + * + * This routine is used by StructOffset as a worker routine. + * + * Entry: pTN - pointer to the type node. + * + * Exit: returns the size of the largest item in pTN. + */ + +int cod_FindLargestSize(TypeNode *pTN) + +{ + int maxsize = 0; + + + if (!pTN) + fatal("cod_FindLargestItem(pTN) Null Parameter"); + + for (; pTN; pTN = pTN->pNextNode) { + /* + * If item is deleted, then ignore it. + */ + if (pTN->iDeleted) + continue; + + /* + * Pointers are the largest items of interest. If we find one, then + * cut the search off, and return its size. Pointers are always DWORDs. + */ + if (pTN->iPointerType) + return DWORD_SIZE; + + if (pTN->iBaseType == TYPE_STRUCT) { + maxsize = MAX(maxsize,cod_FindLargestSize(pTN->pStructElems)); + } + maxsize = MAX( maxsize, (int)(pTN->iBaseDataSize)); + } + return (maxsize); +} + + +/*** cod_CalcStructOffsets() + * + * Entry: pTNode - List of parameters from a function node. + * iAlign - Alignment default value. + * + * Exit: structure offsets are calculated. + * + * PCode: + * For (Each parameter in list) { + * If (Parameter is a structure) { + * If (Alignment < 1) + * Assign default alignment to parameter + * ParameterSize = StructOffset(StructElems,0,Struct Align) + * } + * } + */ + +void cod_CalcStructOffsets( TypeNode *pTNode, int iAlign) + +{ + for( ; pTNode; pTNode = pTNode->pNextNode) { + if( pTNode->iBaseType == TYPE_STRUCT) { + if( pTNode->iAlignment < 1) + pTNode->iAlignment = iAlign; + pTNode->iBaseDataSize = + cod_StructOffset( pTNode->pStructElems, 0, pTNode->iAlignment); + } + } +} + + +/*** cod_CalcTempOffset(pTL, iStart) + * + * This routine will traverse a list of formal parameters, pTL, + * and calculate the stack offset for each temporary pointer. + * Temporary pointers will be assigned for every pointer in the + * type list, including pointers imbedded in structures. + * + * Entry: pTL - typeNode pointing to remainder of parameter list. + * iStart - the first available place for the temp pointers on + * the stack + * + * Exit: Each node in the pTL list will have its iTempOffset field + * filled in with the offset from eBP on the stack. The value + * returned by this function is the next available position + * on the stack. + * + * History: + * 26-Dec-1988 KevinRo Created + */ + +int cod_CalcTempOffset(TypeNode *pTL, + unsigned int iStart) + +{ + while (pTL) { + if (pTL->iPointerType) { + pTL->iTempOffset = iStart; + iStart += DWORD_SIZE; + } + if (pTL->iBaseType == TYPE_STRUCT) { + iStart = cod_CalcTempOffset(pTL->pStructElems,iStart); + } + pTL = pTL->pNextNode; + } + return (iStart); +} + + +/*** cod_CalcOffset(pTL, start, iPSize, fPushDir) + * + * This routine will traverse a list of formal parameters, pTL, + * and calculate the stack offset for each parameter. This routine + * will handle the calculation for stack offsets regardless of + * push direction (left to right, or right to left). + * + * Entry: pTL - typenode pointing to remainder of parameter list. + * start - bytes between top of stack and first parameter. + * iPSize - default size of parameters on stack. 16:16 routines + * pass WORD parameters, 0:32 DWORD parameters. + * fPushDir - direction of push (PUSH_LEFT = left to right). + * + * Exit: Each node in the pTL list will have its iOffset field filled + * in with the offset from eBP on the stack. + * + * PCode: (This routine is recursive) + * If (push left to right) { // push left to right + * If (pTL not NULL) { + * Current offset = return from CalcOffset of next parameter in list + * return Current Offset + size of current parameter + * } Else { + * return starting offset. + * } + * } Else { // push right to left + * If (pTL) { + * Current Offset = starting offset + * starting offset += Size of parameter on stack + * CalcOffset rest of list, using new starting offset + * } + * } + * + * History: + * 30-Nov-1988 JulieB Added use of MAX macro. + */ + +int cod_CalcOffset(TypeNode *pTL, + int start, + int iPSize, + int fPushDir) + +{ + if (fPushDir == PUSH_LEFT) { + if (pTL) { + start = pTL->iOffset + = cod_CalcOffset( pTL->pNextNode, start, iPSize, fPushDir); + /* + * If the parameter is flagged as deleted, then don't add + * its size to the offset. + */ + if( !(pTL->iDeleted)) { + start += (pTL->iPointerType) ? + 4 : + MAX( (int)(pTL->iBaseDataSize), iPSize); + } + } + return start; + } else { + if (pTL) { + pTL->iOffset = start; + /* + * If the parameter is flagged as deleted, then don't add + * its size to the offset. + */ + if( !pTL->iDeleted) { + start += (pTL->iPointerType) ? + 4 : + MAX( (int)(pTL->iBaseDataSize), iPSize); + } + cod_CalcOffset( pTL->pNextNode, start, iPSize, fPushDir); + } + } +} + + +/*** cod_OutputProlog( pmnFirst) + * + * This routine will output a masm header. + * + * Entry: pmnFirst - linked lists of mapping nodes. + * + * Exit: + * + * PCode: + * Output masm header + * For (each entry point) + * Declare symbol as public + * Open segment + * For (each called routine) + * If (routine is 32 bit) + * Output external + */ + +static void +cod_OutputProlog( MapNode *pmnFirst) + +{ + register MapNode *pmn; + FunctionNode *pFNode; + BOOL fExistsTo16, fExistsTo32; + + fExistsTo16 = cod_ExistsToType( pmnFirst, TYPE_API16); + fExistsTo32 = cod_ExistsToType( pmnFirst, TYPE_API32); + + for( pmn = pmnFirst, fLocalHeapUsed = FALSE; pmn; pmn = pmn->pNextMapping) + if( typ_QuerySemanticsUsed( pmn, SEMANTIC_LOCALHEAP)) + fLocalHeapUsed = TRUE; + + for( pmn = pmnFirst; pmn; pmn = pmn->pNextMapping) + printf( "PUBLIC\t%s\n", pmn->pFromNode->pchFunctionName); + + //printf( "\nDGROUP\tGROUP\t_DATA\n"); + + printf( "\n%s\tSEGMENT\tDWORD USE32 PUBLIC '%s'\n", + CODE32_NAME, CODE32_CLASS); + for( pmn = pmnFirst; pmn; pmn = pmn->pNextMapping) { + pFNode = pmn->pToNode; + if( pFNode->iCallType == TYPE_API32) + printf( "EXTRN\t%s:NEAR\n", pFNode->pchFunctionName); + } + printf( "EXTRN\tSELTOFLAT:NEAR\n"); + if( fExistsTo16) { + printf( "EXTRN\tGETTHUNKID32:NEAR\n"); + printf( "EXTRN\tMAPLS32:NEAR\n"); + printf( "EXTRN\tUNMAPLS32:NEAR\n"); + printf( "EXTRN\tGETSTACK32:NEAR\n"); + printf( "EXTRN\tRELEASESTACK32:NEAR\n"); + } + printf( "%s\tENDS\n\n", CODE32_NAME); + + printf( "%s\tSEGMENT\tDWORD USE32 PUBLIC '%s'\n",DATA32_NAME, DATA32_CLASS); + if( fExistsTo16) { + printf( "EXTRN\tSTACK16SELECTOR:WORD\n"); + printf( "EXTRN\tSTACK16INITIALOFFSET:DWORD\n"); + //printf( "EXTRN\t%s:DWORD\n", pszGDISemName); + } + if( fLocalHeapUsed) { + printf( "EXTRN\tDS16LOCALHEAPSELECTOR:WORD\n"); + printf( "EXTRN\tDS16LOCALHEAPBASE:DWORD\n"); + + } + printf( "%s\tENDS\n\n",DATA32_NAME); + + printf( "%s\tSEGMENT\tWORD USE16 PUBLIC '%s'\n",CODE16_NAME,CODE16_CLASS); + for( pmn = pmnFirst; pmn; pmn = pmn->pNextMapping) { + pFNode = pmn->pToNode; + if( pFNode->iCallType == TYPE_API16) + printf( "EXTRN\t%s:FAR\n", pFNode->pchFunctionName); + } + printf( "%s\tENDS\n\n", CODE16_NAME); +} + + +/*** cod_OutputEpilog(pMT) + * + * Outputs any code that belongs at the end of the source file. + * + * Entry: pMT - pointer to the list of mapnodes. + * + * Exit: code for end of source file is generated. + */ + +void cod_OutputEpilog( MapNode *pMT) + +{ + printf("\n\n\tEND\n"); +} + + +/*** cod_ExistsToType + * + * This function returns TRUE iff one of the mapnodes in the list + * has a ToNode of the indicated type. + * + */ + +BOOL +cod_ExistsToType( MapNode *pmnFirst, // pointer to the list of mapnodes + int iCallType) // type of sought ToNode +{ + register MapNode *pmn; + + for( pmn = pmnFirst; pmn; pmn = pmn->pNextMapping) { + if( pmn->pToNode->iCallType == iCallType) + return TRUE; + } + return FALSE; +} + + + +/*** cod_CountPointerParameters + * + * This function returns the number of pointers in a procedure. If the + * fStructOnly is set, it will only return the number of pointers to + * structures. + * + * Entry: pTT - pointer to the first TypeNode in the type table. + * fStructOnly - 1 = only count structure pointers. + * 0 = count all pointers. + * + * Exit: returns the number of pointers in a procedure. + * + * History: + * 28-Nov-1988 JulieB Created it. + * 14-Dec-1988 Kevinro Added recursion to include imbedded pointers + * 02-Feb-1989 Kevinro Added structure flag + */ + +int cod_CountPointerParameters(TypeNode *pTT, + int fStructOnly) + +{ + register TypeNode *pTNode; /* pointer to a TypeNode */ + register int iNumPtrs = 0; /* number of pointer parameters */ + + + for (pTNode = pTT; pTNode != NULL; pTNode = pTNode->pNextNode) { + if (pTNode->iPointerType) { + if (!fStructOnly) { + pTNode->iPointerNumber=iNumPtrs++; + } + else if (pTNode->iBaseType == TYPE_STRUCT) { + pTNode->iPointerNumber=iNumPtrs++; + } + } + if (pTNode->iBaseType == TYPE_STRUCT) { + iNumPtrs += + cod_CountPointerParameters(pTNode->pStructElems,fStructOnly); + } + if (iNumPtrs > 32) { + fprintf(stderr,"Too many pointer parameters - limit is 32\n"); + break; + } + } + return (iNumPtrs); +} + + +/*** cod_CountParameterBytes(pTT, iDefSize) + * + * This function returns the number of bytes in a parameter list. + * + * Entry: pTT - pointer to the first TypeNode in the type table. + * DefSize - parameter default size - based on whether API16 (2) + * or API32 (4). + * + * Exit: returns number of bytes in parameter list. + * + * History: + * 28-Nov-1988 JulieB Created it. + * 08-Mar-1991 KevinR skip deleted nodes + */ + +unsigned int cod_CountParameterBytes( TypeNode *pTT, unsigned int uiDefSize) + +{ + register TypeNode *pTNode; /* pointer to a TypeNode */ + register unsigned int uiNumBytes = 0; /* number of parameter bytes */ + + + for (pTNode = pTT; pTNode; pTNode = pTNode->pNextNode) { + if( !pTNode->iDeleted) { + uiNumBytes += pTNode->iPointerType ? + DWORD_SIZE : + MAX( pTNode->iBaseDataSize, uiDefSize); + } + } + return uiNumBytes; +} + + +/*** cod_MakeFixupRecord(pParent,pFrom,pTo) + * + * This function will allocate and fill in a FixupRec. It will then + * return a pointer to the new record. + * + * Entry: pParent - Parent Node + * pFrom - From node + * pTo - To Node + * + * Exit: Returns the pointer to the new fixup record. + */ + +FixupRec *cod_MakeFixupRecord(TypeNode *pParentFrom, + TypeNode *pParentTo, + TypeNode *pFrom, + TypeNode *pTo) + +{ + FixupRec *temp = NULL; + + + temp = (FixupRec *) malloc(sizeof(FixupRec)); + if (temp) { + temp->pParentFrom = pParentFrom; + temp->pParentTo = pParentTo; + temp->pFrom = pFrom; + temp->pTo = pTo; + temp->pNextRec = NULL; + } else { + fatal("cod_MakeFixupRecord failed memory allocation"); + } + return (temp); +} + + +/*** cod_AddFixupRecord(ppList, pFR) + * + * This routine will add the fixup record pFR to the end of the current + * fixup record list. + * + * Entry: ppList - points to the address of a fixup record list. + * pFR - points to an allocated fixup record. + * + * Exit: pFR - will be appended to the end of the static list FixUps. + */ + +void cod_AddFixupRecord( FixupRec **ppList, FixupRec *pFR) + +{ + FixupRec *index = *ppList; + + + pFR->pNextRec = NULL; + + if (index == NULL) { + *ppList = pFR; + } + else { + while (index->pNextRec) + index = index->pNextRec; + index->pNextRec = pFR; + } +} + + +/*** cod_GetFixupRecord(ppList) + * + * This function removes and returns the head of the ppList list. + * + * Entry: ppList - pointer to address of fixup record list. + * + * Exit: returns the pointer to the node removed from ppList. If + * list was empty, then it returns NULL. + */ + +FixupRec * cod_GetFixupRecord( FixupRec **ppList) + +{ + FixupRec *index = *ppList; + + + if (index) + *ppList = (*ppList)->pNextRec; + return (index); +} + + +/*** cod_AdjustReg(pchReg,iCurrent,iWanted) + * + * This routine will emit code that will ensure that the register named in + * pchReg will have the value in iWanted, based on the current value in + * iCurrent. This includes the ability to add or subtract from pchReg. + * + * Entry: pchReg - register name. + * iCurrent - pointer to current value. + * iWanted - value to be placed in iCurrent. + * + * Exit: generates code to adjust registers. + */ + +void +cod_AdjustReg(char *pchReg, + int *iCurrent, + int iWanted) + +{ + int Delta; + + + if (*iCurrent == iWanted) + return; + + Delta = iWanted - *iCurrent; + if (Delta < 0) { + if (Delta == -1) + printf("\tdec\t%s\n",pchReg); + else + printf("\tsub\t%s,%d\n",pchReg,-Delta); + } + else { + if (Delta == 1) + printf("\tinc\t%s\n",pchReg); + else + printf("\tadd\t%s,%d\n",pchReg,Delta); + } + *iCurrent = iWanted; +} + + +/*** cod_ToUpper(s) + * + * Convert string s to all upper case. + * + * Entry: s == string to convert. + * + * Exit: s == converted string. + */ + +void cod_ToUpper(char *s) + +{ + for( ; *s; s++) + *s = (char)toupper(*s); +} + + +/*** cod_PrefixUnderscore(F) + * + * Insert an underscore in front of node name. + * + * Entry: F - function node to change. + * + * Exit: underscore is inserted in front of node name. + */ + +void cod_PrefixUnderscore(FunctionNode *F) + +{ + char *temp; + + + if (!F) + fatal("cod_PrefixUnderscore(F): F is NULL"); + temp = (char *) malloc(strlen(F->pchFunctionName) + 3); + sprintf(temp,"_%s",F->pchFunctionName); + free(F->pchFunctionName); + F->pchFunctionName = temp; +} + + +/*** cod_NotHandled(CHAR *pszMessage) + * + * Warn that a case is not handled by the thunk compiler. + * Output to stderr and the asm file. + * + * Entry: pszMessage - null-terminated message. + * + * Exit: the warning has been emitted. + */ + +void cod_NotHandled(CHAR *pszMessage) + +{ + fprintf( stderr, "%s, not handled\n", pszMessage); + printf( "\t.err\t\t\t;%s, not handled\n", pszMessage); +} + + + +/***************************************************************************/ +/* Debugging routines */ +/***************************************************************************/ + + +/*** cod_DumpAllowNodes(A) + * + * This function dumps the allow node list. + * + * Entry: A - pointer to allow node. + * + * Exit: allow nodes are dumped. + */ + +void cod_DumpAllowNodes(AllowNode *A) + +{ + if (!A) + return; + fprintf(StdDbg,"AV: "); + while (A) { + fprintf(StdDbg,"%lxh, ",A->ulValue); + A = A->Next; + } +} + + +/*** cod_DumpTNode(T) + * + * This function dumps a type node. + * + * Entry: T - pointer to type node. + * + * Exit: type node is dumped. + */ + +void cod_DumpTNode(TypeNode *T) + +{ + fprintf(StdDbg,"\n%s",T->pchBaseTypeName); + if (T->pchIdent) + fprintf(StdDbg,"\t%s", T->pchIdent); + if (T->iArraySize > 1) + fprintf(StdDbg,"[%u]",T->iArraySize); + fprintf(StdDbg,"\tStructOffset = %u",T->iStructOffset); + if (T->iBaseType == TYPE_STRUCT) + cod_DumpTNodeList(T->pStructElems); + if (T->fSemantics != SEMANTIC_INPUT) + fprintf(StdDbg, "\tfSemantics = 0x%x", T->fSemantics); +} + + +/*** cod_DumpTNodeList(T) + * + * This function dumps the list of type nodes. + * + * Entry: T - pointer to type node list. + * + * Exit: type nodes are dumped. + */ + +void cod_DumpTNodeList(TypeNode *T) + +{ + while (T) { + cod_DumpTNode(T); + T = T->pNextNode; + } +} + + +/*** cod_DumpStructures(T) + * + * This function dumps the structures of a given type node. + * + * Entry: T - pointer to type node. + * + * Exit: type node structures are dumped. + */ + +void cod_DumpStructures(TypeNode *T) + +{ + sym_DumpTNodeList(T); +} + + +/*** cod_DumpTypes(F) + * + * This function dumps all types associated with function node. + * + * Entry: F - pointer to function node. + * + * Exit: type nodes associated with given function node are dumped. + */ + +void cod_DumpTypes(FunctionNode *F) + +{ + TypeNode *t; + + + fprintf(StdDbg,"\n\ncod_DumpTypes for function %s\n\n",F->pchFunctionName); + + t = F->ParamList; + while (t) { + fprintf(StdDbg,"%s offset = %u",typ_NonNull(t->pchIdent),t->iOffset); + if (t->iPointerType) + fprintf(StdDbg,"\ttemp offset = %u ",t->iTempOffset); + fprintf(StdDbg,"\tiBaseDataSize = %u",t->iBaseDataSize); + fprintf(StdDbg,"\t%s",t->iDeleted?"DELETED\t":""); + cod_DumpAllowNodes(t->AllowList); + t = t->pNextNode; + } + fprintf(StdDbg,"\n"); +} + + +/*** cod_DumpMapTable(pMT) + * + * This function dumps the map table. + * + * Entry: pMT - pointer to map table. + * + * Exit: map table is dumped. + */ + +void cod_DumpMapTable(MapNode *pMT) + +{ + MapNode *Diver; + + + fprintf(StdDbg,"\n\nDump of Mapping Table\n"); + + for (; pMT; pMT = pMT->pNextMapping) { + fprintf(StdDbg,"\nParent %s => %s\n", + pMT->pFromNode->pchFunctionName, + pMT->pToNode->pchFunctionName); + + Diver = pMT->pFamily; + + for (; Diver; Diver = Diver->pNextMapping) { + fprintf(StdDbg,"\tChild %s => %s\n", + Diver->pFromNode->pchFunctionName, + Diver->pToNode->pchFunctionName); + + if (Diver->pFamily) { + fprintf(StdDbg,"**** Error: Child has children *****"); + cod_DumpMapTable(Diver->pFamily); + fprintf(StdDbg,"**** End Error Message *****"); + } + } + } +} |