static char * mangleTemplate(char *buf, SYMBOL *sym, TEMPLATEPARAMLIST *params) { BOOLEAN bySpecial = FALSE; if (params && params->p->type == kw_new && ((sym->instantiated && !sym->templateLevel) || (params && params->p->bySpecialization.types))) { params = params->p->bySpecialization.types; bySpecial = TRUE; } if ((sym->isConstructor || sym->isDestructor) && sym->templateLevel == sym->parentClass->templateLevel) { strcpy(buf, sym->name); buf += strlen(buf); } else { *buf++ = '#'; strcpy(buf, sym->name); strcat(buf, "$"); buf += strlen(buf); while (params) { switch(params->p->type) { case kw_typename: if (params->p->packed) { if (params->p->byPack.pack) { TEMPLATEPARAMLIST *pack = params->p->byPack.pack; while (pack) { buf = mangleType(buf, pack->p->byClass.val, TRUE); pack = pack->next; } } else { *buf++ = 'e'; buf = getName(buf, params->p->sym); } } else if (bySpecial) { buf = mangleType(buf, params->p->byClass.dflt, TRUE); } else if (sym->instantiated && params->p->byClass.val) { buf = mangleType(buf, params->p->byClass.val, TRUE); } else { if (params->p->byClass.dflt) { buf = mangleType(buf, params->p->byClass.dflt, TRUE); } else { buf = getName(buf, params->p->sym); } } break; case kw_template: if (params->p->packed) *buf++ = 'e'; if (bySpecial && params->p->byTemplate.dflt && params->p->byTemplate.val) { buf = mangleTemplate(buf, params->p->byTemplate.dflt, params->p->byTemplate.val->templateParams); } else if (sym->instantiated && params->p->byTemplate.val) { buf = mangleTemplate(buf, params->p->byTemplate.val, params->p->byTemplate.val->templateParams); } else if (params->p->sym) { buf = getName(buf, params->p->sym); } else { buf = getName(buf, params->p->byTemplate.dflt); } break; case kw_int: if (params->p->packed) { *buf++ = 'e'; if (params->p->byPack.pack) { params = params->p->byPack.pack; continue; } } else { buf = mangleType(buf, params->p->byNonType.tp, TRUE); if (bySpecial || sym->instantiated) { EXPRESSION *exp = bySpecial ? params->p->byNonType.dflt : params->p->byNonType.val; buf = mangleExpression(buf, exp); } else if (params->p->byNonType.dflt) { buf = mangleExpression(buf, params->p->byNonType.dflt); } } break; default: break; } params = params->next; } *buf++ = '~'; *buf = 0; } return buf; }
std::string Mangler::mangleRValueReferenceType(const RValueReferenceType* type) { return "O" + mangleType(type->elementType()); }
static char * mangleExpressionInternal (char *buf, EXPRESSION *exp) { while (castvalue(exp)) exp = exp->left; if (isintconst(exp)) { if (exp->type == en_const) { sprintf(buf, "%lld&", exp->v.sp->value.i); } else { sprintf(buf, "%lld&", exp->v.i); } if (buf[0] == '-') buf[0] = '_'; } else { BOOLEAN nonpointer = FALSE; while (lvalue(exp)) { nonpointer = TRUE; exp = exp->left; } switch (exp->type) { case en_nullptr: *buf++ = 'n'; *buf = 0; break; case en_arrayadd: case en_structadd: case en_add: *buf++ = 'p'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_sub: *buf++ = 's'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_mul: case en_umul: case en_arraymul: *buf++ = 'm'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_umod: case en_mod: *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_div: case en_udiv: case en_arraydiv: *buf++ = 'd'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_lsh: case en_arraylsh: *buf++ = 'h'; *buf++ = 'l'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_rsh: case en_ursh: *buf++ = 'h'; *buf++ = 'r'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_cond: *buf++ = 'C'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right->left); buf = mangleExpressionInternal(buf, exp->right->right); *buf = 0; break; case en_assign: *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_eq: *buf++ = 'c'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ne: *buf++ = 'c'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_uminus: *buf++ = 'u'; buf = mangleExpressionInternal(buf, exp->left); break; case en_not: *buf++ = 'l'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); break; case en_compl: *buf++ = 'b'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); *buf = 0; break; case en_ascompl: *buf++ = 'a'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ult: case en_lt: *buf++ = 'c'; *buf++ = 'l'; *buf++ = 't'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ule: case en_le: *buf++ = 'c'; *buf++ = 'l'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ugt: case en_gt: *buf++ = 'c'; *buf++ = 'g'; *buf++ = 't'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_uge: case en_ge: *buf++ = 'c'; *buf++ = 'g'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_and: *buf++ = 'b'; *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_land: *buf++ = 'l'; *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_or: *buf++ = 'b'; *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_lor: *buf++ = 'l'; *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_xor: *buf++ = 'b'; *buf++ = 'x'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_autoinc: *buf++ = 'i'; *buf++ = 'p'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_autodec: *buf++ = 'i'; *buf++ = 's'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_templateselector: { TEMPLATESELECTOR *tsl = exp->v.templateSelector, *find = tsl->next->next; SYMBOL *ts = tsl->next->sym; *buf++ = 't'; *buf++ = 's'; if (tsl->next->isTemplate && tsl->next->templateParams) // may be an empty variadic { buf = mangleTemplate(buf, ts, tsl->next->templateParams); } while (find) { *buf++ = 't'; buf = lookupName(buf, find->name); find = find->next; } *buf = 0; break; } case en_templateparam: *buf++ = 't'; *buf++ = 'p'; buf = lookupName(buf,exp->v.sp->name); *buf = 0; break; case en_funcret: buf = mangleExpressionInternal(buf, exp->left); *buf = 0; break; case en_func: if (exp->v.func->ascall) { INITLIST *args = exp->v.func->arguments; *buf++ = 'f'; buf = lookupName(buf, exp->v.func->sp->name); while(args) { *buf++='f'; buf = mangleExpressionInternal(buf, args->exp); args = args->next; } } else { *buf++ = 'e'; *buf++ = '&'; strcpy(buf, exp->v.func->sp->name); buf += strlen(buf); *buf++ = '$'; buf = mangleType( buf, exp->v.func->sp->tp, TRUE); } break; case en_pc: case en_global: case en_label: case en_const: if (isfunction(exp->v.sp->tp)) { *buf++ = 'e'; *buf++ = '&'; strcpy(buf, exp->v.sp->name); buf += strlen(buf); *buf++ = '$'; buf = mangleType( buf, exp->v.sp->tp, TRUE); } else { *buf++ = 'g'; if (!nonpointer) *buf++ = '&'; strcpy(buf, exp->v.sp->name); *buf++ = '$'; *buf = 0; } break; default: *buf = 0; break; } } buf += strlen(buf); return buf; }
std::string Mangler::manglePointerType(const PointerType* type) { return "P" + mangleType(type->elementType()); }