⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mangle.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
Copyright 1994-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
/* Handles name mangling
 */
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"

extern TABLE lsyms,  *gsyms;
extern int prm_cplusplus, prm_cmangle;
extern SYM *declclass;
extern SYM *typequal;
extern char *templatePrefix;
extern TYP stdvoidfunc;
extern char *cpponearg(char *buf, TYP *tp);
extern struct template  *currentTemplate,  *searchTemplate;
extern SYM *parm_namespaces[20][100];
extern int parm_ns_counts[20];
extern int parm_ns_level;
extern int parsing_params;


char *unmang1(char *buf, char *name, int firsttime);

    char *tn_void = "void";
    char *tn_char = "char";
    char *tn_int = "int";
    char *tn_long = "long";
    char *tn_longlong = "long long";
    char *tn_short = "short ";
    char *tn_unsigned = "unsigned ";
    char *tn_ellipse = "...";
    char *tn_float = "float";
    char *tn_double = "double";
    char *tn_longdouble = "long double";
    char *tn_vol = " volatile ";
    char *tn_const = " const ";
    char *tn_class = "class ";
    char *tn_struct = "struct ";
    char *tn_union = "union ";
    char *tn_fcomplex = "float complex";
    char *tn_rcomplex = "double complex";
    char *tn_lrcomplex = "long double complex";

    char *cpp_funcname_tab[] = 
    {
        "$bctr", "$bdtr", "$bnew", "$bdel", "$badd", "$bsub", "$bmul", "$bdiv",
            "$bshl", "$bshr", "$bmod", "$bequ", "$bneq", "$blt", "$bleq", 
            "$bgt", "$bgeq", "$basn", "$basadd", "$bassub", "$basmul", 
            "$basdiv", "$basmod", "$basshl", "$bsasshr", "$basand", "$basor", 
            "$basxor", "$binc", "$bdec", "$barray", "$bcast", "$bpstar", 
            "$barrow", "$blor", "$bland", "$bnot", "$bor", "$band", "$bxor", 
            "$bcpl", "$bnwa", "$bdla", 

    };
    char *xlate_tab[] = 
    {
        0, 0, "new", "delete", "+", "-", "*", "/", "<<", ">>", "%", "==", "!=",
            "<", "<=", ">", ">=", "=", "+=", "-=", "*=", "/=", "%=", "<<=", 
            ">>=", "&=", "|=", "^=", "++", "--", "[]", "()", "->*", "->", "||",
            "&&", "!", "|", "&", "^", "~", "new[]", "delete[]"
    };
    #define IT_THRESHOLD 2
    #define IT_OV_THRESHOLD 2
    #define IT_SIZE (sizeof(cpp_funcname_tab)/sizeof(char *))

#define MAX_MANGLE_NAME_COUNT 36

char *cppargs(char *buf, SYM *sp);
static char *unmangcppfunc(char *buf, char *name, int firsttime);
static char *unmangcpptype(char *buf, char *name, int firsttime);
char *cpponearg(char *buf, TYP *tp);
char *unmang1(char *buf, char *name, int firsttime);
int manglenamecount =  - 1;
static char manglenames[MAX_MANGLE_NAME_COUNT][512];

    void cpp_unmang_intrins(char **buf, char **name, char *last)
    {
        char cur[245],  *p = cur,  *q;
        int i;
        *p++ = *(*name)++;
        while (**name != '@' &&  **name != '$' &&  **name)
            *p++ = *(*name)++;
        *p = 0;
        if (cur[1] == 'o')
        {
            strcpy(*buf, "operator ");
            *buf += strlen(*buf);
            unmang1(*buf, cur + 2, FALSE);
        }
        else
        {
            for (i = 0; i < IT_SIZE; i++)
                if (!strcmp(cur, cpp_funcname_tab[i]))
                    break;
            if (i >= IT_SIZE)
                strcpy(*buf, cur);
            else
            {
                if (i < IT_THRESHOLD)
                {
                    switch (i)
                    {
                        case 1:
                            *(*buf)++ = '~';
                        case 0:
                            strcpy(*buf, last);
                            break;
                    }
                }
                else
                {
                    strcpy(*buf, "operator ");
                    strcat(*buf, xlate_tab[i]);
                }
            }
        }
        *buf += strlen(*buf);

    }
/* Insert an overloaded function ref into the function table
 */
