diff options
Diffstat (limited to 'compiler_and_linker/FrontEnd/C/CMangler.c')
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CMangler.c | 713 |
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; + } +} |