void nteh_declarvars(Blockx *bx) { symbol *s; #if MARS if (!(bx->funcsym->Sfunc->Fflags3 & Fnteh)) // if haven't already done it { bx->funcsym->Sfunc->Fflags3 |= Fnteh; s = symbol_name(s_name_context,SCbprel,tsint); s->Soffset = -5 * 4; // -6 * 4 for C __try, __except, __finally s->Sflags |= SFLfree | SFLnodebug; type_setty(&s->Stype,mTYvolatile | TYint); symbol_add(s); bx->context = s; } #else if (!(funcsym_p->Sfunc->Fflags3 & Fnteh)) // if haven't already done it { funcsym_p->Sfunc->Fflags3 |= Fnteh; if (!s_context) s_context = scope_search(s_name_context_tag,CPP ? SCTglobal : SCTglobaltag); symbol_debug(s_context); s = symbol_name(s_name_context,SCbprel,s_context->Stype); s->Soffset = -6 * 4; // -5 * 4 for C++ s->Sflags |= SFLfree; symbol_add(s); type_setty(&s->Stype,mTYvolatile | TYstruct); s = symbol_name(s_name_ecode,SCauto,type_alloc(mTYvolatile | TYint)); s->Sflags |= SFLfree; symbol_add(s); } #endif }
type *type_setcv(type **pt,tym_t cv) { unsigned long ty; type_debug(*pt); ty = (*pt)->Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared); return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); }
/** * Creates the data symbol for a TLS variable for Mach-O. * * Input: * vd the variable declaration for the symbol * s the regular symbol for the variable * * Returns: the newly create symbol */ Symbol *createTLVDataSymbol(VarDeclaration *vd, Symbol *s) { assert(config.objfmt == OBJ_MACH && I64 && (s->ty() & mTYLINK) == mTYthread); OutBuffer buffer; buffer.writestring(s->Sident); buffer.write("$tlv$init", 9); const char *tlvInitName = buffer.extractString(); Symbol *tlvInit = symbol_name(tlvInitName, SCstatic, type_fake(vd->type->ty)); tlvInit->Sdt = NULL; tlvInit->Salignment = type_alignsize(s->Stype); type_setty(&tlvInit->Stype, tlvInit->Stype->Tty | mTYthreadData); type_setmangle(&tlvInit->Stype, mangle(vd, tlvInit)); return tlvInit; }
/** * Creates the data symbol used to initialize a TLS variable for Mach-O. * * Params: * vd = the variable declaration for the symbol * s = the back end symbol corresponding to vd * * Returns: the newly created symbol */ Symbol *createTLVDataSymbol(VarDeclaration *vd, Symbol *s) { assert(config.objfmt == OBJ_MACH && I64 && (s->ty() & mTYLINK) == mTYthread); // Compute identifier for tlv symbol OutBuffer buffer; buffer.writestring(s->Sident); buffer.write("$tlv$init", 9); const char *tlvInitName = buffer.peekString(); // Compute type for tlv symbol type *t = type_fake(vd->type->ty); type_setty(&t, t->Tty | mTYthreadData); type_setmangle(&t, mangle(vd)); Symbol *tlvInit = symbol_name(tlvInitName, SCstatic, t); tlvInit->Sdt = NULL; tlvInit->Salignment = type_alignsize(s->Stype); if (vd->linkage == LINKcpp) tlvInit->Sflags |= SFLpublic; return tlvInit; }
Symbol *VarDeclaration::toSymbol() { //printf("VarDeclaration::toSymbol(%s)\n", toChars()); //if (needThis()) *(char*)0=0; assert(!needThis()); if (!csym) { TYPE *t; const char *id; if (isDataseg()) id = mangle(); else id = ident->toChars(); Symbol *s = symbol_calloc(id); s->Salignment = alignment; if (storage_class & (STCout | STCref)) { // should be TYref, but problems in back end t = type_pointer(type->toCtype()); } else if (storage_class & STClazy) { if (config.exe == EX_WIN64 && isParameter()) t = type_fake(TYnptr); else t = type_fake(TYdelegate); // Tdelegate as C type t->Tcount++; } else if (isParameter()) { if (config.exe == EX_WIN64 && type->size(Loc()) > REGSIZE) { // should be TYref, but problems in back end t = type_pointer(type->toCtype()); } else { t = type->toCParamtype(); t->Tcount++; } } else { t = type->toCtype(); t->Tcount++; } if (isDataseg()) { if (isThreadlocal()) { /* Thread local storage */ TYPE *ts = t; ts->Tcount++; // make sure a different t is allocated type_setty(&t, t->Tty | mTYthread); ts->Tcount--; if (global.params.vtls) { char *p = loc.toChars(); fprintf(stderr, "%s: %s is thread local\n", p ? p : "", toChars()); if (p) mem.free(p); } } s->Sclass = SCextern; s->Sfl = FLextern; slist_add(s); /* if it's global or static, then it needs to have a qualified but unmangled name. * This gives some explanation of the separation in treating name mangling. * It applies to PDB format, but should apply to CV as PDB derives from CV. * http://msdn.microsoft.com/en-us/library/ff553493(VS.85).aspx */ s->prettyIdent = toPrettyChars(); } else { s->Sclass = SCauto; s->Sfl = FLauto; if (nestedrefs.dim) { /* Symbol is accessed by a nested function. Make sure * it is not put in a register, and that the optimizer * assumes it is modified across function calls and pointer * dereferences. */ //printf("\tnested ref, not register\n"); type_setcv(&t, t->Tty | mTYvolatile); } } if (ident == Id::va_argsave) /* __va_argsave is set outside of the realm of the optimizer, * so we tell the optimizer to leave it alone */ type_setcv(&t, t->Tty | mTYvolatile); mangle_t m = 0; switch (linkage) { case LINKwindows: m = mTYman_std; break; case LINKpascal: m = mTYman_pas; break; case LINKc: m = mTYman_c; break; case LINKd: m = mTYman_d; break; case LINKcpp: { m = mTYman_cpp; s->Sflags = SFLpublic; Dsymbol *parent = toParent(); ClassDeclaration *cd = parent->isClassDeclaration(); if (cd) { ::type *tc = cd->type->toCtype(); s->Sscope = tc->Tnext->Ttag; } StructDeclaration *sd = parent->isStructDeclaration(); if (sd) { ::type *ts = sd->type->toCtype(); s->Sscope = ts->Ttag; } break; } default: printf("linkage = %d\n", linkage); assert(0); } type_setmangle(&t, m); s->Stype = t; csym = s; } return csym; }
Symbol *VarDeclaration::toSymbol() { //printf("VarDeclaration::toSymbol(%s)\n", toChars()); //if (needThis()) *(char*)0=0; assert(!needThis()); if (!csym) { Symbol *s; TYPE *t; const char *id; mangle_t m = 0; if (isDataseg()) id = mangle(); else id = ident->toChars(); s = symbol_calloc(id); if (storage_class & (STCout | STCref)) { if (global.params.symdebug && storage_class & STCparameter) { t = type_alloc(TYnptr); // should be TYref, but problems in back end t->Tnext = type->toCtype(); t->Tnext->Tcount++; } else t = type_fake(TYnptr); } else if (storage_class & STClazy) t = type_fake(TYdelegate); // Tdelegate as C type else if (isParameter()) t = type->toCParamtype(); else t = type->toCtype(); t->Tcount++; if (isDataseg()) { if (storage_class & STCtls) { /* Thread local storage */ type_setty(&t, t->Tty | mTYthread); } s->Sclass = SCextern; s->Sfl = FLextern; slist_add(s); } else { s->Sclass = SCauto; s->Sfl = FLauto; if (nestedref) { /* Symbol is accessed by a nested function. Make sure * it is not put in a register, and that the optimizer * assumes it is modified across function calls and pointer * dereferences. */ //printf("\tnested ref, not register\n"); type_setcv(&t, t->Tty | mTYvolatile); } } if (storage_class & STCconst) { // Insert const modifiers tym_t tym = 0; if (storage_class & STCconst) tym |= mTYconst; type_setcv(&t, tym); } switch (linkage) { case LINKwindows: m = mTYman_std; break; case LINKpascal: m = mTYman_pas; break; case LINKc: m = mTYman_c; break; case LINKd: m = mTYman_d; break; case LINKcpp: m = mTYman_cpp; break; default: printf("linkage = %d\n", linkage); assert(0); } type_setmangle(&t, m); s->Stype = t; csym = s; } return csym; }
Symbol *VarDeclaration::toSymbol() { //printf("VarDeclaration::toSymbol(%s)\n", toChars()); //if (needThis()) *(char*)0=0; assert(!needThis()); if (!csym) { Symbol *s; TYPE *t; const char *id; if (isDataseg()) id = mangle(); else id = ident->toChars(); s = symbol_calloc(id); if (storage_class & (STCout | STCref)) { if (global.params.symdebug && storage_class & STCparameter) { t = type_alloc(TYnptr); // should be TYref, but problems in back end t->Tnext = type->toCtype(); t->Tnext->Tcount++; } else t = type_fake(TYnptr); } else if (storage_class & STClazy) t = type_fake(TYdelegate); // Tdelegate as C type else if (isParameter()) t = type->toCParamtype(); else t = type->toCtype(); t->Tcount++; if (isDataseg()) { if (isThreadlocal()) { /* Thread local storage */ TYPE *ts = t; ts->Tcount++; // make sure a different t is allocated type_setty(&t, t->Tty | mTYthread); ts->Tcount--; if (global.params.vtls) { char *p = loc.toChars(); fprintf(stdmsg, "%s: %s is thread local\n", p ? p : "", toChars()); if (p) mem.free(p); } } s->Sclass = SCextern; s->Sfl = FLextern; slist_add(s); } else { s->Sclass = SCauto; s->Sfl = FLauto; if (nestedrefs.dim) { /* Symbol is accessed by a nested function. Make sure * it is not put in a register, and that the optimizer * assumes it is modified across function calls and pointer * dereferences. */ //printf("\tnested ref, not register\n"); type_setcv(&t, t->Tty | mTYvolatile); } } if (ident == Id::va_argsave) /* __va_argsave is set outside of the realm of the optimizer, * so we tell the optimizer to leave it alone */ type_setcv(&t, t->Tty | mTYvolatile); mangle_t m = 0; switch (linkage) { case LINKwindows: m = mTYman_std; break; case LINKpascal: m = mTYman_pas; break; case LINKc: m = mTYman_c; break; case LINKd: m = mTYman_d; break; case LINKcpp: m = mTYman_cpp; break; default: printf("linkage = %d\n", linkage); assert(0); } type_setmangle(&t, m); s->Stype = t; csym = s; } return csym; }
void visit(VarDeclaration *vd) { //printf("VarDeclaration::toSymbol(%s)\n", vd->toChars()); assert(!vd->needThis()); if (!vd->csym) { const char *id; if (vd->isDataseg()) id = mangle(vd); else id = vd->ident->toChars(); Symbol *s = symbol_calloc(id); s->Salignment = vd->alignment; if (vd->storage_class & STCtemp) s->Sflags |= SFLartifical; TYPE *t; if (vd->storage_class & (STCout | STCref)) { t = type_allocn(TYnref, Type_toCtype(vd->type)); t->Tcount++; } else if (vd->storage_class & STClazy) { if (config.exe == EX_WIN64 && vd->isParameter()) t = type_fake(TYnptr); else t = type_fake(TYdelegate); // Tdelegate as C type t->Tcount++; } else if (vd->isParameter()) { if (config.exe == EX_WIN64 && vd->type->size(Loc()) > REGSIZE) { t = type_allocn(TYnref, Type_toCtype(vd->type)); t->Tcount++; } else { t = Type_toCtype(vd->type); t->Tcount++; } } else { t = Type_toCtype(vd->type); t->Tcount++; } if (vd->isDataseg()) { if (vd->isThreadlocal()) { /* Thread local storage */ TYPE *ts = t; ts->Tcount++; // make sure a different t is allocated type_setty(&t, t->Tty | mTYthread); ts->Tcount--; if (global.params.vtls) { char *p = vd->loc.toChars(); fprintf(global.stdmsg, "%s: %s is thread local\n", p ? p : "", vd->toChars()); if (p) mem.xfree(p); } } s->Sclass = SCextern; s->Sfl = FLextern; slist_add(s); /* if it's global or static, then it needs to have a qualified but unmangled name. * This gives some explanation of the separation in treating name mangling. * It applies to PDB format, but should apply to CV as PDB derives from CV. * http://msdn.microsoft.com/en-us/library/ff553493(VS.85).aspx */ s->prettyIdent = vd->toPrettyChars(true); } else { s->Sclass = SCauto; s->Sfl = FLauto; if (vd->nestedrefs.dim) { /* Symbol is accessed by a nested function. Make sure * it is not put in a register, and that the optimizer * assumes it is modified across function calls and pointer * dereferences. */ //printf("\tnested ref, not register\n"); type_setcv(&t, t->Tty | mTYvolatile); } } if (vd->ident == Id::va_argsave || vd->storage_class & STCvolatile) { /* __va_argsave is set outside of the realm of the optimizer, * so we tell the optimizer to leave it alone */ type_setcv(&t, t->Tty | mTYvolatile); } mangle_t m = 0; switch (vd->linkage) { case LINKwindows: m = global.params.is64bit ? mTYman_c : mTYman_std; break; case LINKpascal: m = mTYman_pas; break; case LINKc: m = mTYman_c; break; case LINKd: m = mTYman_d; break; case LINKcpp: s->Sflags |= SFLpublic; m = mTYman_d; break; default: printf("linkage = %d\n", vd->linkage); assert(0); } type_setmangle(&t, m); s->Stype = t; vd->csym = s; } result = vd->csym; }