void visit(Declaration *d) { //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage); if (!d->parent || d->parent->isModule() || d->linkage == LINKcpp) // if at global scope { switch (d->linkage) { case LINKd: break; case LINKc: case LINKwindows: case LINKpascal: result = d->ident->toChars(); break; case LINKcpp: result = toCppMangle(d); break; case LINKdefault: d->error("forward declaration"); result = d->ident->toChars(); break; default: fprintf(stderr, "'%s', linkage = %d\n", d->toChars(), d->linkage); assert(0); } } if (!result) { OutBuffer buf; buf.writestring("_D"); mangleDecl(&buf, d); result = buf.extractString(); } #ifdef DEBUG assert(result); size_t len = strlen(result); 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); } #endif }
void visit(Declaration *d) { //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", // d, d->toChars(), d->parent ? d->parent->toChars() : "null", d->linkage); if (!d->parent || d->parent->isModule() || d->linkage == LINKcpp) // if at global scope { switch (d->linkage) { case LINKd: break; case LINKc: case LINKwindows: case LINKpascal: buf->writestring(d->ident->toChars()); return; case LINKcpp: buf->writestring(toCppMangle(d)); return; case LINKdefault: d->error("forward declaration"); buf->writestring(d->ident->toChars()); return; default: fprintf(stderr, "'%s', linkage = %d\n", d->toChars(), d->linkage); assert(0); return; } } buf->writestring("_D"); mangleDecl(d); #ifdef DEBUG assert(buf->data); size_t len = buf->offset; assert(len > 0); for (size_t i = 0; i < len; i++) { assert(buf->data[i] == '_' || buf->data[i] == '@' || buf->data[i] == '?' || buf->data[i] == '$' || isalnum(buf->data[i]) || buf->data[i] & 0x80); } #endif }
/****************************************************************************** * isv : for the enclosing auto functions of an inner class/struct type. * An aggregate type which defined inside auto function, it might * become Voldemort Type so its object might be returned. * This flag is necessary due to avoid mutual mangling * between return type and enclosing scope. See bugzilla 8847. */ char *mangleDecl(Declaration *sthis, bool isv) { OutBuffer buf; char *id; Dsymbol *s; //printf("::mangleDecl(%s)\n", sthis->toChars()); s = sthis; do { //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent); if (s->getIdent()) { FuncDeclaration *fd = s->isFuncDeclaration(); if (s != sthis && fd) { id = mangleDecl(fd, isv); buf.prependstring(id); goto L1; } else { id = s->ident->toChars(); size_t len = strlen(id); char tmp[sizeof(len) * 3 + 1]; buf.prependstring(id); sprintf(tmp, "%d", (int)len); buf.prependstring(tmp); } } else buf.prependstring("0"); TemplateInstance *ti = s->isTemplateInstance(); if (ti && !ti->isTemplateMixin()) s = ti->tempdecl->parent; else s = s->parent; } while (s); // buf.prependstring("_D"); L1: //printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null"); //printf("sthis->type = %s\n", sthis->type->toChars()); FuncDeclaration *fd = sthis->isFuncDeclaration(); if (fd && (fd->needThis() || fd->isNested())) buf.writeByte(Type::needThisPrefix()); if (isv && fd && (fd->inferRetType || getFuncTemplateDecl(fd))) { #if DDMD TypeFunction *tfn = (TypeFunction *)sthis->type->copy(); TypeFunction *tfo = (TypeFunction *)sthis->originalType; tfn->purity = tfo->purity; tfn->isnothrow = tfo->isnothrow; tfn->isproperty = tfo->isproperty; tfn->isref = fd->storage_class & STCauto ? false : tfo->isref; tfn->trust = tfo->trust; tfn->next = NULL; // do not mangle return type tfn->toDecoBuffer(&buf, 0); #else TypeFunction tfn = *(TypeFunction *)sthis->type; TypeFunction *tfo = (TypeFunction *)sthis->originalType; tfn.purity = tfo->purity; tfn.isnothrow = tfo->isnothrow; tfn.isproperty = tfo->isproperty; tfn.isref = fd->storage_class & STCauto ? false : tfo->isref; tfn.trust = tfo->trust; tfn.next = NULL; // do not mangle return type tfn.toDecoBuffer(&buf, 0); #endif } else if (sthis->type->deco) buf.writestring(sthis->type->deco); else { #ifdef DEBUG if (!fd->inferRetType) printf("%s\n", fd->toChars()); #endif assert(fd && fd->inferRetType && fd->type->ty == Tfunction); TypeFunction *tf = (TypeFunction *)sthis->type; Type *tn = tf->next; tf->next = NULL; // do not mangle undetermined return type tf->toDecoBuffer(&buf, 0); tf->next = tn; } id = buf.extractString(); return id; }