1: 
  2: // Compiler implementation of the D programming language
  3: // Copyright (c) 1999-2010 by Digital Mars
  4: // All Rights Reserved
  5: // written by Walter Bright
  6: // http://www.digitalmars.com
  7: // License for redistribution is by either the Artistic License
  8: // in artistic.txt, or the GNU General Public License in gnu.txt.
  9: // See the included readme.txt for details.
 10: 
 11: #include <stdio.h>
 12: #include <string.h>
 13: #include <ctype.h>
 14: static char __file__[] = __FILE__;      /* for tassert.h                */
 15: #include        "tassert.h"
 16: 
 17: #include "cdef.h"
 18: #include "root.h"
 19: 
 20: #include "init.h"
 21: #include "declaration.h"
 22: #include "aggregate.h"
 23: #include "mtype.h"
 24: #include "attrib.h"
 25: #include "template.h"
 26: #include "id.h"
 27: #include "module.h"
 28: 
 29: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
 30: char *cpp_mangle(Dsymbol *s);
 31: #endif
 32: 
 33: char *mangle(Declaration *sthis)
 34: {
 35:     OutBuffer buf;
 36:     char *id;
 37:     Dsymbol *s;
 38: 
 39:     //printf("::mangle(%s)\n", sthis->toChars());
 40:     s = sthis;
 41:     do
 42:     {
 43:         //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
 44:         if (s->ident)
 45:         {
 46:             FuncDeclaration *fd = s->isFuncDeclaration();
 47:             if (s != sthis && fd)
 48:             {
 49:                 id = mangle(fd);
 50:                 buf.prependstring(id);
 51:                 goto L1;
 52:             }
 53:             else
 54:             {
 55:                 id = s->ident->toChars();
 56:                 int len = strlen(id);
 57:                 char tmp[sizeof(len) * 3 + 1];
 58:                 buf.prependstring(id);
 59:                 sprintf(tmp, "%d", len);
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
60: buf.prependstring(tmp); 61: } 62: } 63: else 64: buf.prependstring("0"); 65: s = s->parent; 66: } while (s); 67: 68: // buf.prependstring("_D"); 69: L1: 70: //printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null"); 71: //printf("sthis->type = %s\n", sthis->type->toChars()); 72: FuncDeclaration *fd = sthis->isFuncDeclaration(); 73: if (fd && (fd->needThis() || fd->isNested())) 74: buf.writeByte(Type::needThisPrefix()); 75: if (sthis->type->deco) 76: buf.writestring(sthis->type->deco); 77: else 78: { 79: #ifdef DEBUG 80: if (!fd->inferRetType) 81: printf("%s\n", fd->toChars()); 82: #endif 83: assert(fd && fd->inferRetType); 84: } 85: 86: id = buf.toChars(); 87: buf.data = NULL; 88: return id; 89: } 90: 91: char *Declaration::mangle() 92: #if __DMC__ 93: __out(result) 94: { 95: int len = strlen(result); 96: 97: assert(len > 0); 98: //printf("mangle: '%s' => '%s'\n", toChars(), result); 99: for (int i = 0; i < len; i++) 100: { 101: assert(result[i] == '_' || 102: result[i] == '@' || 103: isalnum(result[i]) || result[i] & 0x80); 104: } 105: } 106: __body 107: #endif 108: { 109: //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage); 110: if (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope 111: { 112: // If it's not a D declaration, no mangling 113: switch (linkage) 114: { 115: case LINKd: 116: break; 117: 118: case LINKc: 119: case LINKwindows: 120: case LINKpascal: 121: return ident->toChars(); 122: 123: case LINKcpp: 124: #if CPP_MANGLE 125: return cpp_mangle(this); 126: #else 127: // Windows C++ mangling is done by C++ back end 128: return ident->toChars(); 129: #endif 130: 131: case LINKdefault: 132: error("forward declaration"); 133: return ident->toChars(); 134: 135: default: 136: fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage); 137: assert(0); 138: } 139: } 140: char *p = ::mangle(this); 141: OutBuffer buf; 142: buf.writestring("_D"); 143: buf.writestring(p); 144: p = buf.toChars(); 145: buf.data = NULL; 146: //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p); 147: return p; 148: } 149: 150: char *FuncDeclaration::mangle() 151: #if __DMC__ 152: __out(result) 153: { 154: assert(strlen(result) > 0); 155: } 156: __body 157: #endif 158: { 159: if (isMain()) 160: return (char *)"_Dmain"; 161: 162: if (isWinMain() || isDllMain() || ident == Id::tls_get_addr) 163: return ident->toChars(); 164: 165: assert(this); 166: return Declaration::mangle(); 167: } 168: 169: char *StructDeclaration::mangle() 170: { 171: //printf("StructDeclaration::mangle() '%s'\n", toChars()); 172: return Dsymbol::mangle(); 173: } 174: 175: 176: char *TypedefDeclaration::mangle() 177: { 178: //printf("TypedefDeclaration::mangle() '%s'\n", toChars()); 179: return Dsymbol::mangle(); 180: } 181: 182: 183: char *ClassDeclaration::mangle() 184: { 185: Dsymbol *parentsave = parent; 186: 187: //printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars()); 188: 189: /* These are reserved to the compiler, so keep simple 190: * names for them. 191: */ 192: if (ident == Id::Exception) 193: { if (parent->ident == Id::object) 194: parent = NULL; 195: } 196: else if (ident == Id::TypeInfo || 197: // ident == Id::Exception || 198: ident == Id::TypeInfo_Struct || 199: ident == Id::TypeInfo_Class || 200: ident == Id::TypeInfo_Typedef || 201: ident == Id::TypeInfo_Tuple || 202: this == object || 203: this == classinfo || 204: this == Module::moduleinfo || 205: memcmp(ident->toChars(), "TypeInfo_", 9) == 0 206: ) 207: parent = NULL; 208: 209: char *id = Dsymbol::mangle(); 210: parent = parentsave; 211: return id; 212: } 213: 214: 215: char *TemplateInstance::mangle() 216: { 217: OutBuffer buf; 218: 219: #if 0 220: printf("TemplateInstance::mangle() %p %s", this, toChars()); 221: if (parent) 222: printf(" parent = %s %s", parent->kind(), parent->toChars()); 223: printf("\n"); 224: #endif 225: char *id = ident ? ident->toChars() : toChars(); 226: if (!tempdecl) 227: error("is not defined"); 228: else 229: { 230: Dsymbol *par = isnested || isTemplateMixin() ? parent : tempdecl->parent; 231: if (par) 232: { 233: char *p = par->mangle(); 234: if (p[0] == '_' && p[1] == 'D') 235: p += 2; 236: buf.writestring(p); 237: } 238: } 239: buf.printf("%"SIZE_T_FORMAT"u%s", strlen(id), id); 240: id = buf.toChars(); 241: buf.data = NULL; 242: //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id); 243: return id; 244: } 245: 246: 247: 248: char *Dsymbol::mangle() 249: { 250: OutBuffer buf; 251: char *id; 252: 253: #if 0 254: printf("Dsymbol::mangle() '%s'", toChars()); 255: if (parent) 256: printf(" parent = %s %s", parent->kind(), parent->toChars()); 257: printf("\n"); 258: #endif 259: id = ident ? ident->toChars() : toChars(); 260: if (parent) 261: { 262: char *p = parent->mangle(); 263: if (p[0] == '_' && p[1] == 'D') 264: p += 2; 265: buf.writestring(p); 266: } 267: buf.printf("%"SIZE_T_FORMAT"u%s", strlen(id), id); 268: id = buf.toChars(); 269: buf.data = NULL; 270: //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); 271: return id; 272: } 273: 274: 275: