trandecl.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 557 行 · 第 1/2 页

C
557
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wic.h"

static char * NAME_PREFIX = "STRUN"; // struct/union

typedef enum {
    DECL_INFO,
    DECL_TREE_ELEM
} DeclTreeElemType;

struct DeclTreeElem {
    DeclTreeElemType type;
    union {
        pDeclInfo decl;
        pDeclTree list;
    };
};

pDeclTreeElem createDeclTreeElem(DeclTreeElemType type, void *data) {
    pDeclTreeElem newElem = wicMalloc(sizeof *newElem);
    newElem->type = type;
    if (type == DECL_TREE_ELEM) {
        newElem->list = data;
    } else if (type == DECL_INFO) {
        newElem->decl = data;
    } else {
        assert(0);
    }
    return newElem;
}

static void zapDeclTreeElem(void *_elem) {
    pDeclTreeElem elem = _elem;

    if (elem == NULL) {
        return;
    }

    switch(elem->type) {
        case DECL_INFO:
            zapDeclInfo(elem->decl);
            break;
        case DECL_TREE_ELEM:
            zapSLList(elem->list, zapDeclTreeElem);
            break;
        default:
            assert(0);
    }

    wicFree(elem);
}


char *_get1stDclrName(pDclrList list) {
    pDclr dclr;

    rewindCurrSLListPos(list);
    if (!getCurrSLListPosElem(list, &dclr)) {
        reportError(FATAL_INTERNAL, "In _get1stDclrName");
    }
    assert(dclr != NULL);
    assert(dclr->id != NULL);
    return getDclrName(dclr);
}

char *_createUnnamedDeclStructDclrList(pDeclInfo decl) {
    static char noname[] = { "noname           " };
    static unsigned int counter = 1;
    pTokPos endPos;

    sprintf(noname+6, "%d", counter);  // 6 is strlen("noname")
    counter++;

    if (decl->repr.s->body == NULL) {
        endPos = decl->repr.s->name->pos;
    } else {
        endPos = decl->repr.s->body->endPos;
    }

    decl->dclrList = createDclrList (
        createDclr(
            createIDTokenAfter(
                noname,
                endPos
            )
        )
    );

    return noname;
}

static char *_nameUnnamedStruct(pDeclInfo decl, char *baseName, int level){
// Name the sturct/union if it does not have name;
// Return NULL if error occures; Return a named struct otherwise.

    char *name;
    char *retVal;
    int addBase = 1;

    if (decl->storage == STG_TYPEDEF) {
        zapToken(decl->repr.s->name);  decl->repr.s->name = NULL;
        addBase = 0;
    }
    if (decl->repr.s->name == NULL) {
        if (decl->dclrList == NULL) {
            if (level > 0) {
                name = _createUnnamedDeclStructDclrList(decl);
            } else {
                name = "INVALID";
                reportError(RERR_INCOMPLETE_TYPE);
            }
        } else {
            name = _get1stDclrName(decl->dclrList);
        }
    } else {
        name = getTokenIdName(decl->repr.s->name);
        if (decl->dclrList == NULL && level > 0) {
            name = _createUnnamedDeclStructDclrList(decl);
        }
    }
    if (decl->repr.s->name == NULL) {
        if (addBase) {
            retVal = wicMalloc(strlen(baseName) + strlen(name) + 2);
            sprintf(retVal, "%s_%s", baseName, name);
        } else {
            retVal = wicStrdup(name);
        }
        decl->repr.s->name = createIDTokenAfter(
                                retVal,
                                dupTokPos(decl->repr.s->typePos, NULL)
                             );
    }
    retVal = getTokenIdName(decl->repr.s->name);
    return retVal;
}


static int _nameUnnamed(pDeclInfo decl, char *baseName, int level) {
    char *name;

    switch (decl->type) {
    case DIT_ENUM:
    case DIT_SCALAR:
        return 1;
    case DIT_STRUCT_OR_UNION:
        assert(decl->repr.s != NULL);
        name = _nameUnnamedStruct(decl, baseName, level);
        if (name == NULL) {
            reportError(RERR_INCOMPLETE_TYPE);
            return 0;
        }
        if (decl->repr.s->body != NULL) {
            pDeclList list = decl->repr.s->body->declList;
            pDeclInfo node;

            assert(list != NULL);
            rewindCurrSLListPos(list);
            while (getCurrSLListPosElem(list, &node)) {
                incCurrSLListPos(list);
                _nameUnnamed(node, name, level+1);
            }
        }
        return 1;

    case DIT_NULL:
        reportError(RERR_INCOMPLETE_TYPE);
        return 0;

    default:
        assert(0);
    }
    return 1;
}

static pDeclTree _unNestDecl(pDeclInfo decl) {
    pDeclTree retVal = NULL;

    switch (decl->type) {
    case DIT_SCALAR:
        retVal = createSLList();
        addSLListElem(retVal, createDeclTreeElem(DECL_INFO, decl));
        break;

    case DIT_STRUCT_OR_UNION:
    {
        pDeclStructBody body;
        pDeclTree prepend = createSLList();

        body = decl->repr.s->body;
        if (body != NULL) {
            pDeclInfo node;
            pDeclTreeElem node1, node2;
            pDeclTree inside;

            rewindCurrSLListPos(body->declList);

            while (getCurrSLListPosElem(body->declList, &node)) {
                inside = _unNestDecl(node);

                rewindCurrSLListPos(inside);
                if (!getCurrSLListPosElem(inside, &node1)) {
                    reportError(FATAL_INTERNAL, "In _unNestDecl");
                }
                incCurrSLListPos(inside);
                if (getCurrSLListPosElem(inside, &node2))
                {
                    addSLListElem(prepend, node1);
                    setCurrSLListPosElem(body->declList, node2->decl);
                }
                incCurrSLListPos(body->declList);
            }

            if (decl->dclrList != NULL) {
                pDeclInfo newDecl;
                assert(decl->repr.s->typePos != NULL);
                newDecl = dupDeclInfo(decl, decl->repr.s->typePos);
                zapDeclStructBody(newDecl->repr.s->body);
                newDecl->repr.s->body = NULL;
                zapSLList(decl->dclrList, zapDclr);
                decl->dclrList = NULL;

                addSLListElem(prepend, createDeclTreeElem(DECL_INFO, decl));
                retVal = createSLList();
                addSLListElem(retVal,
                    createDeclTreeElem(DECL_TREE_ELEM, prepend) );
                addSLListElem(retVal, createDeclTreeElem(DECL_INFO, newDecl));
            } else {
                addSLListElem(prepend, createDeclTreeElem(DECL_INFO, decl));
                retVal = prepend;
            }
        } else {
            retVal = createSLList();
            addSLListElem(retVal, createDeclTreeElem(DECL_INFO, decl));
        }
        break;
    }

    case DIT_ENUM:
    {
        pDeclEnum e;
        pDclrList saveDclrList;

        e = decl->repr.e;
        assert(e != NULL);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?