From 333d678fe871970347f26db59ae7e842072e9ce9 Mon Sep 17 00:00:00 2001 From: k-hara Date: Sun, 31 Aug 2014 15:45:03 +0900 Subject: [PATCH 1/4] [Refactoring] Remove unused flag 0x100 in Type::toDecoBuffer --- src/mtype.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/mtype.c b/src/mtype.c index e857413c04d1..938762e9f7cf 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -1570,13 +1570,11 @@ char *MODtoChars(MOD mod) /******************************** * Name mangling. - * Input: - * flag 0x100 do not do modifiers */ void Type::toDecoBuffer(OutBuffer *buf, int flag) { - if (flag != mod && flag != 0x100) + if (flag != mod) { MODtoDecoBuffer(buf, mod); } @@ -2563,7 +2561,7 @@ void TypeNext::toDecoBuffer(OutBuffer *buf, int flag) Type::toDecoBuffer(buf, flag); assert(next != this); //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty); - next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); + next->toDecoBuffer(buf, mod); } void TypeNext::checkDeprecated(Loc loc, Scope *sc) @@ -3632,12 +3630,12 @@ char *TypeVector::toChars() void TypeVector::toDecoBuffer(OutBuffer *buf, int flag) { - if (flag != mod && flag != 0x100) + if (flag != mod) { MODtoDecoBuffer(buf, mod); } buf->writestring("Nh"); - basetype->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); + basetype->toDecoBuffer(buf, mod); } d_uns64 TypeVector::size(Loc loc) @@ -4176,12 +4174,7 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) if (dim) buf->printf("%llu", dim->toInteger()); if (next) - /* Note that static arrays are value types, so - * for a parameter, propagate the 0x100 to the next - * level, since for T[4][3], any const should apply to the T, - * not the [4]. - */ - next->toDecoBuffer(buf, (flag & 0x100) ? flag : mod); + next->toDecoBuffer(buf, mod); } Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) @@ -4476,7 +4469,7 @@ void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag) { Type::toDecoBuffer(buf, flag); if (next) - next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); + next->toDecoBuffer(buf, mod); } Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) @@ -4884,7 +4877,7 @@ void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag) { Type::toDecoBuffer(buf, flag); index->toDecoBuffer(buf); - next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); + next->toDecoBuffer(buf, mod); } Expression *TypeAArray::defaultInit(Loc loc) @@ -9428,15 +9421,7 @@ void Parameter::toDecoBuffer(OutBuffer *buf) #endif assert(0); } -#if 0 - int mod = 0x100; - if (type->toBasetype()->ty == Tclass) - mod = 0; - type->toDecoBuffer(buf, mod); -#else - //type->toHeadMutable()->toDecoBuffer(buf, 0); type->toDecoBuffer(buf, 0); -#endif } /*************************************** From 5cb879af5e9671f3c8958bf2b9b93a60b18ef2c9 Mon Sep 17 00:00:00 2001 From: k-hara Date: Sun, 31 Aug 2014 15:48:16 +0900 Subject: [PATCH 2/4] [Refactoring] Directly handle OutBuffer in Mangler --- src/mangle.c | 239 +++++++++++++++++++++++++-------------------------- 1 file changed, 115 insertions(+), 124 deletions(-) diff --git a/src/mangle.c b/src/mangle.c index 438cb7259f9c..2e7d3d671802 100644 --- a/src/mangle.c +++ b/src/mangle.c @@ -26,96 +26,112 @@ #include "module.h" char *toCppMangle(Dsymbol *s); -void toBuffer(OutBuffer *buf, const char *id, Dsymbol *s); -void mangleFunc(OutBuffer *buf, FuncDeclaration *fd, bool inParent) +class Mangler : public Visitor { - //printf("deco = '%s'\n", fd->type->deco ? fd->type->deco : "null"); - //printf("fd->type = %s\n", fd->type->toChars()); - if (fd->needThis() || fd->isNested()) - buf->writeByte(Type::needThisPrefix()); - if (inParent) - { - TypeFunction *tfx = (TypeFunction *)fd->type; - TypeFunction *tf = (TypeFunction *)fd->originalType; - - // replace with the actual parameter types - Parameters *prms = tf->parameters; - tf->parameters = tfx->parameters; - - // do not mangle return type - Type *tret = tf->next; - tf->next = NULL; - - tf->toDecoBuffer(buf, 0); +public: + OutBuffer *buf; - tf->parameters = prms; - tf->next = tret; - } - else if (fd->type->deco) + Mangler(OutBuffer *buf) { - buf->writestring(fd->type->deco); + this->buf = buf; } - else - { - printf("[%s] %s %s\n", fd->loc.toChars(), fd->toChars(), fd->type->toChars()); - assert(0); // don't mangle function until semantic3 done. - } -} -void mangleParent(OutBuffer *buf, Dsymbol *s) -{ - Dsymbol *p; - if (TemplateInstance *ti = s->isTemplateInstance()) - p = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent; - else - p = s->parent; + //////////////////////////////////////////////////////////////////////////// - if (p) + void mangleDecl(Declaration *sthis) { - mangleParent(buf, p); + mangleParent(sthis); - if (p->getIdent()) - { - const char *id = p->ident->toChars(); - toBuffer(buf, id, s); + assert(sthis->ident); + const char *id = sthis->ident->toChars(); + toBuffer(id, sthis); - if (FuncDeclaration *f = p->isFuncDeclaration()) - mangleFunc(buf, f, true); + if (FuncDeclaration *fd = sthis->isFuncDeclaration()) + { + mangleFunc(fd, false); + } + else if (sthis->type->deco) + { + buf->writestring(sthis->type->deco); } else - buf->writeByte('0'); + assert(0); } -} -void mangleDecl(OutBuffer *buf, Declaration *sthis) -{ - mangleParent(buf, sthis); + void mangleParent(Dsymbol *s) + { + Dsymbol *p; + if (TemplateInstance *ti = s->isTemplateInstance()) + p = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent; + else + p = s->parent; - assert(sthis->ident); - const char *id = sthis->ident->toChars(); - toBuffer(buf, id, sthis); + if (p) + { + mangleParent(p); - if (FuncDeclaration *fd = sthis->isFuncDeclaration()) - { - mangleFunc(buf, fd, false); + if (p->getIdent()) + { + const char *id = p->ident->toChars(); + toBuffer(id, s); + + if (FuncDeclaration *f = p->isFuncDeclaration()) + mangleFunc(f, true); + } + else + buf->writeByte('0'); + } } - else if (sthis->type->deco) + + void mangleFunc(FuncDeclaration *fd, bool inParent) { - buf->writestring(sthis->type->deco); - } - else - assert(0); -} + //printf("deco = '%s'\n", fd->type->deco ? fd->type->deco : "null"); + //printf("fd->type = %s\n", fd->type->toChars()); + if (fd->needThis() || fd->isNested()) + buf->writeByte(Type::needThisPrefix()); + if (inParent) + { + TypeFunction *tfx = (TypeFunction *)fd->type; + TypeFunction *tf = (TypeFunction *)fd->originalType; -class Mangler : public Visitor -{ -public: - const char *result; + // replace with the actual parameter types + Parameters *prms = tf->parameters; + tf->parameters = tfx->parameters; + + // do not mangle return type + Type *tret = tf->next; + tf->next = NULL; + + tf->toDecoBuffer(buf, 0); - Mangler() + tf->parameters = prms; + tf->next = tret; + } + else if (fd->type->deco) + { + buf->writestring(fd->type->deco); + } + else + { + printf("[%s] %s %s\n", fd->loc.toChars(), fd->toChars(), fd->type->toChars()); + assert(0); // don't mangle function until semantic3 done. + } + } + + /************************************************************ + * Write length prefixed string to buf. + */ + void toBuffer(const char *id, Dsymbol *s) { - result = NULL; + size_t len = strlen(id); + if (len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone + s->error("excessive length %llu for symbol, possible recursive expansion?", len); + else + { + buf->printf("%llu", (ulonglong)len); + buf->write(id, len); + } } void visit(Declaration *d) @@ -132,43 +148,39 @@ class Mangler : public Visitor case LINKc: case LINKwindows: case LINKpascal: - result = d->ident->toChars(); - break; + buf->writestring(d->ident->toChars()); + return; case LINKcpp: - result = toCppMangle(d); - break; + buf->writestring(toCppMangle(d)); + return; case LINKdefault: d->error("forward declaration"); - result = d->ident->toChars(); - break; + buf->writestring(d->ident->toChars()); + return; default: fprintf(stderr, "'%s', linkage = %d\n", d->toChars(), d->linkage); assert(0); + return; } } - if (!result) - { - OutBuffer buf; - buf.writestring("_D"); - mangleDecl(&buf, d); - result = buf.extractString(); - } + buf->writestring("_D"); + mangleDecl(d); #ifdef DEBUG - assert(result); - size_t len = strlen(result); + assert(buf->data); + size_t len = buf->offset; assert(len > 0); for (size_t i = 0; i < len; i++) { - assert(result[i] == '_' || - result[i] == '@' || - result[i] == '?' || - result[i] == '$' || - isalnum(result[i]) || result[i] & 0x80); + assert(buf->data[i] == '_' || + buf->data[i] == '@' || + buf->data[i] == '?' || + buf->data[i] == '$' || + isalnum(buf->data[i]) || buf->data[i] & 0x80); } #endif } @@ -255,19 +267,19 @@ class Mangler : public Visitor if (fd->mangleOverride) { - result = fd->mangleOverride; + buf->writestring(fd->mangleOverride); return; } if (fd->isMain()) { - result = "_Dmain"; + buf->writestring("_Dmain"); return; } if (fd->isWinMain() || fd->isDllMain() || fd->ident == Id::tls_get_addr) { - result = fd->ident->toChars(); + buf->writestring(fd->ident->toChars()); return; } @@ -278,7 +290,7 @@ class Mangler : public Visitor { if (vd->mangleOverride) { - result = vd->mangleOverride; + buf->writestring(vd->mangleOverride); return; } @@ -330,19 +342,16 @@ class Mangler : public Visitor printf("\n"); #endif - OutBuffer buf; if (!ti->tempdecl) ti->error("is not defined"); else - mangleParent(&buf, ti); + mangleParent(ti); ti->getIdent(); const char *id = ti->ident ? ti->ident->toChars() : ti->toChars(); - toBuffer(&buf, id, ti); - id = buf.extractString(); + toBuffer(id, ti); //printf("TemplateInstance::mangle() %s = %s\n", ti->toChars(), ti->id); - result = id; } void visit(Dsymbol *s) @@ -354,23 +363,21 @@ class Mangler : public Visitor printf("\n"); #endif - OutBuffer buf; - mangleParent(&buf, s); + mangleParent(s); char *id = s->ident ? s->ident->toChars() : s->toChars(); - toBuffer(&buf, id, s); - id = buf.extractString(); + toBuffer(id, s); //printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id); - result = id; } }; const char *mangle(Dsymbol *s) { - Mangler v; + OutBuffer buf; + Mangler v(&buf); s->accept(&v); - return v.result; + return buf.extractString(); } /****************************************************************************** @@ -378,24 +385,8 @@ const char *mangle(Dsymbol *s) */ const char *mangleExact(FuncDeclaration *fd) { - Mangler v; + OutBuffer buf; + Mangler v(&buf); v.mangleExact(fd); - return v.result; -} - - -/************************************************************ - * Write length prefixed string to buf. - */ - -void toBuffer(OutBuffer *buf, const char *id, Dsymbol *s) -{ - size_t len = strlen(id); - if (len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone - s->error("excessive length %llu for symbol, possible recursive expansion?", len); - else - { - buf->printf("%llu", (ulonglong)len); - buf->write(id, len); - } + return buf.extractString(); } From 92b085a062d4cc61f87292a1341ddf72b06e6d4f Mon Sep 17 00:00:00 2001 From: k-hara Date: Sun, 31 Aug 2014 16:02:48 +0900 Subject: [PATCH 3/4] [Refactoring] Move type mangling code into mangle.c --- src/mangle.c | 360 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/mtype.c | 329 ++-------------------------------------------- src/mtype.h | 21 --- src/tocsym.c | 6 +- 4 files changed, 360 insertions(+), 356 deletions(-) diff --git a/src/mangle.c b/src/mangle.c index 2e7d3d671802..fc5478525d91 100644 --- a/src/mangle.c +++ b/src/mangle.c @@ -24,8 +24,112 @@ #include "template.h" #include "id.h" #include "module.h" +#include "enum.h" char *toCppMangle(Dsymbol *s); +void mangleToBuffer(Type *t, OutBuffer *buf); + +static unsigned char mangleChar[TMAX]; + +void initTypeMangle() +{ + mangleChar[Tarray] = 'A'; + mangleChar[Tsarray] = 'G'; + mangleChar[Taarray] = 'H'; + mangleChar[Tpointer] = 'P'; + mangleChar[Treference] = 'R'; + mangleChar[Tfunction] = 'F'; + mangleChar[Tident] = 'I'; + mangleChar[Tclass] = 'C'; + mangleChar[Tstruct] = 'S'; + mangleChar[Tenum] = 'E'; + mangleChar[Ttypedef] = 'T'; + mangleChar[Tdelegate] = 'D'; + + mangleChar[Tnone] = 'n'; + mangleChar[Tvoid] = 'v'; + mangleChar[Tint8] = 'g'; + mangleChar[Tuns8] = 'h'; + mangleChar[Tint16] = 's'; + mangleChar[Tuns16] = 't'; + mangleChar[Tint32] = 'i'; + mangleChar[Tuns32] = 'k'; + mangleChar[Tint64] = 'l'; + mangleChar[Tuns64] = 'm'; + mangleChar[Tfloat32] = 'f'; + mangleChar[Tfloat64] = 'd'; + mangleChar[Tfloat80] = 'e'; + + mangleChar[Timaginary32] = 'o'; + mangleChar[Timaginary64] = 'p'; + mangleChar[Timaginary80] = 'j'; + mangleChar[Tcomplex32] = 'q'; + mangleChar[Tcomplex64] = 'r'; + mangleChar[Tcomplex80] = 'c'; + + mangleChar[Tbool] = 'b'; + mangleChar[Tchar] = 'a'; + mangleChar[Twchar] = 'u'; + mangleChar[Tdchar] = 'w'; + + // '@' shouldn't appear anywhere in the deco'd names + mangleChar[Tinstance] = '@'; + mangleChar[Terror] = '@'; + mangleChar[Ttypeof] = '@'; + mangleChar[Ttuple] = 'B'; + mangleChar[Tslice] = '@'; + mangleChar[Treturn] = '@'; + mangleChar[Tvector] = '@'; + mangleChar[Tint128] = '@'; + mangleChar[Tuns128] = '@'; + + mangleChar[Tnull] = 'n'; // same as TypeNone + + for (size_t i = 0; i < TMAX; i++) + { + if (!mangleChar[i]) + fprintf(stderr, "ty = %llu\n", (ulonglong)i); + assert(mangleChar[i]); + } +} + +/********************************* + * Mangling for mod. + */ +void MODtoDecoBuffer(OutBuffer *buf, MOD mod) +{ + switch (mod) + { + case 0: + break; + case MODconst: + buf->writeByte('x'); + break; + case MODimmutable: + buf->writeByte('y'); + break; + case MODshared: + buf->writeByte('O'); + break; + case MODshared | MODconst: + buf->writestring("Ox"); + break; + case MODwild: + buf->writestring("Ng"); + break; + case MODwildconst: + buf->writestring("Ngx"); + break; + case MODshared | MODwild: + buf->writestring("ONg"); + break; + case MODshared | MODwildconst: + buf->writestring("ONgx"); + break; + default: + assert(0); + } +} class Mangler : public Visitor { @@ -37,6 +141,182 @@ class Mangler : public Visitor this->buf = buf; } + + //////////////////////////////////////////////////////////////////////////// + + /************************************************** + * Type mangling + */ + + void visitWithMask(Type *t, unsigned char modMask) + { + if (modMask != t->mod) + { + MODtoDecoBuffer(buf, t->mod); + } + t->accept(this); + } + + void visit(Type *t) + { + buf->writeByte(mangleChar[t->ty]); + } + + void visit(TypeNext *t) + { + visit((Type *)t); + visitWithMask(t->next, t->mod); + } + + void visit(TypeVector *t) + { + buf->writestring("Nh"); + visitWithMask(t->basetype, t->mod); + } + + void visit(TypeSArray *t) + { + visit((Type *)t); + if (t->dim) + buf->printf("%llu", t->dim->toInteger()); + if (t->next) + visitWithMask(t->next, t->mod); + } + + void visit(TypeDArray *t) + { + visit((Type *)t); + if (t->next) + visitWithMask(t->next, t->mod); + } + + void visit(TypeAArray *t) + { + visit((Type *)t); + visitWithMask(t->index, 0); + visitWithMask(t->next, t->mod); + } + + void visit(TypeFunction *t) + { + //printf("TypeFunction::toDecoBuffer() t = %p %s\n", t, t->toChars()); + //static int nest; if (++nest == 50) *(char*)0=0; + + mangleFuncType(t, t, t->mod, t->next); + } + + void mangleFuncType(TypeFunction *t, TypeFunction *ta, unsigned char modMask, Type *tret) + { + if (t->inuse) + { + t->inuse = 2; // flag error to caller + return; + } + t->inuse++; + + if (modMask != t->mod) + MODtoDecoBuffer(buf, t->mod); + + unsigned char mc; + switch (t->linkage) + { + case LINKd: mc = 'F'; break; + case LINKc: mc = 'U'; break; + case LINKwindows: mc = 'W'; break; + case LINKpascal: mc = 'V'; break; + case LINKcpp: mc = 'R'; break; + default: + assert(0); + } + buf->writeByte(mc); + + if (ta->purity || ta->isnothrow || ta->isnogc || ta->isproperty || ta->isref || ta->trust) + { + if (ta->purity) + buf->writestring("Na"); + if (ta->isnothrow) + buf->writestring("Nb"); + if (ta->isref) + buf->writestring("Nc"); + if (ta->isproperty) + buf->writestring("Nd"); + if (ta->isnogc) + buf->writestring("Ni"); + switch (ta->trust) + { + case TRUSTtrusted: + buf->writestring("Ne"); + break; + case TRUSTsafe: + buf->writestring("Nf"); + break; + default: + break; + } + } + + // Write argument types + argsToDecoBuffer(t->parameters); + //if (buf->data[buf->offset - 1] == '@') halt(); + buf->writeByte('Z' - t->varargs); // mark end of arg list + if (tret != NULL) + visitWithMask(tret, 0); + + t->inuse--; + } + + void visit(TypeIdentifier *t) + { + visit((Type *)t); + const char *name = t->ident->toChars(); + size_t len = strlen(name); + buf->printf("%u%s", (unsigned)len, name); + } + + void visit(TypeEnum *t) + { + visit((Type *)t); + t->sym->accept(this); + } + + void visit(TypeTypedef *t) + { + visit((Type *)t); + t->sym->accept(this); + } + + void visit(TypeStruct *t) + { + //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", t->toChars(), name); + visit((Type *)t); + t->sym->accept(this); + } + + void visit(TypeClass *t) + { + //printf("TypeClass::toDecoBuffer('%s' mod=%x) = '%s'\n", t->toChars(), mod, name); + visit((Type *)t); + t->sym->accept(this); + } + + void visit(TypeTuple *t) + { + //printf("TypeTuple::toDecoBuffer() t = %p, %s\n", t, t->toChars()); + visit((Type *)t); + + OutBuffer buf2; + buf2.reserve(32); + Mangler v(&buf2); + v.argsToDecoBuffer(t->arguments); + int len = (int)buf2.offset; + buf->printf("%d%.*s", len, len, buf2.extractData()); + } + + void visit(TypeNull *t) + { + visit((Type *)t); + } + //////////////////////////////////////////////////////////////////////////// void mangleDecl(Declaration *sthis) @@ -92,21 +372,9 @@ class Mangler : public Visitor buf->writeByte(Type::needThisPrefix()); if (inParent) { - TypeFunction *tfx = (TypeFunction *)fd->type; - TypeFunction *tf = (TypeFunction *)fd->originalType; - - // replace with the actual parameter types - Parameters *prms = tf->parameters; - tf->parameters = tfx->parameters; - - // do not mangle return type - Type *tret = tf->next; - tf->next = NULL; - - tf->toDecoBuffer(buf, 0); - - tf->parameters = prms; - tf->next = tret; + TypeFunction *tf = (TypeFunction *)fd->type; + TypeFunction *tfo = (TypeFunction *)fd->originalType; + mangleFuncType(tf, tfo, 0, NULL); } else if (fd->type->deco) { @@ -370,6 +638,48 @@ class Mangler : public Visitor //printf("Dsymbol::mangle() %s = %s\n", s->toChars(), id); } + + //////////////////////////////////////////////////////////////////////////// + + void argsToDecoBuffer(Parameters *arguments) + { + //printf("Parameter::argsToDecoBuffer()\n"); + Parameter::foreach(arguments, &argsToDecoBufferDg, (void *)this); + } + + static int argsToDecoBufferDg(void *ctx, size_t n, Parameter *arg) + { + arg->accept((Visitor *)ctx); + return 0; + } + + void visit(Parameter *p) + { + if (p->storageClass & STCscope) + buf->writeByte('M'); + switch (p->storageClass & (STCin | STCout | STCref | STClazy)) + { + case 0: + case STCin: + break; + case STCout: + buf->writeByte('J'); + break; + case STCref: + buf->writeByte('K'); + break; + case STClazy: + buf->writeByte('L'); + break; + default: + #ifdef DEBUG + printf("storageClass = x%llx\n", p->storageClass & (STCin | STCout | STCref | STClazy)); + halt(); + #endif + assert(0); + } + visitWithMask(p->type, 0); + } }; const char *mangle(Dsymbol *s) @@ -390,3 +700,23 @@ const char *mangleExact(FuncDeclaration *fd) v.mangleExact(fd); return buf.extractString(); } + +void mangleToBuffer(Type *t, OutBuffer *buf) +{ + Mangler v(buf); + v.visitWithMask(t, 0); +} + +void mangleToBuffer(Type *t, OutBuffer *buf, bool internal) +{ + if (internal) + { + buf->writeByte(mangleChar[t->ty]); + if (t->ty == Tarray) + buf->writeByte(mangleChar[((TypeArray *)t)->next->ty]); + } + else if (t->deco) + buf->writestring(t->deco); + else + mangleToBuffer(t, buf); +} diff --git a/src/mtype.c b/src/mtype.c index 938762e9f7cf..81fe77a13d4b 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -120,10 +120,12 @@ Type *Type::tvoidptr; Type *Type::tstring; Type *Type::tvalist; Type *Type::basic[TMAX]; -unsigned char Type::mangleChar[TMAX]; unsigned char Type::sizeTy[TMAX]; StringTable Type::stringtable; +void initTypeMangle(); +void mangleToBuffer(Type *t, OutBuffer *buf); +void mangleToBuffer(Type *t, OutBuffer *buf, bool internal); Type::Type(TY ty) { @@ -213,63 +215,7 @@ void Type::init() sizeTy[Terror] = sizeof(TypeError); sizeTy[Tnull] = sizeof(TypeNull); - mangleChar[Tarray] = 'A'; - mangleChar[Tsarray] = 'G'; - mangleChar[Taarray] = 'H'; - mangleChar[Tpointer] = 'P'; - mangleChar[Treference] = 'R'; - mangleChar[Tfunction] = 'F'; - mangleChar[Tident] = 'I'; - mangleChar[Tclass] = 'C'; - mangleChar[Tstruct] = 'S'; - mangleChar[Tenum] = 'E'; - mangleChar[Ttypedef] = 'T'; - mangleChar[Tdelegate] = 'D'; - - mangleChar[Tnone] = 'n'; - mangleChar[Tvoid] = 'v'; - mangleChar[Tint8] = 'g'; - mangleChar[Tuns8] = 'h'; - mangleChar[Tint16] = 's'; - mangleChar[Tuns16] = 't'; - mangleChar[Tint32] = 'i'; - mangleChar[Tuns32] = 'k'; - mangleChar[Tint64] = 'l'; - mangleChar[Tuns64] = 'm'; - mangleChar[Tfloat32] = 'f'; - mangleChar[Tfloat64] = 'd'; - mangleChar[Tfloat80] = 'e'; - - mangleChar[Timaginary32] = 'o'; - mangleChar[Timaginary64] = 'p'; - mangleChar[Timaginary80] = 'j'; - mangleChar[Tcomplex32] = 'q'; - mangleChar[Tcomplex64] = 'r'; - mangleChar[Tcomplex80] = 'c'; - - mangleChar[Tbool] = 'b'; - mangleChar[Tchar] = 'a'; - mangleChar[Twchar] = 'u'; - mangleChar[Tdchar] = 'w'; - - // '@' shouldn't appear anywhere in the deco'd names - mangleChar[Tinstance] = '@'; - mangleChar[Terror] = '@'; - mangleChar[Ttypeof] = '@'; - mangleChar[Ttuple] = 'B'; - mangleChar[Tslice] = '@'; - mangleChar[Treturn] = '@'; - mangleChar[Tvector] = '@'; - mangleChar[Tint128] = '@'; - mangleChar[Tuns128] = '@'; - - mangleChar[Tnull] = 'n'; // same as TypeNone - - for (size_t i = 0; i < TMAX; i++) - { if (!mangleChar[i]) - fprintf(stderr, "ty = %llu\n", (ulonglong)i); - assert(mangleChar[i]); - } + initTypeMangle(); // Set basic types static TY basetab[] = @@ -282,7 +228,8 @@ void Type::init() Tchar, Twchar, Tdchar, Terror }; for (size_t i = 0; basetab[i] != Terror; i++) - { Type *t = new TypeBasic(basetab[i]); + { + Type *t = new TypeBasic(basetab[i]); t = t->merge(); basic[basetab[i]] = t; } @@ -1470,43 +1417,6 @@ MOD MODmerge(MOD mod1, MOD mod2) return result; } -/********************************* - * Mangling for mod. - */ -void MODtoDecoBuffer(OutBuffer *buf, MOD mod) -{ - switch (mod) - { case 0: - break; - case MODconst: - buf->writeByte('x'); - break; - case MODimmutable: - buf->writeByte('y'); - break; - case MODshared: - buf->writeByte('O'); - break; - case MODshared | MODconst: - buf->writestring("Ox"); - break; - case MODwild: - buf->writestring("Ng"); - break; - case MODwildconst: - buf->writestring("Ngx"); - break; - case MODshared | MODwild: - buf->writestring("ONg"); - break; - case MODshared | MODwildconst: - buf->writestring("ONgx"); - break; - default: - assert(0); - } -} - /********************************* * Store modifier name into buf. */ @@ -1568,19 +1478,6 @@ char *MODtoChars(MOD mod) return buf.extractString(); } -/******************************** - * Name mangling. - */ - -void Type::toDecoBuffer(OutBuffer *buf, int flag) -{ - if (flag != mod) - { - MODtoDecoBuffer(buf, mod); - } - buf->writeByte(mangleChar[ty]); -} - /******************************** * For pretty-printing a type. */ @@ -1748,12 +1645,12 @@ Type *Type::merge() OutBuffer buf; buf.reserve(32); - //if (next) - //next = next->merge(); - toDecoBuffer(&buf); + mangleToBuffer(this, &buf); + StringValue *sv = stringtable.update((char *)buf.data, buf.offset); if (sv->ptrvalue) - { t = (Type *) sv->ptrvalue; + { + t = (Type *) sv->ptrvalue; #ifdef DEBUG if (!t->deco) printf("t = %s\n", t->toChars()); @@ -2401,16 +2298,7 @@ Identifier *Type::getTypeInfoIdent(int internal) // _init_10TypeInfo_%s OutBuffer buf; buf.reserve(32); - - if (internal) - { buf.writeByte(mangleChar[ty]); - if (ty == Tarray) - buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]); - } - else if (deco) - buf.writestring(deco); - else - toDecoBuffer(&buf); + mangleToBuffer(this, &buf, internal); size_t len = buf.offset; buf.writeByte(0); @@ -2556,14 +2444,6 @@ TypeNext::TypeNext(TY ty, Type *next) this->next = next; } -void TypeNext::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - assert(next != this); - //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty); - next->toDecoBuffer(buf, mod); -} - void TypeNext::checkDeprecated(Loc loc, Scope *sc) { Type::checkDeprecated(loc, sc); @@ -3628,16 +3508,6 @@ char *TypeVector::toChars() return Type::toChars(); } -void TypeVector::toDecoBuffer(OutBuffer *buf, int flag) -{ - if (flag != mod) - { - MODtoDecoBuffer(buf, mod); - } - buf->writestring("Nh"); - basetype->toDecoBuffer(buf, mod); -} - d_uns64 TypeVector::size(Loc loc) { return basetype->size(); @@ -4168,15 +4038,6 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) return Type::terror; } -void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - if (dim) - buf->printf("%llu", dim->toInteger()); - if (next) - next->toDecoBuffer(buf, mod); -} - Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { #if LOGDOTEXP @@ -4465,13 +4326,6 @@ void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol } } -void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - if (next) - next->toDecoBuffer(buf, mod); -} - Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { #if LOGDOTEXP @@ -4873,13 +4727,6 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int return e; } -void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - index->toDecoBuffer(buf); - next->toDecoBuffer(buf, mod); -} - Expression *TypeAArray::defaultInit(Loc loc) { #if LOGDEFAULTINIT @@ -5438,65 +5285,6 @@ int Type::covariant(Type *t, StorageClass *pstc) return 2; } -void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag) -{ - //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars()); - //static int nest; if (++nest == 50) *(char*)0=0; - if (inuse) - { - inuse = 2; // flag error to caller - return; - } - inuse++; - - MODtoDecoBuffer(buf, mod); - - unsigned char mc; - switch (linkage) - { - case LINKd: mc = 'F'; break; - case LINKc: mc = 'U'; break; - case LINKwindows: mc = 'W'; break; - case LINKpascal: mc = 'V'; break; - case LINKcpp: mc = 'R'; break; - default: - assert(0); - } - buf->writeByte(mc); - - if (purity || isnothrow || isnogc || isproperty || isref || trust) - { - if (purity) - buf->writestring("Na"); - if (isnothrow) - buf->writestring("Nb"); - if (isref) - buf->writestring("Nc"); - if (isproperty) - buf->writestring("Nd"); - if (isnogc) - buf->writestring("Ni"); - switch (trust) - { - case TRUSTtrusted: - buf->writestring("Ne"); - break; - case TRUSTsafe: - buf->writestring("Nf"); - break; - default: break; - } - } - - // Write argument types - Parameter::argsToDecoBuffer(buf, parameters); - //if (buf->data[buf->offset - 1] == '@') halt(); - buf->writeByte('Z' - varargs); // mark end of arg list - if (next != NULL) - next->toDecoBuffer(buf); - inuse--; -} - Type *TypeFunction::semantic(Loc loc, Scope *sc) { if (deco) // if semantic() already run @@ -6729,14 +6517,6 @@ Type *TypeIdentifier::syntaxCopy() return t; } -void TypeIdentifier::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - const char *name = ident->toChars(); - size_t len = strlen(name); - buf->printf("%u%s", (unsigned)len, name); -} - /************************************* * Takes an array of Identifiers and figures out if * it represents a Type or an Expression. @@ -7340,13 +7120,6 @@ Type *TypeEnum::toBasetype() return sym->getMemtype(Loc())->toBasetype(); } -void TypeEnum::toDecoBuffer(OutBuffer *buf, int flag) -{ - const char *name = mangle(sym); - Type::toDecoBuffer(buf, flag); - buf->writestring(name); -} - Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { #if LOGDOTEXP @@ -7560,13 +7333,6 @@ Dsymbol *TypeTypedef::toDsymbol(Scope *sc) return sym; } -void TypeTypedef::toDecoBuffer(OutBuffer *buf, int flag) -{ - Type::toDecoBuffer(buf, flag); - const char *name = mangle(sym); - buf->writestring(name); -} - Expression *TypeTypedef::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { #if LOGDOTEXP @@ -7854,14 +7620,6 @@ Dsymbol *TypeStruct::toDsymbol(Scope *sc) return sym; } -void TypeStruct::toDecoBuffer(OutBuffer *buf, int flag) -{ - const char *name = mangle(sym); - //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name); - Type::toDecoBuffer(buf, flag); - buf->writestring(name); -} - Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { Dsymbol *s; @@ -8399,14 +8157,6 @@ Dsymbol *TypeClass::toDsymbol(Scope *sc) return sym; } -void TypeClass::toDecoBuffer(OutBuffer *buf, int flag) -{ - const char *name = mangle(sym); - //printf("TypeClass::toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name); - Type::toDecoBuffer(buf, flag); - buf->writestring(name); -} - Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag) { Dsymbol *s; @@ -9060,17 +8810,6 @@ Type *TypeTuple::makeConst() } #endif -void TypeTuple::toDecoBuffer(OutBuffer *buf, int flag) -{ - //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars()); - Type::toDecoBuffer(buf, flag); - OutBuffer buf2; - buf2.reserve(32); - Parameter::argsToDecoBuffer(&buf2, arguments); - int len = (int)buf2.offset; - buf->printf("%d%.*s", len, len, (char *)buf2.extractData()); -} - Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag) { Expression *e; @@ -9292,12 +9031,6 @@ bool TypeNull::checkBoolean() return true; } -void TypeNull::toDecoBuffer(OutBuffer *buf, int flag) -{ - //tvoidptr->toDecoBuffer(buf, flag); - Type::toDecoBuffer(buf, flag); -} - d_uns64 TypeNull::size(Loc loc) { return tvoidptr->size(loc); } Expression *TypeNull::defaultInit(Loc loc) { return new NullExp(Loc(), Type::tnull); } @@ -9337,19 +9070,6 @@ Parameters *Parameter::arraySyntaxCopy(Parameters *args) return a; } -static int argsToDecoBufferDg(void *ctx, size_t n, Parameter *arg) -{ - arg->toDecoBuffer((OutBuffer *)ctx); - return 0; -} - -void Parameter::argsToDecoBuffer(OutBuffer *buf, Parameters *arguments) -{ - //printf("Parameter::argsToDecoBuffer()\n"); - // Write argument types - foreach(arguments, &argsToDecoBufferDg, buf); -} - /**************************************** * Determine if parameter list is really a template parameter list * (i.e. it has auto or alias parameters) @@ -9397,33 +9117,6 @@ Type *Parameter::isLazyArray() return NULL; } -void Parameter::toDecoBuffer(OutBuffer *buf) -{ - if (storageClass & STCscope) - buf->writeByte('M'); - switch (storageClass & (STCin | STCout | STCref | STClazy)) - { case 0: - case STCin: - break; - case STCout: - buf->writeByte('J'); - break; - case STCref: - buf->writeByte('K'); - break; - case STClazy: - buf->writeByte('L'); - break; - default: -#ifdef DEBUG - printf("storageClass = x%llx\n", storageClass & (STCin | STCout | STCref | STClazy)); - halt(); -#endif - assert(0); - } - type->toDecoBuffer(buf, 0); -} - /*************************************** * Determine number of arguments, folding in tuples. */ diff --git a/src/mtype.h b/src/mtype.h index e931a580bb88..d1f29162a028 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -28,13 +28,11 @@ class Identifier; class Expression; class StructDeclaration; class ClassDeclaration; -class VarDeclaration; class EnumDeclaration; class TypedefDeclaration; class TypeInfoDeclaration; class Dsymbol; class TemplateInstance; -struct CppMangleState; class TemplateDeclaration; enum LINK; @@ -48,7 +46,6 @@ typedef union tree_node type; typedef struct TYPE type; #endif struct Symbol; -class TypeTuple; void semanticTypeInfo(Scope *sc, Type *t); MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm = NULL, size_t inferStart = 0); @@ -223,7 +220,6 @@ class Type : public RootObject static TemplateDeclaration *rtinfo; static Type *basic[TMAX]; - static unsigned char mangleChar[TMAX]; static unsigned char sizeTy[TMAX]; static StringTable stringtable; @@ -255,7 +251,6 @@ class Type : public RootObject virtual unsigned alignsize(); virtual Type *semantic(Loc loc, Scope *sc); Type *trySemantic(Loc loc, Scope *sc); - virtual void toDecoBuffer(OutBuffer *buf, int flag = 0); Type *merge(); Type *merge2(); void modToBuffer(OutBuffer *buf); @@ -381,7 +376,6 @@ class TypeNext : public Type Type *next; TypeNext(TY ty, Type *next); - void toDecoBuffer(OutBuffer *buf, int flag); void checkDeprecated(Loc loc, Scope *sc); int hasWild(); Type *nextOf(); @@ -445,7 +439,6 @@ class TypeVector : public Type Expression *getProperty(Loc loc, Identifier *ident, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); char *toChars(); - void toDecoBuffer(OutBuffer *buf, int flag); bool isintegral(); bool isfloating(); bool isscalar(); @@ -482,7 +475,6 @@ class TypeSArray : public TypeArray unsigned alignsize(); Type *semantic(Loc loc, Scope *sc); void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); bool isString(); bool isZeroInit(Loc loc); @@ -511,7 +503,6 @@ class TypeDArray : public TypeArray unsigned alignsize(); Type *semantic(Loc loc, Scope *sc); void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); bool isString(); bool isZeroInit(Loc loc); @@ -539,7 +530,6 @@ class TypeAArray : public TypeArray d_uns64 size(Loc loc); Type *semantic(Loc loc, Scope *sc); void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); Expression *defaultInit(Loc loc); bool isZeroInit(Loc loc); @@ -650,7 +640,6 @@ class TypeFunction : public TypeNext Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); void purityLevel(); - void toDecoBuffer(OutBuffer *buf, int flag); TypeInfoDeclaration *getTypeInfoDeclaration(); bool hasLazyParameters(); bool parameterEscapes(Parameter *p); @@ -717,7 +706,6 @@ class TypeIdentifier : public TypeQualified const char *kind(); Type *syntaxCopy(); //char *toChars(); - void toDecoBuffer(OutBuffer *buf, int flag); void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); Dsymbol *toDsymbol(Scope *sc); Type *semantic(Loc loc, Scope *sc); @@ -736,7 +724,6 @@ class TypeInstance : public TypeQualified const char *kind(); Type *syntaxCopy(); //char *toChars(); - //void toDecoBuffer(OutBuffer *buf, int flag); void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false); Type *semantic(Loc loc, Scope *sc); Dsymbol *toDsymbol(Scope *sc); @@ -798,7 +785,6 @@ class TypeStruct : public Type Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); Dsymbol *toDsymbol(Scope *sc); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); structalign_t alignment(); Expression *defaultInit(Loc loc); @@ -831,7 +817,6 @@ class TypeEnum : public Type char *toChars(); Type *semantic(Loc loc, Scope *sc); Dsymbol *toDsymbol(Scope *sc); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); Expression *getProperty(Loc loc, Identifier *ident, int flag); bool isintegral(); @@ -871,7 +856,6 @@ class TypeTypedef : public Type char *toChars(); Type *semantic(Loc loc, Scope *sc); Dsymbol *toDsymbol(Scope *sc); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); structalign_t alignment(); Expression *getProperty(Loc loc, Identifier *ident, int flag); @@ -913,7 +897,6 @@ class TypeClass : public Type Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); Dsymbol *toDsymbol(Scope *sc); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag); ClassDeclaration *isClassHandle(); int isBaseOf(Type *t, int *poffset); @@ -947,7 +930,6 @@ class TypeTuple : public Type Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); bool equals(RootObject *o); - void toDecoBuffer(OutBuffer *buf, int flag); Expression *getProperty(Loc loc, Identifier *ident, int flag); Expression *defaultInit(Loc loc); TypeInfoDeclaration *getTypeInfoDeclaration(); @@ -975,7 +957,6 @@ class TypeNull : public Type const char *kind(); Type *syntaxCopy(); - void toDecoBuffer(OutBuffer *buf, int flag); MATCH implicitConvTo(Type *to); bool checkBoolean(); @@ -1001,13 +982,11 @@ class Parameter : public RootObject static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg); Parameter *syntaxCopy(); Type *isLazyArray(); - void toDecoBuffer(OutBuffer *buf); // kludge for template.isType() int dyncast() { return DYNCAST_PARAMETER; } virtual void accept(Visitor *v) { v->visit(this); } static Parameters *arraySyntaxCopy(Parameters *args); - static void argsToDecoBuffer(OutBuffer *buf, Parameters *arguments); static int isTPL(Parameters *arguments); static size_t dim(Parameters *arguments); static Parameter *getNth(Parameters *arguments, size_t nth, size_t *pn = NULL); diff --git a/src/tocsym.c b/src/tocsym.c index 52a03bdd7ca9..24bc643aa2c3 100644 --- a/src/tocsym.c +++ b/src/tocsym.c @@ -69,7 +69,8 @@ Symbol *Dsymbol::toSymbolX(const char *prefix, int sclass, type *t, const char * char idbuf[20]; char *id = idbuf; if (idlen > sizeof(idbuf)) - { id = (char *)malloc(idlen); + { + id = (char *)malloc(idlen); assert(id); } @@ -683,7 +684,8 @@ Symbol *TypeAArray::aaGetSymbol(const char *func, int flags) // See if symbol is already in sarray for (size_t i = 0; i < sarray->dim; i++) - { Symbol *s = (*sarray)[i]; + { + Symbol *s = (*sarray)[i]; if (strcmp(id, s->Sident) == 0) { #ifdef DEBUG From 212f61e5c784ff03ae0c20306ed35321a897fa1b Mon Sep 17 00:00:00 2001 From: k-hara Date: Sun, 31 Aug 2014 16:20:07 +0900 Subject: [PATCH 4/4] [Refactoring] Move expression mangling code into mangle.c --- src/expression.c | 179 -------------------------------------------- src/expression.h | 12 +-- src/mangle.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++ src/template.c | 3 +- 4 files changed, 192 insertions(+), 191 deletions(-) diff --git a/src/expression.c b/src/expression.c index af2dd467ecb2..d2abc8fdf5ee 100644 --- a/src/expression.c +++ b/src/expression.c @@ -2054,11 +2054,6 @@ StringExp *Expression::toStringExp() return NULL; } -void Expression::toMangleBuffer(OutBuffer *buf) -{ - error("expression %s is not a valid template value argument", toChars()); -} - /*************************************** * Return !=0 if expression is an lvalue. */ @@ -2709,14 +2704,6 @@ Expression *IntegerExp::toLvalue(Scope *sc, Expression *e) return new ErrorExp(); } -void IntegerExp::toMangleBuffer(OutBuffer *buf) -{ - if ((sinteger_t)value < 0) - buf->printf("N%lld", -value); - else - buf->printf("i%lld", value); -} - /******************************** ErrorExp **************************/ /* Use this expression for error recovery. @@ -2812,61 +2799,6 @@ int RealExp::isBool(int result) : (value == 0); } -void realToMangleBuffer(OutBuffer *buf, real_t value) -{ - /* Rely on %A to get portable mangling. - * Must munge result to get only identifier characters. - * - * Possible values from %A => mangled result - * NAN => NAN - * -INF => NINF - * INF => INF - * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79 - * 0X1.9P+2 => 19P2 - */ - - if (Port::isNan(value)) - buf->writestring("NAN"); // no -NAN bugs - else if (Port::isInfinity(value)) - buf->writestring(value < 0 ? "NINF" : "INF"); - else - { - const size_t BUFFER_LEN = 36; - char buffer[BUFFER_LEN]; - size_t n = ld_sprint(buffer, 'A', value); - assert(n < BUFFER_LEN); - for (size_t i = 0; i < n; i++) - { char c = buffer[i]; - - switch (c) - { - case '-': - buf->writeByte('N'); - break; - - case '+': - case 'X': - case '.': - break; - - case '0': - if (i < 2) - break; // skip leading 0X - default: - buf->writeByte(c); - break; - } - } - } -} - -void RealExp::toMangleBuffer(OutBuffer *buf) -{ - buf->writeByte('e'); - realToMangleBuffer(buf, value); -} - - /******************************** ComplexExp **************************/ ComplexExp::ComplexExp(Loc loc, complex_t value, Type *type) @@ -2936,16 +2868,6 @@ int ComplexExp::isBool(int result) return !value; } -void ComplexExp::toMangleBuffer(OutBuffer *buf) -{ - buf->writeByte('c'); - real_t r = toReal(); - realToMangleBuffer(buf, r); - buf->writeByte('c'); // separate the two - r = toImaginary(); - realToMangleBuffer(buf, r); -} - /******************************** IdentifierExp **************************/ IdentifierExp::IdentifierExp(Loc loc, Identifier *ident) @@ -3531,11 +3453,6 @@ StringExp *NullExp::toStringExp() return NULL; } -void NullExp::toMangleBuffer(OutBuffer *buf) -{ - buf->writeByte('n'); -} - /******************************** StringExp **************************/ StringExp::StringExp(Loc loc, char *string) @@ -3849,66 +3766,6 @@ unsigned StringExp::charAt(uinteger_t i) return value; } -void StringExp::toMangleBuffer(OutBuffer *buf) -{ char m; - OutBuffer tmp; - unsigned c; - size_t u; - utf8_t *q; - size_t qlen; - - /* Write string in UTF-8 format - */ - switch (sz) - { case 1: - m = 'a'; - q = (utf8_t *)string; - qlen = len; - break; - case 2: - m = 'w'; - for (u = 0; u < len; ) - { - const char *p = utf_decodeWchar((unsigned short *)string, len, &u, &c); - if (p) - error("%s", p); - else - tmp.writeUTF8(c); - } - q = (utf8_t *)tmp.data; - qlen = tmp.offset; - break; - case 4: - m = 'd'; - for (u = 0; u < len; u++) - { - c = ((unsigned *)string)[u]; - if (!utf_isValidDchar(c)) - error("invalid UCS-32 char \\U%08x", c); - else - tmp.writeUTF8(c); - } - q = (utf8_t *)tmp.data; - qlen = tmp.offset; - break; - default: - assert(0); - } - buf->reserve(1 + 11 + 2 * qlen); - buf->writeByte(m); - buf->printf("%d_", (int)qlen); // nbytes <= 11 - - for (utf8_t *p = (utf8_t *)buf->data + buf->offset, *pend = p + 2 * qlen; - p < pend; p += 2, ++q) - { - utf8_t hi = *q >> 4 & 0xF; - p[0] = (utf8_t)(hi < 10 ? hi + '0' : hi - 10 + 'a'); - utf8_t lo = *q & 0xF; - p[1] = (utf8_t)(lo < 10 ? lo + '0' : lo - 10 + 'a'); - } - buf->offset += 2 * qlen; -} - /************************ ArrayLiteralExp ************************************/ // [ e1, e2, e3, ... ] @@ -4041,16 +3898,6 @@ StringExp *ArrayLiteralExp::toStringExp() return NULL; } -void ArrayLiteralExp::toMangleBuffer(OutBuffer *buf) -{ - size_t dim = elements ? elements->dim : 0; - buf->printf("A%u", dim); - for (size_t i = 0; i < dim; i++) - { Expression *e = (*elements)[i]; - e->toMangleBuffer(buf); - } -} - /************************ AssocArrayLiteralExp ************************************/ // [ key0 : value0, key1 : value1, ... ] @@ -4145,19 +3992,6 @@ int AssocArrayLiteralExp::isBool(int result) return result ? (dim != 0) : (dim == 0); } -void AssocArrayLiteralExp::toMangleBuffer(OutBuffer *buf) -{ - size_t dim = keys->dim; - buf->printf("A%u", dim); - for (size_t i = 0; i < dim; i++) - { Expression *key = (*keys)[i]; - Expression *value = (*values)[i]; - - key->toMangleBuffer(buf); - value->toMangleBuffer(buf); - } -} - /************************ StructLiteralExp ************************************/ // sd( e1, e2, e3, ... ) @@ -4362,19 +4196,6 @@ int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) return -1; } -void StructLiteralExp::toMangleBuffer(OutBuffer *buf) -{ - size_t dim = elements ? elements->dim : 0; - buf->printf("S%u", dim); - for (size_t i = 0; i < dim; i++) - { Expression *e = (*elements)[i]; - if (e) - e->toMangleBuffer(buf); - else - buf->writeByte('v'); // 'v' for void - } -} - /************************ TypeDotIdExp ************************************/ /* Things like: diff --git a/src/expression.h b/src/expression.h index cfee285f20fa..75ba8c1b6103 100644 --- a/src/expression.h +++ b/src/expression.h @@ -174,7 +174,6 @@ class Expression : public RootObject virtual real_t toImaginary(); virtual complex_t toComplex(); virtual StringExp *toStringExp(); - virtual void toMangleBuffer(OutBuffer *buf); virtual int isLvalue(); virtual Expression *toLvalue(Scope *sc, Expression *e); virtual Expression *modifiableLvalue(Scope *sc, Expression *e); @@ -242,10 +241,9 @@ class Expression : public RootObject class IntegerExp : public Expression { -private: +public: dinteger_t value; -public: IntegerExp(Loc loc, dinteger_t value, Type *type); IntegerExp(dinteger_t value); bool equals(RootObject *o); @@ -255,7 +253,6 @@ class IntegerExp : public Expression real_t toImaginary(); complex_t toComplex(); int isBool(int result); - void toMangleBuffer(OutBuffer *buf); Expression *toLvalue(Scope *sc, Expression *e); void accept(Visitor *v) { v->visit(this); } dinteger_t getInteger() { return value; } @@ -288,7 +285,6 @@ class RealExp : public Expression real_t toImaginary(); complex_t toComplex(); int isBool(int result); - void toMangleBuffer(OutBuffer *buf); void accept(Visitor *v) { v->visit(this); } }; @@ -306,7 +302,6 @@ class ComplexExp : public Expression real_t toImaginary(); complex_t toComplex(); int isBool(int result); - void toMangleBuffer(OutBuffer *buf); void accept(Visitor *v) { v->visit(this); } }; @@ -377,7 +372,6 @@ class NullExp : public Expression Expression *semantic(Scope *sc); int isBool(int result); StringExp *toStringExp(); - void toMangleBuffer(OutBuffer *buf); void accept(Visitor *v) { v->visit(this); } }; @@ -406,7 +400,6 @@ class StringExp : public Expression Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); unsigned charAt(uinteger_t i); - void toMangleBuffer(OutBuffer *buf); void accept(Visitor *v) { v->visit(this); } }; @@ -450,7 +443,6 @@ class ArrayLiteralExp : public Expression Expression *semantic(Scope *sc); int isBool(int result); StringExp *toStringExp(); - void toMangleBuffer(OutBuffer *buf); void accept(Visitor *v) { v->visit(this); } }; @@ -467,7 +459,6 @@ class AssocArrayLiteralExp : public Expression Expression *syntaxCopy(); Expression *semantic(Scope *sc); int isBool(int result); - void toMangleBuffer(OutBuffer *buf); void accept(Visitor *v) { v->visit(this); } }; @@ -521,7 +512,6 @@ class StructLiteralExp : public Expression Expression *semantic(Scope *sc); Expression *getField(Type *type, unsigned offset); int getFieldIndex(Type *type, unsigned offset); - void toMangleBuffer(OutBuffer *buf); Expression *addDtorHook(Scope *sc); Symbol *toSymbol(); diff --git a/src/mangle.c b/src/mangle.c index fc5478525d91..a53293877fce 100644 --- a/src/mangle.c +++ b/src/mangle.c @@ -25,6 +25,8 @@ #include "id.h" #include "module.h" #include "enum.h" +#include "expression.h" +#include "utf.h" char *toCppMangle(Dsymbol *s); void mangleToBuffer(Type *t, OutBuffer *buf); @@ -641,6 +643,187 @@ class Mangler : public Visitor //////////////////////////////////////////////////////////////////////////// + void visit(Expression *e) + { + e->error("expression %s is not a valid template value argument", e->toChars()); + } + + void visit(IntegerExp *e) + { + if ((sinteger_t)e->value < 0) + buf->printf("N%lld", -e->value); + else + buf->printf("i%lld", e->value); + } + + void visit(RealExp *e) + { + buf->writeByte('e'); + realToMangleBuffer(e->value); + } + + void realToMangleBuffer(real_t value) + { + /* Rely on %A to get portable mangling. + * Must munge result to get only identifier characters. + * + * Possible values from %A => mangled result + * NAN => NAN + * -INF => NINF + * INF => INF + * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79 + * 0X1.9P+2 => 19P2 + */ + + if (Port::isNan(value)) + buf->writestring("NAN"); // no -NAN bugs + else if (Port::isInfinity(value)) + buf->writestring(value < 0 ? "NINF" : "INF"); + else + { + const size_t BUFFER_LEN = 36; + char buffer[BUFFER_LEN]; + size_t n = ld_sprint(buffer, 'A', value); + assert(n < BUFFER_LEN); + for (size_t i = 0; i < n; i++) + { + char c = buffer[i]; + switch (c) + { + case '-': + buf->writeByte('N'); + break; + + case '+': + case 'X': + case '.': + break; + + case '0': + if (i < 2) + break; // skip leading 0X + default: + buf->writeByte(c); + break; + } + } + } + } + + void visit(ComplexExp *e) + { + buf->writeByte('c'); + realToMangleBuffer(e->toReal()); + buf->writeByte('c'); // separate the two + realToMangleBuffer(e->toImaginary()); + } + + void visit(NullExp *e) + { + buf->writeByte('n'); + } + + void visit(StringExp *e) + { + char m; + OutBuffer tmp; + utf8_t *q; + size_t qlen; + + /* Write string in UTF-8 format + */ + switch (e->sz) + { + case 1: + m = 'a'; + q = (utf8_t *)e->string; + qlen = e->len; + break; + + case 2: + m = 'w'; + for (size_t u = 0; u < e->len; ) + { + unsigned c; + const char *p = utf_decodeWchar((unsigned short *)e->string, e->len, &u, &c); + if (p) + e->error("%s", p); + else + tmp.writeUTF8(c); + } + q = (utf8_t *)tmp.data; + qlen = tmp.offset; + break; + + case 4: + m = 'd'; + for (size_t u = 0; u < e->len; u++) + { + unsigned c = ((unsigned *)e->string)[u]; + if (!utf_isValidDchar(c)) + e->error("invalid UCS-32 char \\U%08x", c); + else + tmp.writeUTF8(c); + } + q = (utf8_t *)tmp.data; + qlen = tmp.offset; + break; + + default: + assert(0); + } + buf->reserve(1 + 11 + 2 * qlen); + buf->writeByte(m); + buf->printf("%d_", (int)qlen); // nbytes <= 11 + + for (utf8_t *p = (utf8_t *)buf->data + buf->offset, *pend = p + 2 * qlen; + p < pend; p += 2, ++q) + { + utf8_t hi = *q >> 4 & 0xF; + p[0] = (utf8_t)(hi < 10 ? hi + '0' : hi - 10 + 'a'); + utf8_t lo = *q & 0xF; + p[1] = (utf8_t)(lo < 10 ? lo + '0' : lo - 10 + 'a'); + } + buf->offset += 2 * qlen; + } + + void visit(ArrayLiteralExp *e) + { + size_t dim = e->elements ? e->elements->dim : 0; + buf->printf("A%u", dim); + for (size_t i = 0; i < dim; i++) + { + (*e->elements)[i]->accept(this); + } + } + + void visit(AssocArrayLiteralExp *e) + { + size_t dim = e->keys->dim; + buf->printf("A%u", dim); + for (size_t i = 0; i < dim; i++) + { + (*e->keys)[i]->accept(this); + (*e->values)[i]->accept(this); + } + } + + void visit(StructLiteralExp *e) + { + size_t dim = e->elements ? e->elements->dim : 0; + buf->printf("S%u", dim); + for (size_t i = 0; i < dim; i++) + { + Expression *ex = (*e->elements)[i]; + if (ex) + ex->accept(this); + else + buf->writeByte('v'); // 'v' for void + } + } + + //////////////////////////////////////////////////////////////////////////// + void argsToDecoBuffer(Parameters *arguments) { //printf("Parameter::argsToDecoBuffer()\n"); @@ -720,3 +903,9 @@ void mangleToBuffer(Type *t, OutBuffer *buf, bool internal) else mangleToBuffer(t, buf); } + +void mangleToBuffer(Expression *e, OutBuffer *buf) +{ + Mangler v(buf); + e->accept(&v); +} diff --git a/src/template.c b/src/template.c index b24308467968..ee650d5cf99e 100644 --- a/src/template.c +++ b/src/template.c @@ -44,6 +44,7 @@ int arrayObjectMatch(Objects *oa1, Objects *oa2); hash_t arrayObjectHash(Objects *oa1); unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam); MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam); +void mangleToBuffer(Expression *e, OutBuffer *buf); /******************************************** * These functions substitute for dynamic_cast. dynamic_cast does not work @@ -7374,7 +7375,7 @@ Identifier *TemplateInstance::genIdent(Objects *args) /* Use deco that matches what it would be for a function parameter */ buf.writestring(ea->type->deco); - ea->toMangleBuffer(&buf); + mangleToBuffer(ea, &buf); } else if (sa) {