summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/C/CMangler.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/FrontEnd/C/CMangler.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-main.tar.gz
MWCC-main.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/FrontEnd/C/CMangler.c')
-rw-r--r--compiler_and_linker/FrontEnd/C/CMangler.c713
1 files changed, 713 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/C/CMangler.c b/compiler_and_linker/FrontEnd/C/CMangler.c
new file mode 100644
index 0000000..615abf5
--- /dev/null
+++ b/compiler_and_linker/FrontEnd/C/CMangler.c
@@ -0,0 +1,713 @@
+#include "compiler/CMangler.h"
+#include "compiler/CError.h"
+#include "compiler/CInt64.h"
+#include "compiler/CFunc.h"
+#include "compiler/CParser.h"
+#include "compiler/CTemplateTools.h"
+#include "compiler/CompilerTools.h"
+#include "compiler/enode.h"
+#include "compiler/objects.h"
+#include "compiler/scopes.h"
+#include "compiler/templates.h"
+#include "compiler/types.h"
+#include "cos.h"
+
+HashNameNode *constructor_name_node;
+HashNameNode *destructor_name_node;
+HashNameNode *asop_name_node;
+
+// forward decls
+static void CMangler_MangleClassName(TypeClass *tclass);
+static void CMangler_MangleTypeAppend(Type *type, UInt32 qual);
+static void CMangler_MangleArgs(FuncArg *args);
+
+void CMangler_Setup(void) {
+ constructor_name_node = GetHashNameNodeExport("__ct");
+ destructor_name_node = GetHashNameNodeExport("__dt");
+ asop_name_node = GetHashNameNodeExport("__as");
+}
+
+HashNameNode *CMangler_BasicDtorName(void) {
+ return GetHashNameNodeExport("__dtb");
+}
+
+HashNameNode *CMangler_VBaseDtorName(void) {
+ return GetHashNameNodeExport("__dtv");
+}
+
+HashNameNode *CMangler_ArrayDtorName(void) {
+ return GetHashNameNodeExport("__dta");
+}
+
+HashNameNode *CMangler_SDeleteDtorName(void) {
+ return GetHashNameNodeExport("__dts");
+}
+
+HashNameNode *CMangler_DeleteDtorName(void) {
+ return GetHashNameNodeExport("__dt");
+}
+
+char *CMangler_GetOperator(HashNameNode *name) {
+ char *str;
+
+ if (name == asop_name_node)
+ return "operator=";
+
+ str = name->name;
+ if (!strcmp(str, "__nw")) return "operator new";
+ if (!strcmp(str, "__dl")) return "operator delete";
+ if (!strcmp(str, "__nwa")) return "operator new[]";
+ if (!strcmp(str, "__dla")) return "operator delete[]";
+ if (!strcmp(str, "__pl")) return "operator+";
+ if (!strcmp(str, "__mi")) return "operator-";
+ if (!strcmp(str, "__ml")) return "operator*";
+ if (!strcmp(str, "__dv")) return "operator/";
+ if (!strcmp(str, "__md")) return "operator%";
+ if (!strcmp(str, "__er")) return "operator^";
+ if (!strcmp(str, "__ad")) return "operator&";
+ if (!strcmp(str, "__or")) return "operator|";
+ if (!strcmp(str, "__co")) return "operator~";
+ if (!strcmp(str, "__nt")) return "operator!";
+ if (!strcmp(str, "__lt")) return "operator<";
+ if (!strcmp(str, "__gt")) return "operator>";
+ if (!strcmp(str, "__apl")) return "operator+=";
+ if (!strcmp(str, "__ami")) return "operator-=";
+ if (!strcmp(str, "__amu")) return "operator*=";
+ if (!strcmp(str, "__adv")) return "operator/=";
+ if (!strcmp(str, "__amd")) return "operator%=";
+ if (!strcmp(str, "__aer")) return "operator^=";
+ if (!strcmp(str, "__aad")) return "operator&=";
+ if (!strcmp(str, "__aor")) return "operator|=";
+ if (!strcmp(str, "__ls")) return "operator<<";
+ if (!strcmp(str, "__rs")) return "operator>>";
+ if (!strcmp(str, "__als")) return "operator<<=";
+ if (!strcmp(str, "__ars")) return "operator>>=";
+ if (!strcmp(str, "__eq")) return "operator==";
+ if (!strcmp(str, "__ne")) return "operator!=";
+ if (!strcmp(str, "__le")) return "operator<=";
+ if (!strcmp(str, "__ge")) return "operator>=";
+ if (!strcmp(str, "__aa")) return "operator&&";
+ if (!strcmp(str, "__oo")) return "operator||";
+ if (!strcmp(str, "__pp")) return "operator++";
+ if (!strcmp(str, "__mm")) return "operator--";
+ if (!strcmp(str, "__cm")) return "operator,";
+ if (!strcmp(str, "__rm")) return "operator->*";
+ if (!strcmp(str, "__rf")) return "operator*";
+ if (!strcmp(str, "__cl")) return "operator()";
+ if (!strcmp(str, "__vc")) return "operator[]";
+ return NULL;
+}
+
+HashNameNode *CMangler_OperatorName(short token) {
+ switch (token) {
+ case TK_NEW: return GetHashNameNodeExport("__nw");
+ case TK_DELETE: return GetHashNameNodeExport("__dl");
+ case TK_NEW_ARRAY: return GetHashNameNodeExport("__nwa");
+ case TK_DELETE_ARRAY: return GetHashNameNodeExport("__dla");
+ case '+': return GetHashNameNodeExport("__pl");
+ case '-': return GetHashNameNodeExport("__mi");
+ case '*': return GetHashNameNodeExport("__ml");
+ case '/': return GetHashNameNodeExport("__dv");
+ case '%': return GetHashNameNodeExport("__md");
+ case '^': return GetHashNameNodeExport("__er");
+ case '&': return GetHashNameNodeExport("__ad");
+ case '|': return GetHashNameNodeExport("__or");
+ case '~': return GetHashNameNodeExport("__co");
+ case '!': return GetHashNameNodeExport("__nt");
+ case '=': return asop_name_node;
+ case '<': return GetHashNameNodeExport("__lt");
+ case '>': return GetHashNameNodeExport("__gt");
+ case TK_ADD_ASSIGN: return GetHashNameNodeExport("__apl");
+ case TK_SUB_ASSIGN: return GetHashNameNodeExport("__ami");
+ case TK_MULT_ASSIGN: return GetHashNameNodeExport("__amu");
+ case TK_DIV_ASSIGN: return GetHashNameNodeExport("__adv");
+ case TK_MOD_ASSIGN: return GetHashNameNodeExport("__amd");
+ case TK_XOR_ASSIGN: return GetHashNameNodeExport("__aer");
+ case TK_AND_ASSIGN: return GetHashNameNodeExport("__aad");
+ case TK_OR_ASSIGN: return GetHashNameNodeExport("__aor");
+ case TK_SHL: return GetHashNameNodeExport("__ls");
+ case TK_SHR: return GetHashNameNodeExport("__rs");
+ case TK_SHL_ASSIGN: return GetHashNameNodeExport("__als");
+ case TK_SHR_ASSIGN: return GetHashNameNodeExport("__ars");
+ case TK_LOGICAL_EQ: return GetHashNameNodeExport("__eq");
+ case TK_LOGICAL_NE: return GetHashNameNodeExport("__ne");
+ case TK_LESS_EQUAL: return GetHashNameNodeExport("__le");
+ case TK_GREATER_EQUAL: return GetHashNameNodeExport("__ge");
+ case TK_LOGICAL_AND: return GetHashNameNodeExport("__aa");
+ case TK_LOGICAL_OR: return GetHashNameNodeExport("__oo");
+ case TK_INCREMENT: return GetHashNameNodeExport("__pp");
+ case TK_DECREMENT: return GetHashNameNodeExport("__mm");
+ case ',': return GetHashNameNodeExport("__cm");
+ case TK_ARROW_STAR: return GetHashNameNodeExport("__rm");
+ case TK_ARROW: return GetHashNameNodeExport("__rf");
+ case '(': return GetHashNameNodeExport("__cl");
+ case '[': return GetHashNameNodeExport("__vc");
+ default: return NULL;
+ }
+}
+
+HashNameNode *CMangler_VTableName(TypeClass *theclass) {
+ HashNameNode *name;
+
+ name_mangle_list.size = 0;
+ AppendGListName(&name_mangle_list, "__vt__");
+ CMangler_MangleClassName(theclass);
+ AppendGListByte(&name_mangle_list, 0);
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual) {
+ HashNameNode *name;
+
+ name_mangle_list.size = 0;
+ AppendGListName(&name_mangle_list, "__RTTI__");
+ CMangler_MangleTypeAppend(type, qual);
+ AppendGListByte(&name_mangle_list, 0);
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+HashNameNode *CMangler_ThunkName(Object *vfunc, SInt32 this_delta, SInt32 return_delta, SInt32 ctoroffset) {
+ HashNameNode *linkname;
+ HashNameNode *name;
+ char buf[64];
+
+ linkname = CMangler_GetLinkName(vfunc);
+ name_mangle_list.size = 0;
+ if (return_delta == 0) {
+ if (ctoroffset < 0)
+ sprintf(buf, "_@%" PRId32 "@", -this_delta);
+ else
+ sprintf(buf, "_@%" PRId32 "@%" PRId32 "@", -this_delta, ctoroffset);
+ } else {
+ sprintf(buf, "_@%" PRId32 "@%" PRId32 "@%" PRId32 "@", -this_delta, ctoroffset, return_delta);
+ }
+ AppendGListName(&name_mangle_list, buf);
+ AppendGListID(&name_mangle_list, linkname->name + 1);
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+static void CMangler_CheckTemplateArguments(TemplArg *arg) {
+ ENode *expr;
+
+ while (arg) {
+ if (arg->pid.type == TPT_NONTYPE) {
+ expr = arg->data.paramdecl.expr;
+ CError_ASSERT(360, expr);
+ if (expr->rtype->type != TYPETEMPLDEPEXPR) {
+ switch (expr->type) {
+ case EINTCONST:
+ break;
+ case EOBJREF:
+ CMangler_GetLinkName(expr->data.objref);
+ break;
+ default:
+ CError_FATAL(383);
+ }
+ }
+ }
+ arg = arg->next;
+ }
+}
+
+static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
+ ENode *expr;
+ char buf[32];
+
+ AppendGListByte(&name_mangle_list, '<');
+
+ while (arg) {
+ if (arg->pid.type == TPT_NONTYPE) {
+ expr = arg->data.paramdecl.expr;
+ CError_ASSERT(409, expr);
+ if (expr->rtype->type != TYPETEMPLDEPEXPR) {
+ switch (expr->type) {
+ case EINTCONST:
+ CInt64_PrintDec(buf, expr->data.intval);
+ AppendGListName(&name_mangle_list, buf);
+ break;
+ case EOBJREF:
+ AppendGListByte(&name_mangle_list, '&');
+ AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
+ break;
+ default:
+ CError_FATAL(452);
+ }
+ } else {
+ AppendGListByte(&name_mangle_list, 'T');
+ }
+ } else if (arg->pid.type == TPT_TYPE) {
+ CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
+ } else {
+ CError_ASSERT(467, arg->pid.type == TPT_TEMPLATE);
+ CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
+ }
+
+ if (arg->next)
+ AppendGListByte(&name_mangle_list, ',');
+ arg = arg->next;
+ }
+
+ AppendGListByte(&name_mangle_list, '>');
+}
+
+HashNameNode *CMangler_TemplateInstanceName(HashNameNode *basename, TemplArg *args) {
+ HashNameNode *name;
+
+ CMangler_CheckTemplateArguments(args);
+ name_mangle_list.size = 0;
+ AppendGListName(&name_mangle_list, basename->name);
+ CMangler_AppendTemplateArgumentList(args);
+ AppendGListByte(&name_mangle_list, 0);
+
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+static void CMangler_MangleTypeName(char *str) {
+ char buf[16];
+
+ sprintf(buf, "%d", strlen(str));
+ AppendGListName(&name_mangle_list, buf);
+ AppendGListName(&name_mangle_list, str);
+}
+
+static void CMangler_MangleNameSpaceName(NameSpace *nspace, char *str) {
+ char *stack[10];
+ int stackp;
+
+ stack[0] = str;
+ stackp = 1;
+ while (nspace) {
+ if (nspace->name) {
+ stack[stackp++] = nspace->name->name;
+ if (stackp >= 9)
+ break;
+ }
+ nspace = nspace->parent;
+ }
+
+ if (stackp > 1) {
+ AppendGListByte(&name_mangle_list, 'Q');
+ AppendGListByte(&name_mangle_list, '0' + stackp);
+ }
+
+ while (--stackp >= 0)
+ CMangler_MangleTypeName(stack[stackp]);
+}
+
+static void CMangler_MangleClassName(TypeClass *tclass) {
+ if (!tclass->classname)
+ CMangler_MangleNameSpaceName(tclass->nspace->parent, "class");
+ else
+ CMangler_MangleNameSpaceName(tclass->nspace->parent, tclass->nspace->name->name);
+}
+
+static void CMangler_MangleQualifier(UInt32 qual) {
+ if (qual & Q_CONST)
+ AppendGListByte(&name_mangle_list, 'C');
+ if (qual & Q_VOLATILE)
+ AppendGListByte(&name_mangle_list, 'V');
+}
+
+static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
+ char buf[16];
+
+ switch (type->type) {
+ case TYPEVOID:
+ CMangler_MangleQualifier(qual);
+ AppendGListByte(&name_mangle_list, 'v');
+ break;
+ case TYPEINT:
+ case TYPEFLOAT:
+ CMangler_MangleQualifier(qual);
+ switch (TYPE_INTEGRAL(type)->integral) {
+ case IT_BOOL:
+ AppendGListByte(&name_mangle_list, 'b');
+ return;
+ case IT_CHAR:
+ AppendGListByte(&name_mangle_list, 'c');
+ return;
+ case IT_WCHAR_T:
+ AppendGListByte(&name_mangle_list, 'w');
+ return;
+ case IT_UCHAR:
+ AppendGListName(&name_mangle_list, "Uc");
+ return;
+ case IT_SCHAR:
+ AppendGListName(&name_mangle_list, "Sc");
+ return;
+ case IT_SHORT:
+ AppendGListByte(&name_mangle_list, 's');
+ return;
+ case IT_USHORT:
+ AppendGListName(&name_mangle_list, "Us");
+ return;
+ case IT_INT:
+ AppendGListByte(&name_mangle_list, 'i');
+ return;
+ case IT_UINT:
+ AppendGListName(&name_mangle_list, "Ui");
+ return;
+ case IT_LONG:
+ AppendGListByte(&name_mangle_list, 'l');
+ return;
+ case IT_ULONG:
+ AppendGListName(&name_mangle_list, "Ul");
+ return;
+ case IT_LONGLONG:
+ AppendGListByte(&name_mangle_list, 'x');
+ return;
+ case IT_ULONGLONG:
+ AppendGListName(&name_mangle_list, "Ux");
+ return;
+ case IT_FLOAT:
+ AppendGListByte(&name_mangle_list, 'f');
+ return;
+ case IT_SHORTDOUBLE:
+ AppendGListByte(&name_mangle_list, 'D');
+ return;
+ case IT_DOUBLE:
+ AppendGListByte(&name_mangle_list, 'd');
+ return;
+ case IT_LONGDOUBLE:
+ AppendGListByte(&name_mangle_list, 'r');
+ return;
+ default:
+ CError_FATAL(619);
+ }
+ case TYPEENUM:
+ CMangler_MangleQualifier(qual);
+ if (!TYPE_ENUM(type)->enumname)
+ CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, "enum");
+ else
+ CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, TYPE_ENUM(type)->enumname->name);
+ break;
+ case TYPEPOINTER:
+ CMangler_MangleQualifier(TYPE_POINTER(type)->qual);
+ if (TYPE_POINTER(type)->qual & Q_REFERENCE)
+ AppendGListByte(&name_mangle_list, 'R');
+ else
+ AppendGListByte(&name_mangle_list, 'P');
+ CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
+ break;
+ case TYPEMEMBERPOINTER:
+ if (TYPE_MEMBER_POINTER(type)->ty2->type != TYPECLASS) {
+ AppendGListName(&name_mangle_list, "3<T>");
+ } else {
+ CMangler_MangleQualifier(TYPE_MEMBER_POINTER(type)->qual);
+ AppendGListByte(&name_mangle_list, 'M');
+ CMangler_MangleClassName(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2));
+ CMangler_MangleTypeAppend(TYPE_MEMBER_POINTER(type)->ty1, qual);
+ }
+ break;
+ case TYPEARRAY:
+ AppendGListByte(&name_mangle_list, 'A');
+ if (TYPE_POINTER(type)->target->size) {
+ sprintf(buf, "%" PRId32 "", type->size / TYPE_POINTER(type)->target->size);
+ AppendGListName(&name_mangle_list, buf);
+ } else {
+ AppendGListByte(&name_mangle_list, '0');
+ }
+ AppendGListByte(&name_mangle_list, '_');
+ CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
+ break;
+ case TYPEFUNC:
+ CMangler_MangleQualifier(qual);
+ AppendGListByte(&name_mangle_list, 'F');
+ CMangler_MangleArgs(TYPE_FUNC(type)->args);
+ AppendGListByte(&name_mangle_list, '_');
+ CMangler_MangleTypeAppend(TYPE_FUNC(type)->functype, TYPE_FUNC(type)->qual);
+ break;
+ case TYPESTRUCT:
+ CMangler_MangleQualifier(qual);
+ switch (TYPE_STRUCT(type)->stype) {
+ case STRUCT_VECTOR_UCHAR:
+ AppendGListName(&name_mangle_list, "XUc");
+ return;
+ case STRUCT_VECTOR_SCHAR:
+ AppendGListName(&name_mangle_list, "Xc");
+ return;
+ case STRUCT_VECTOR_BCHAR:
+ AppendGListName(&name_mangle_list, "XC");
+ return;
+ case STRUCT_VECTOR_USHORT:
+ AppendGListName(&name_mangle_list, "XUs");
+ return;
+ case STRUCT_VECTOR_SSHORT:
+ AppendGListName(&name_mangle_list, "Xs");
+ return;
+ case STRUCT_VECTOR_BSHORT:
+ AppendGListName(&name_mangle_list, "XS");
+ return;
+ case STRUCT_VECTOR_UINT:
+ AppendGListName(&name_mangle_list, "XUi");
+ return;
+ case STRUCT_VECTOR_SINT:
+ AppendGListName(&name_mangle_list, "Xi");
+ return;
+ case STRUCT_VECTOR_BINT:
+ AppendGListName(&name_mangle_list, "XI");
+ return;
+ case STRUCT_VECTOR_FLOAT:
+ AppendGListName(&name_mangle_list, "Xf");
+ return;
+ case STRUCT_VECTOR_PIXEL:
+ AppendGListName(&name_mangle_list, "Xp");
+ return;
+ }
+
+ if (TYPE_STRUCT(type)->name && !IsTempName(TYPE_STRUCT(type)->name)) {
+ CMangler_MangleTypeName(TYPE_STRUCT(type)->name->name);
+ return;
+ }
+
+ switch (TYPE_STRUCT(type)->stype) {
+ case STRUCT_TYPE_STRUCT:
+ AppendGListName(&name_mangle_list, "struct");
+ break;
+ case STRUCT_TYPE_UNION:
+ AppendGListName(&name_mangle_list, "union");
+ break;
+ case STRUCT_TYPE_CLASS:
+ AppendGListName(&name_mangle_list, "class");
+ break;
+ default:
+ CError_FATAL(701);
+ }
+ break;
+
+ case TYPECLASS:
+ CMangler_MangleQualifier(qual);
+ CMangler_MangleClassName(TYPE_CLASS(type));
+ break;
+
+ case TYPETEMPLATE:
+ AppendGListName(&name_mangle_list, "1T");
+ break;
+
+ default:
+ CError_FATAL(716);
+ }
+}
+
+void CMangler_MangleType(Type *type, UInt32 qual) {
+ name_mangle_list.size = 0;
+ CMangler_MangleTypeAppend(type, qual);
+}
+
+static void CMangler_MangleArgs(FuncArg *args) {
+ TypePointer ptr;
+
+ if (args) {
+ if (args->type) {
+ while (args) {
+ if (args != &elipsis && args != &oldstyle) {
+ if (args->type->type == TYPEPOINTER) {
+ ptr = *TYPE_POINTER(args->type);
+ ptr.qual &= ~(Q_CONST | Q_VOLATILE);
+ CMangler_MangleTypeAppend(TYPE(&ptr), args->qual);
+ } else {
+ CMangler_MangleTypeAppend(args->type, 0);
+ }
+ } else {
+ AppendGListByte(&name_mangle_list, 'e');
+ }
+ args = args->next;
+ }
+ } else {
+ AppendGListByte(&name_mangle_list, 'e');
+ }
+ } else {
+ AppendGListByte(&name_mangle_list, 'v');
+ }
+}
+
+static void CMangler_MangleFunction(Object *obj, NameSpace *nspace) {
+ TypeFunc *tfunc = TYPE_FUNC(obj->type);
+ FuncArg *arg = tfunc->args;
+
+ AppendGListName(&name_mangle_list, obj->name->name);
+ if (obj->u.func.inst) {
+ if (tfunc->flags & FUNC_CONVERSION)
+ CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
+ CMangler_AppendTemplateArgumentList(obj->u.func.inst->args);
+ }
+ AppendGListName(&name_mangle_list, "__");
+ while (nspace && nspace->name == NULL)
+ nspace = nspace->parent;
+
+ if (nspace) {
+ CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
+ if (nspace->theclass) {
+ if (obj->name == destructor_name_node) {
+ AppendGListName(&name_mangle_list, "Fv");
+ return;
+ }
+ if (arg) {
+ if (obj->name == constructor_name_node) {
+ arg = arg->next;
+ if (arg && (nspace->theclass->flags & CLASS_HAS_VBASES))
+ arg = arg->next;
+ } else {
+ if ((tfunc->flags & FUNC_METHOD) && !TYPE_METHOD(tfunc)->is_static) {
+ CMangler_MangleQualifier(arg->qual);
+ arg = arg->next;
+ }
+ }
+ }
+ }
+ }
+
+ AppendGListByte(&name_mangle_list, 'F');
+ CMangler_MangleArgs(arg);
+ if (obj->u.func.inst && copts.new_mangler) {
+ AppendGListByte(&name_mangle_list, '_');
+ CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
+ }
+}
+
+HashNameNode *CMangler_ConversionFuncName(Type *type, UInt32 qual) {
+ HashNameNode *name;
+
+ if (CTemplTool_IsTemplateArgumentDependentType(type))
+ return GetHashNameNodeExport("__op");
+
+ name_mangle_list.size = 0;
+ AppendGListName(&name_mangle_list, "__op");
+ CMangler_MangleTypeAppend(type, qual);
+ AppendGListByte(&name_mangle_list, 0);
+
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+static HashNameNode *CMangler_MangleNameToUpper(char *str) {
+ HashNameNode *name;
+
+ name_mangle_list.size = 0;
+ while (*str) {
+ AppendGListByte(&name_mangle_list, toupper(*(str++)));
+ }
+ AppendGListByte(&name_mangle_list, 0);
+
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+static HashNameNode *CMangler_FunctionLinkName(Object *obj) {
+ HashNameNode *name;
+ NameSpace *nspace;
+
+ if (obj->u.func.inst)
+ CMangler_CheckTemplateArguments(obj->u.func.inst->args);
+
+ for (nspace = obj->nspace; nspace; nspace = nspace->parent) {
+ if (nspace->name)
+ break;
+ }
+
+ name_mangle_list.size = 0;
+ if (is_pascal_object(obj) && (!nspace || !nspace->theclass)) {
+ AppendGListData(&name_mangle_list, "_", 1);
+ AppendGListID(&name_mangle_list, obj->name->name);
+ } else if ((obj->qual & Q_MANGLE_NAME) && (strcmp("main", obj->name->name) || (obj->nspace != cscope_root))) {
+ AppendGListData(&name_mangle_list, "_", 1);
+ CMangler_MangleFunction(obj, nspace);
+ AppendGListByte(&name_mangle_list, 0);
+ } else {
+ AppendGListData(&name_mangle_list, "_", 1);
+ AppendGListID(&name_mangle_list, obj->name->name);
+ }
+
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+HashNameNode *CMangler_GetCovariantFunctionName(Object *dobj, TypeClass *theclass) {
+ HashNameNode *name;
+
+ name = CMangler_GetLinkName(dobj);
+ name_mangle_list.size = 0;
+ AppendGListName(&name_mangle_list, name->name);
+ AppendGListName(&name_mangle_list, "@@");
+ CMangler_MangleTypeAppend(TYPE(theclass), 0);
+ AppendGListByte(&name_mangle_list, 0);
+
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+static HashNameNode *CMangler_DataLinkName(Object *obj) {
+ NameSpace *nspace;
+ HashNameNode *name;
+
+ nspace = obj->nspace;
+ while (nspace && nspace->name == NULL)
+ nspace = nspace->parent;
+
+ name_mangle_list.size = 0;
+ AppendGListData(&name_mangle_list, "_", 1);
+ AppendGListName(&name_mangle_list, obj->name->name);
+
+ while (nspace && nspace->name == NULL)
+ nspace = nspace->parent;
+ if (nspace && (obj->qual & Q_MANGLE_NAME)) {
+ AppendGListName(&name_mangle_list, "__");
+ CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
+ }
+ AppendGListByte(&name_mangle_list, 0);
+
+ COS_LockHandle(name_mangle_list.data);
+ name = GetHashNameNodeExport(*name_mangle_list.data);
+ COS_UnlockHandle(name_mangle_list.data);
+ return name;
+}
+
+HashNameNode *CMangler_GetLinkName(Object *obj) {
+ while (obj->datatype == DALIAS)
+ obj = obj->u.alias.object;
+
+ switch (obj->datatype) {
+ case DFUNC:
+ case DVFUNC:
+ if (!obj->u.func.linkname)
+ obj->u.func.linkname = CMangler_FunctionLinkName(obj);
+ return obj->u.func.linkname;
+ case DDATA:
+ if (!obj->u.data.linkname)
+ obj->u.data.linkname = CMangler_DataLinkName(obj);
+ return obj->u.data.linkname;
+ case DINLINEFUNC:
+ return CMangler_FunctionLinkName(obj);
+ case DLOCAL:
+ case DABSOLUTE:
+ case DLABEL:
+ return obj->name;
+ case DNONLAZYPTR:
+ if (!obj->u.toc.linkname)
+ obj->u.toc.linkname = CMangler_DataLinkName(obj);
+ return obj->u.toc.linkname;
+ default:
+ CError_FATAL(1110);
+ return NULL;
+ }
+}