void funcrefinsert(char *name, SYM *refsym, TABLE *tbl, SYM *insp)
{
        char buf[100];
        SYM *sp,  *sp1;
        sp1 = search2(name, tbl, FALSE, TRUE);
        if (sp1)
            insert(refsym, &sp1->tp->lst);
        else
        {
            sp = makesym(sc_defunc);
            sp->name = litlate(name);
            sp->tp = maketype(bt_defunc, 0);
            sp->tp->sp = sp;
            sp->tp->lst.head = sp->tp->lst.tail = refsym;
            sp->parentclass = insp;
            insert(sp, tbl);
        }
}

//-------------------------------------------------------------------------

    static int templateNameSearch(TYP *typ1, TYP *typ2)
    {
        while (typ1->type == bt_pointer && typ2->type == bt_pointer)
        {
            typ1 = typ1->btp, typ2 = typ2->btp;
        }
        if (isstructured(typ1) && isstructured(typ2))
        {
            SYM *sp2 = currentTemplate->classes.head;
            SYM *sp1 = searchTemplate->classes.head;
            while (sp1 && sp2)
            {
                if (!strcmp(sp2->name, typ2->sp->name))
                    if (!strcmp(sp1->name, typ1->sp->name))
                        return TRUE;
                    else
                        return FALSE;
                sp1 = sp1->next;
                sp2 = sp2->next;
            }

        }
        return FALSE;
    }
    int matchone(SYM *sp1, SYM *sp2, ENODE *node, int nodefault, int any)
    {
        int rv = 1;
        CLASSLIST *l;
        ENODE *ep = node;
        /* don't match templates here */
        while (sp1 && sp1 != (SYM*) - 1 && sp2 && sp2 != (SYM*) - 1)
        {
            if (!exactype(sp1->tp, sp2->tp, FALSE))
            {
                TYP *typ1 = sp1->tp;
                TYP *typ2 = sp2->tp;
                if (typ1->type == bt_ellipse || typ2->type == bt_ellipse)
                    return rv;
                if (typ1->type == bt_ref)
                    typ1 = typ1->btp;
                if (typ2->type == bt_ref)
                    typ2 = typ2->btp;
                if (typ1->type == bt_pointer && typ2->type == bt_pointer &&
                    typ1->btp->type == bt_void)
                    rv = 2;
                else if (isscalar(typ1) && isscalar(typ2) && typ1->type !=
                    bt_enum)
                    rv = 2;
                else if (typ2->type == bt_defunc)
                {
                    if (typ1->type == bt_pointer && (typ1->btp->type == bt_func
                        || typ1->btp->type == bt_ifunc))
                    {
                        if (!funcovermatch2(typ2->sp, typ1->btp, 0, FALSE,
                            FALSE, FALSE))
                            return 0;
                    }
                    else
                        return 0;
                }
                else if (typ1->type == bt_memberptr)
                {
                    if (typ2->type == bt_memberptr && typ2->btp && typ2->btp
                        ->type == bt_defunc)
                    {
                        if (!funcovermatch2(typ2->btp->sp, typ1->btp, node,
                            FALSE, FALSE, FALSE))
                            return 0;
                    }
                    else
                        if (!isscalar(typ2) || !ep || ep->v.p[0]->nodetype !=
                            en_icon || ep->v.p[0]->v.i != 0)
                            return 0;
                }
                else if (currentTemplate && searchTemplate &&
                    templateNameSearch(typ1, typ2))
                {
                    ; // empty statement
                }
                else if (any && isstructured(typ1))
                {
                    SYM *sp3 = search(cpp_funcname_tab[CI_CONSTRUCTOR], &typ1
                        ->lst);
                    if (!sp3)
                        return 0;
                    sp3 = sp3->tp->lst.head;
                    while (sp3)
                    {
                        if (sp3 && sp3->tp->lst.head == sp3->tp->lst.tail)
                        {
                            if (exactype(sp3->tp->lst.head->tp, typ2, FALSE))
                                goto join;
                        }
                        sp3 = sp3->next;
                    }
                    if (isstructured(typ2) && typ2->sp
                        ->value.classdata.baseclass)
                    {
                        l = typ2->sp->value.classdata.baseclass->link;
                        while (l)
                        {
                            if (l->data->mainsym == typ1->sp->mainsym)
                                break;
                            l = l->link;
                        }
                        if (!l)
                            return 0;
                    }
                    else
                        return 0;
                }
                else if (typ1->type == bt_pointer && isstructured(typ1->btp))
                {
                    if (typ2->type == bt_pointer && isstructured(typ2->btp))
                    {
                        if (typ2->btp->sp->value.classdata.baseclass)
                        {
                            l = typ2->btp->sp->value.classdata.baseclass->link;
                            while (l)
                            {
                                if (l->data->mainsym == typ1->btp->sp->mainsym)
                                    break;
                                l = l->link;
                            }
                            if (!l)
                                return 0;
                        }
                        else
                            return 0;
                    }
                    else
                        if (!isscalar(typ2) || !ep || ep->v.p[0]->nodetype !=
                            en_icon || ep->v.p[0]->v.i != 0)
                            return 0;
                }
                else
                    if (typ1->type != bt_pointer || !isscalar(typ2) || !ep ||
                        ep->v.p[0]->nodetype != en_icon || ep->v.p[0]->v.i != 0)
                        return 0;
            } else if (!checktypeassign(sp1->tp,sp2->tp))
                return 0;
            join: sp1 = sp1->next;
            sp2 = sp2->next;
            if (ep)
                ep = ep->v.p[1];
        }
        /* If we get here one of the lists has quit.  If it isn't sp2
         * or if there is no defalt value, bail
         */
        if (!sp1 && !sp2)
            return rv;
        if (sp1 == (SYM*) - 1)
            if (sp2 == (SYM*) - 1 || sp2 && sp2->tp->type == bt_void)
                return rv;
        if (sp2 && sp2 != (SYM*) - 1)
            return 0;
        if (sp1 && sp1 != (SYM*) - 1 && !nodefault && sp1
            ->value.classdata.defalt)
            return rv;
        return 0;
    }
