📄 mangle.c
字号:
/*
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 + -