summaryrefslogtreecommitdiffstats
path: root/private/os2/client/thunk/thunkcom/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/os2/client/thunk/thunkcom/symtab.c443
1 files changed, 443 insertions, 0 deletions
diff --git a/private/os2/client/thunk/thunkcom/symtab.c b/private/os2/client/thunk/thunkcom/symtab.c
new file mode 100644
index 000000000..b74e19bf1
--- /dev/null
+++ b/private/os2/client/thunk/thunkcom/symtab.c
@@ -0,0 +1,443 @@
+#define SCCSID "@(#)symtab.c 13.13 90/08/28"
+
+/*
+ * Thunk Compiler - Symbol Table Routines.
+ *
+ * This is an OS/2 2.x specific file
+ * Microsoft Confidential
+ *
+ * Copyright (c) Microsoft Corporation 1987, 1988, 1989
+ *
+ * All Rights Reserved
+ *
+ * Written 10/15/88 by Kevin Ross
+ */
+
+
+#include <stdio.h>
+#include "thunk.h"
+#include "types.h"
+#include "symtab.h"
+
+
+extern FILE *StdDbg;
+
+
+/*
+ * BaseTable is used to access the base data types quickly.
+ */
+TypeNode *BaseTable[SYMTAB_LASTBASEUSED];
+
+TypeNode *SymTable= NULL;
+TypeNode *TypeTable = NULL;
+FunctionNode *FunctionTable = NULL;
+MapNode *MapTable = NULL;
+
+char *SemanticTable[5];
+
+
+/*** sym_SymTabInit() - Module initialization Routine
+ *
+ * This routine is called before any other symbol table routines
+ * are used.
+ *
+ * It will setup the table of base types, and initialize any other
+ * needed variables.
+ *
+ * Entry: none
+ *
+ * Exit: tables and variables are initialized.
+ */
+
+void sym_SymTabInit()
+
+{
+ BaseTable[SYMTAB_SHORT] = typ_MakeTypeNode(TYPE_SHORT);
+ BaseTable[SYMTAB_SHORT]->iBaseType = TYPE_SHORT;
+ BaseTable[SYMTAB_SHORT]->iBaseDataSize = 2;
+ BaseTable[SYMTAB_SHORT]->pchBaseTypeName = "short";
+
+ BaseTable[SYMTAB_LONG] = typ_MakeTypeNode(TYPE_LONG);
+ BaseTable[SYMTAB_LONG]->iBaseType = TYPE_LONG;
+ BaseTable[SYMTAB_LONG]->iBaseDataSize = 4;
+ BaseTable[SYMTAB_LONG]->pchBaseTypeName = "long";
+
+ BaseTable[SYMTAB_USHORT] = typ_MakeTypeNode(TYPE_USHORT);
+ BaseTable[SYMTAB_USHORT]->iBaseType = TYPE_USHORT;
+ BaseTable[SYMTAB_USHORT]->iBaseDataSize = 2;
+ BaseTable[SYMTAB_USHORT]->pchBaseTypeName = "unsigned short";
+
+ BaseTable[SYMTAB_ULONG] = typ_MakeTypeNode(TYPE_ULONG);
+ BaseTable[SYMTAB_ULONG]->iBaseType = TYPE_ULONG;
+ BaseTable[SYMTAB_ULONG]->iBaseDataSize = 4;
+ BaseTable[SYMTAB_ULONG]->pchBaseTypeName = "unsigned long";
+
+ BaseTable[SYMTAB_INT] = typ_MakeTypeNode(TYPE_INT);
+ BaseTable[SYMTAB_INT]->iBaseType = TYPE_INT;
+ BaseTable[SYMTAB_INT]->iBaseDataSize = -99;
+ BaseTable[SYMTAB_INT]->pchBaseTypeName = "int";
+
+ BaseTable[SYMTAB_UINT] = typ_MakeTypeNode(TYPE_UINT);
+ BaseTable[SYMTAB_UINT]->iBaseType = TYPE_UINT;
+ BaseTable[SYMTAB_UINT]->iBaseDataSize = -99;
+ BaseTable[SYMTAB_UINT]->pchBaseTypeName = "unsigned int";
+
+ BaseTable[SYMTAB_VOID] = typ_MakeTypeNode(TYPE_VOID);
+ BaseTable[SYMTAB_VOID]->iBaseType = TYPE_VOID;
+ BaseTable[SYMTAB_VOID]->iBaseDataSize = 1;
+ BaseTable[SYMTAB_VOID]->pchBaseTypeName = "void";
+
+ BaseTable[SYMTAB_UCHAR] = typ_MakeTypeNode(TYPE_UCHAR);
+ BaseTable[SYMTAB_UCHAR]->iBaseType = TYPE_UCHAR;
+ BaseTable[SYMTAB_UCHAR]->iBaseDataSize = 1;
+ BaseTable[SYMTAB_UCHAR]->pchBaseTypeName = "unsigned char";
+
+ BaseTable[SYMTAB_CHAR] = typ_MakeTypeNode(TYPE_CHAR);
+ BaseTable[SYMTAB_CHAR]->iBaseType = TYPE_CHAR;
+ BaseTable[SYMTAB_CHAR]->iBaseDataSize = 1;
+ BaseTable[SYMTAB_CHAR]->pchBaseTypeName = "char";
+
+ BaseTable[SYMTAB_STRING] = typ_MakeTypeNode(TYPE_STRING);
+ BaseTable[SYMTAB_STRING]->iBaseDataSize = 1;
+ BaseTable[SYMTAB_STRING]->pchBaseTypeName = "string";
+
+ BaseTable[SYMTAB_NULLTYPE] = typ_MakeTypeNode(TYPE_NULLTYPE);
+ BaseTable[SYMTAB_NULLTYPE]->iBaseType = TYPE_NULLTYPE;
+ BaseTable[SYMTAB_NULLTYPE]->iBaseDataSize = 4;
+ BaseTable[SYMTAB_NULLTYPE]->pchBaseTypeName = "nulltype";
+
+ SemanticTable[0] = "";
+ SemanticTable[1] = "Input";
+ SemanticTable[2] = "Output";
+ SemanticTable[3] = "InOut";
+ SemanticTable[4] = "SizeOf";
+}
+
+
+/*** sym_FindSymbolTypeNode(pTab,pchSym)
+ *
+ * This function will look down the list of symbols - pTab - and
+ * return a pointer to the TypeNode that it finds.
+ *
+ * This is implemented as a linear list to get the compiler up and
+ * running. It should be revised to a faster algorithm.
+ *
+ * Entry: pTab - pointer to list of symbols.
+ * pchSym - pointer to symbol to find.
+ *
+ * Exit: returns a pointer to the typenode.
+ */
+
+TypeNode *sym_FindSymbolTypeNode(TypeNode *pTab,
+ char *pchSym)
+
+{
+ while (pTab && pchSym) {
+ if (pTab->pchIdent) {
+ if (!strcmp(pTab->pchIdent,pchSym))
+ return pTab;
+ }
+ pTab = pTab->pNextNode;
+ }
+ return (NULL);
+}
+
+
+/*** sym_FindSymbolTypeNodePair(pTab1,pTab2,ppT1,ppT2,pchSym)
+ *
+ * This routine will look down the list of symbols - pTab1 - and
+ * return in ppT1 the pointer to the TypeNode it finds that matches
+ * the pchIdent with pchSym. It will also concurrently walk a second
+ * list of symbols, pTab2, and returns ppT2.
+ *
+ * The net result is that FindSymbolTypeNodePair returns the pair of
+ * typenodes that represent the same parameter ordinal in two lists.
+ *
+ * This is implemented as a linear list to get the compiler up and
+ * running. It should be revised to a faster algorithm.
+ */
+
+int sym_FindSymbolTypeNodePair(TypeNode *pTab1,
+ TypeNode *pTab2,
+ TypeNode **ppT1,
+ TypeNode **ppT2,
+ char *pchSym)
+
+{
+ *ppT1 = pTab1;
+ *ppT2 = pTab2;
+
+ while (*ppT1 && *ppT2 && pchSym) {
+ if ((*ppT1)->pchIdent)
+ if (!strcmp((*ppT1)->pchIdent,pchSym))
+ return 1;
+ *ppT1 = (*ppT1)->pNextNode;
+ *ppT2 = (*ppT2)->pNextNode;
+ }
+ return (0);
+}
+
+
+/*** sym_FindSymbolFunctionNode(pTab,pchSym)
+ *
+ * FindSymbolFunctionNode will look down the list of symbols - pTab -
+ * and return a pointer to the FunctionNode that it finds.
+ *
+ * This is implemented as a linear list to get the compiler up and
+ * running. It should be revised to a faster algorithm.
+ */
+
+FunctionNode *sym_FindSymbolFunctionNode(FunctionNode *pTab,
+ char *pchSym)
+
+{
+ while (pTab && pchSym) {
+ if (!strcmp(pTab->pchFunctionName,pchSym))
+ return (pTab);
+ pTab = pTab->pNextFunctionNode;
+ }
+ return (NULL);
+}
+
+
+/*** sym_InsertTypeNode(ppTab,pNode)
+ *
+ * InsertTypeNode will add pNode to the symbol table ppTab.
+ *
+ * This is implemented as a linear list to get the compiler up and
+ * running. This routine will always add the new symbol to the front
+ * of the current list. It should be revised to a algorithm better
+ * for searching.
+ */
+
+void sym_InsertTypeNode(TypeNode **ppTab,
+ TypeNode *pNode)
+
+{
+ if (*ppTab) {
+ pNode->pNextNode = *ppTab;
+ }
+ *ppTab = pNode;
+}
+
+
+/*** sym_InsertFunctionNode(ppTab,pFNode)
+ *
+ * InsertFunctionNode will add pFNode to the symbol table ppTab.
+ *
+ * This is implemented as a linear list to get the compiler up and
+ * running. This routine will always add the new symbol to the front
+ * of the current list. It should be revised to a algorithm better
+ * for searching.
+ */
+
+void sym_InsertFunctionNode(FunctionNode **ppTab,
+ FunctionNode *pFNode)
+
+{
+ if (*ppTab) {
+ pFNode->pNextFunctionNode = *ppTab;
+ }
+ *ppTab = pFNode;
+}
+
+
+/*** sym_ReverseTypeList(pOld)
+ *
+ * ReverseTypeList will reverse the order of a TypeNode linked list.
+ * This is needed in several places in the compiler.
+ */
+
+TypeNode *sym_ReverseTypeList(TypeNode *pOld)
+
+{
+ register TypeNode *pNew, *pNext;
+
+
+ if (! pOld)
+ return pOld;
+
+ pNew = pOld->pNextNode;
+ pOld->pNextNode = NULL;
+
+ while (pNew) {
+ pNext = pNew->pNextNode;
+ pNew->pNextNode = pOld;
+ pOld = pNew;
+ pNew = pNext;
+ }
+ return (pOld);
+}
+
+
+/*** sym_FindFMapping(pMapTab,pSymA,pSymB)
+ *
+ * FindFMapping will search the list pMapTab in search for either pSymA
+ * or pSymB in the pFromName field of the mapping list.
+ */
+
+MapNode *sym_FindFMapping(MapNode *pMapTab,
+ char *pSymA,
+ char *pSymB)
+
+{
+ while (pMapTab) {
+ if (!strcmp(pMapTab->pFromName,pSymA) ||
+ !strcmp(pMapTab->pFromName,pSymB)) {
+ return (pMapTab);
+ }
+ pMapTab = pMapTab->pNextMapping;
+ }
+ return (NULL);
+}
+
+
+/*** sym_AddFMapping(ppMapTab,pFuncA,pFuncB)
+ *
+ * AddFMapping accepts two FunctionNode pointers, and a table.
+ * It will create a MapNode containing link information to the two
+ * functions. The mapping id is contained in pFromName.
+ */
+
+MapNode *sym_AddFMapping(MapNode **ppMapTab,
+ FunctionNode *pFuncA,
+ FunctionNode *pFuncB)
+
+{
+ MapNode *temp,*ptr;
+
+
+ if (temp = (MapNode *) malloc(sizeof(MapNode))) {
+ temp->pFromName = pFuncA->pchFunctionName;
+ temp->pFromNode = pFuncA;
+ temp->pToNode = pFuncB;
+ temp->pNextMapping = NULL;
+ temp->pFamily = NULL;
+
+ ptr = *ppMapTab;
+ if (!ptr)
+ *ppMapTab = temp;
+ else {
+ while (ptr->pNextMapping)
+ ptr = ptr->pNextMapping;
+ ptr->pNextMapping = temp;
+ }
+ return (*ppMapTab);
+ }
+ else
+ fatal("sym_AddFMapping malloc failure");
+}
+
+
+
+/***********************************************************************/
+/* Dump Routines: Used for debugging output only. */
+/***********************************************************************/
+
+static char IndentString[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+
+static int ILevel = 18;
+
+
+void sym_DumpFNode(FunctionNode *F)
+
+{
+ fprintf(StdDbg,"\nFunction Node: %s\n",F->pchFunctionName);
+ fprintf(StdDbg,"Call Type: %s\n",
+ (F->iCallType == TYPE_API16) ? "API16":"API32");
+ fprintf(StdDbg,"System Call Convention: %s\n",F->fSysCall?"TRUE":"FALSE");
+ fprintf(StdDbg,"Ring Type: %s\n",
+ (F->fConforming) ? "Conforming":"Normal");
+ fprintf(StdDbg,"Return Type: ");
+
+ sym_DumpTNode(F->ReturnType);
+
+ fprintf(StdDbg,"ErrBadParam = %lu\n",F->ulErrBadParam);
+ fprintf(StdDbg,"ErrNoMem = %lu\n",F->ulErrNoMem);
+ fprintf(StdDbg,"MinStack = %d\tInlineCode = %s\n",F->iMinStack,
+ (F->fInlineCode) ? "TRUE" : "FALSE");
+
+ fprintf(StdDbg,"Maps to function: %s\n",F->pMapsToFunction->pchFunctionName);
+
+ fprintf(StdDbg,"Parameter Types:\n");
+
+ ILevel--;
+ sym_DumpTNodeList(F->ParamList);
+ ILevel++;
+ fprintf(StdDbg,"\n");
+}
+
+
+void sym_DumpFNodeList(FunctionNode *F)
+
+{
+ for( ; F; F = F->pNextFunctionNode)
+ sym_DumpFNode( F);
+}
+
+
+void sym_DumpTNode(TypeNode *T)
+
+{
+ fprintf(StdDbg,"%s",&IndentString[ILevel]);
+
+ fprintf(StdDbg,"%s",(T->iPointerType) ?
+ ((T->iPointerType == TYPE_FAR16) ? "FAR16 ":
+ ((T->iPointerType == TYPE_NEAR32) ? "NEAR32 ":"PTR ")):"");
+ fprintf(StdDbg,"%s",T->pchBaseTypeName);
+ if (T->pchIdent)
+ fprintf(StdDbg,"\t%s", T->pchIdent);
+ if (T->iArraySize > 1)
+ fprintf(StdDbg,"[%u]",T->iArraySize);
+ fprintf(StdDbg," #SO %u BS %u #",T->iStructOffset,T->iBaseDataSize);
+ if (T->iDeleted)
+ fprintf(StdDbg," DELETED fv=%lu ",T->iFillValue);
+ if (T->iBaseType == TYPE_STRUCT) {
+ fprintf(StdDbg," Aligned %d",T->iAlignment);
+ fprintf(StdDbg,"\n%s",&IndentString[ILevel--]);
+ fprintf(StdDbg,"{\n");
+ sym_DumpTNodeList(T->pStructElems);
+ fprintf(StdDbg,"%s",&IndentString[++ILevel]);
+ fprintf(StdDbg,"}");
+ }
+
+ sym_DumpSemantics(T);
+ fprintf(StdDbg,"\n");
+}
+
+
+void sym_DumpTNodeList(TypeNode *T)
+
+{
+ for( ; T; T = T->pNextNode)
+ sym_DumpTNode(T);
+}
+
+
+void sym_DumpSemantics(TypeNode *T)
+
+{
+ fprintf(StdDbg,";");
+ if (SemanticTable[T->fSemantics & 3]) {
+ fprintf(StdDbg,"\t%s",SemanticTable[T->fSemantics & 3]);
+ }
+
+ if (T->fSemantics & SEMANTIC_SIZE)
+ fprintf(StdDbg,"\tSizeOf %s", T->pParamSizeOf->pchIdent);
+
+ if (T->fSemantics & SEMANTIC_COUNT)
+ fprintf(StdDbg,"\tCountOf %s", T->pParamSizeOf->pchIdent);
+}
+
+
+void sym_DumpFMappingList(MapNode *M)
+
+{
+ fprintf(StdDbg,"\nFunction Map Table\n\n");
+ while (M) {
+ fprintf(StdDbg,"\nMapping Id: %s\t",M->pFromName);
+ fprintf(StdDbg,"Maps %s => %s\n",M->pFromNode->pchFunctionName,
+ M->pToNode->pchFunctionName);
+ M = M->pNextMapping;
+ }
+}