/* Search the tables looking for a match for an argument type list */
int funciterate(SYM *sp1, TYP *tp, ENODE *node, int nodefault, int any, SYM
    **sp2, SYM **sp3, SYM **sp4)
{
    while (sp1 && sp1 != (SYM*) - 1)
    {
        if (!sp1->istemplate && !sp1->isinsttemplate)
        {
            switch (matchone(sp1->tp->lst.head, tp->lst.head, node, nodefault,
                any))
            {
                case 0:
                default:
                    break;
                case 1:
                    if (*sp2)
                    {
                        genfunc2error(ERR_AMBIGFUNC, funcwithns(sp1),
                            funcwithns(*sp2));
                        return TRUE;
                    }
                    else
                         *sp2 = sp1;
                    break;
                case 2:
                    if (! *sp3)
                        *sp3 = sp1;
                    else
                        if (! *sp4)
                            *sp4 = sp1;
                    break;
            }
        }
        sp1 = sp1->next;
    }
    return FALSE;
}

//-------------------------------------------------------------------------

SYM *funcovermatch2(SYM *tbsym, TYP *tp, ENODE *node, int exact, int nodefault,
    int any)
{
        int i;
        SYM *sp1 = tbsym->tp->lst.head;
        SYM *sp2 = 0;
        SYM *sp3 = 0,  *sp4 = 0;
        if (funciterate(sp1, tp, node, nodefault, any, &sp2, &sp3, &sp4))
            return sp2;
        for (i = 0; i < parm_ns_counts[parm_ns_level - 1]; i++)
        {
            SYM *spx = namespace_search(tbsym->name,
                parm_namespaces[parm_ns_level - 1][i]->value.classdata.parentns,
                FALSE);
            if (spx && spx->mainsym != tbsym->mainsym)
                if (funciterate(spx->tp->lst.head, tp, node, nodefault, any,
                    &sp2, &sp3, &sp4))
                    return sp2;
        }
        if (sp2 || exact)
            return sp2;
        if (sp3 && sp4)
            genfunc2error(ERR_AMBIGFUNC, funcwithns(sp3), funcwithns(sp4));
        return sp3;
}

//-------------------------------------------------------------------------

SYM *funcovermatch(SYM *tbsym, TYP *tp, ENODE *ep, int exact, int nodefault)
{

    SYM *sp;
    sp = funcovermatch2(tbsym, tp, ep, exact, nodefault, FALSE);
    if (sp)
        return sp;
    return funcovermatch2(tbsym, tp, ep, exact, nodefault, TRUE);

}

⌨️ 快捷键说明

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