void StructDeclaration::semanticTypeInfoMembers() { if (xeq && xeq->scope && xeq->semanticRun < PASSsemantic3done) { unsigned errors = global.startGagging(); xeq->semantic3(xeq->scope); if (global.endGagging(errors)) xeq = xerreq; } if (xcmp && xcmp->scope && xcmp->semanticRun < PASSsemantic3done) { unsigned errors = global.startGagging(); xcmp->semantic3(xcmp->scope); if (global.endGagging(errors)) xcmp = xerrcmp; } FuncDeclaration *ftostr = search_toString(this); if (ftostr && ftostr->scope && ftostr->semanticRun < PASSsemantic3done) { ftostr->semantic3(ftostr->scope); } if (xhash && xhash->scope && xhash->semanticRun < PASSsemantic3done) { xhash->semantic3(xhash->scope); } if (postblit && postblit->scope && postblit->semanticRun < PASSsemantic3done) { postblit->semantic3(postblit->scope); } if (dtor && dtor->scope && dtor->semanticRun < PASSsemantic3done) { dtor->semantic3(dtor->scope); } }
void visit(TypeStruct *t) { StructDeclaration *sd = t->sym; if (sd->members && (sd->xeq && sd->xeq != sd->xerreq || sd->xcmp && sd->xcmp != sd->xerrcmp || (sd->postblit && !(sd->postblit->storage_class & STCdisable)) || sd->dtor || sd->xhash || search_toString(sd) ) && sd->inNonRoot()) { //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot()); Module::addDeferredSemantic3(sd); } }
void visit(TypeStruct *t) { StructDeclaration *sd = t->sym; if (!sd->members) return; // opaque struct if (sd->semanticRun >= PASSsemantic3) return; // semantic3 will be done if (!sd->xeq && !sd->xcmp && !sd->postblit && !sd->dtor && !sd->xhash && !search_toString(sd)) return; // none of TypeInfo-specific members // If the struct is in a non-root module, run semantic3 to get // correct symbols for the member function. if (TemplateInstance *ti = sd->isInstantiated()) { if (ti->minst && !ti->minst->isRoot()) Module::addDeferredSemantic3(sd); } else { if (sd->inNonRoot()) { //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot()); Module::addDeferredSemantic3(sd); } } if (!sc) // inline may request TypeInfo. { Scope scx; scx.module = sd->getModule(); getTypeInfoType(t, &scx); } else getTypeInfoType(t, sc); if (!sc || sc->minst) sd->requestTypeInfo = true; }
void TypeInfoStructDeclaration::toDt(dt_t **pdt) { //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); if (global.params.is64bit) verifyStructSize(Type::typeinfostruct, 17 * Target::ptrsize); else verifyStructSize(Type::typeinfostruct, 15 * Target::ptrsize); dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0); // vtbl for TypeInfo_Struct dtsize_t(pdt, 0); // monitor assert(tinfo->ty == Tstruct); TypeStruct *tc = (TypeStruct *)tinfo; StructDeclaration *sd = tc->sym; if (!sd->members) return; /* Put out: * char[] name; * void[] init; * hash_t function(in void*) xtoHash; * bool function(in void*, in void*) xopEquals; * int function(in void*, in void*) xopCmp; * string function(const(void)*) xtoString; * StructFlags m_flags; * //xgetMembers; * xdtor; * xpostblit; * uint m_align; * version (X86_64) * TypeInfo m_arg1; * TypeInfo m_arg2; * xgetRTInfo */ const char *name = sd->toPrettyChars(); size_t namelen = strlen(name); dtsize_t(pdt, namelen); dtabytes(pdt, 0, namelen + 1, name); // void[] init; dtsize_t(pdt, sd->structsize); // init.length if (sd->zeroInit) dtsize_t(pdt, 0); // NULL for 0 initialization else dtxoff(pdt, sd->toInitializer(), 0); // init.ptr if (FuncDeclaration *fd = search_toHash(sd)) { dtxoff(pdt, fd->toSymbol(), 0); TypeFunction *tf = (TypeFunction *)fd->type; assert(tf->ty == Tfunction); /* I'm a little unsure this is the right way to do it. Perhaps a better * way would to automatically add these attributes to any struct member * function with the name "toHash". * So I'm leaving this here as an experiment for the moment. */ if (!tf->isnothrow || tf->trust == TRUSTsystem /*|| tf->purity == PUREimpure*/) warning(fd->loc, "toHash() must be declared as extern (D) size_t toHash() const nothrow @safe, not %s", tf->toChars()); } else dtsize_t(pdt, 0); if (sd->xeq) dtxoff(pdt, sd->xeq->toSymbol(), 0); else dtsize_t(pdt, 0); if (sd->xcmp) dtxoff(pdt, sd->xcmp->toSymbol(), 0); else dtsize_t(pdt, 0); if (FuncDeclaration *fd = search_toString(sd)) { dtxoff(pdt, fd->toSymbol(), 0); } else dtsize_t(pdt, 0); // StructFlags m_flags; StructFlags::Type m_flags = 0; if (tc->hasPointers()) m_flags |= StructFlags::hasPointers; dtsize_t(pdt, m_flags); #if DMDV2 #if 0 // xgetMembers FuncDeclaration *sgetmembers = sd->findGetMembers(); if (sgetmembers) dtxoff(pdt, sgetmembers->toSymbol(), 0); else dtsize_t(pdt, 0); // xgetMembers #endif // xdtor FuncDeclaration *sdtor = sd->dtor; if (sdtor) dtxoff(pdt, sdtor->toSymbol(), 0); else dtsize_t(pdt, 0); // xdtor // xpostblit FuncDeclaration *spostblit = sd->postblit; if (spostblit && !(spostblit->storage_class & STCdisable)) dtxoff(pdt, spostblit->toSymbol(), 0); else dtsize_t(pdt, 0); // xpostblit #endif // uint m_align; dtsize_t(pdt, tc->alignsize()); if (global.params.is64bit) { Type *t = sd->arg1type; for (int i = 0; i < 2; i++) { // m_argi if (t) { t->getTypeInfo(NULL); dtxoff(pdt, t->vtinfo->toSymbol(), 0); } else dtsize_t(pdt, 0); t = sd->arg2type; } } // xgetRTInfo if (sd->getRTInfo) sd->getRTInfo->toDt(pdt); else if (m_flags & StructFlags::hasPointers) dtsize_t(pdt, 1); else dtsize_t(pdt, 0); }
Expression *Type::getTypeInfo(Scope *sc) { //printf("Type::getTypeInfo() %p, %s\n", this, toChars()); if (!Type::dtypeinfo) { error(Loc(), "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch"); fatal(); } Type *t = merge2(); // do this since not all Type's are merge'd if (!t->vtinfo) { #if DMDV2 if (t->isShared()) // does both 'shared' and 'shared const' t->vtinfo = new TypeInfoSharedDeclaration(t); else if (t->isConst()) t->vtinfo = new TypeInfoConstDeclaration(t); else if (t->isImmutable()) t->vtinfo = new TypeInfoInvariantDeclaration(t); else if (t->isWild()) t->vtinfo = new TypeInfoWildDeclaration(t); else #endif t->vtinfo = t->getTypeInfoDeclaration(); assert(t->vtinfo); vtinfo = t->vtinfo; /* If this has a custom implementation in std/typeinfo, then * do not generate a COMDAT for it. */ if (!t->builtinTypeInfo()) { // Generate COMDAT if (sc) // if in semantic() pass { // Find module that will go all the way to an object file Module *m = sc->module->importedFrom; m->members->push(t->vtinfo); if (ty == Tstruct) { Dsymbol *s; StructDeclaration *sd = ((TypeStruct *)this)->sym; if ((sd->xeq && sd->xeq != sd->xerreq || sd->xcmp && sd->xcmp != sd->xerrcmp || search_toHash(sd) || search_toString(sd) ) && inNonRoot(sd)) { //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), inNonRoot(sd)); Module::addDeferredSemantic3(sd); } } } else // if in obj generation pass { t->vtinfo->toObjFile(global.params.multiobj); } } } if (!vtinfo) vtinfo = t->vtinfo; // Types aren't merged, but we can share the vtinfo's Expression *e = new VarExp(Loc(), t->vtinfo); e = e->addressOf(sc); e->type = t->vtinfo->type; // do this so we don't get redundant dereference return e; }
TypeInfoDeclaration *Type::buildTypeInfo(Scope *sc, bool checkNeedSemantic) { if (vtinfo) return vtinfo; if (sc && checkNeedSemantic && !typeInfoNeedsSemantic()) return 0; //printf("Type::getTypeInfo() %p, %s\n", this, toChars()); if (!Type::dtypeinfo) { error(Loc(), "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch"); fatal(); } Type *t = merge2(); // do this since not all Type's are merge'd if (!t->vtinfo) { if (t->isShared()) // does both 'shared' and 'shared const' t->vtinfo = new TypeInfoSharedDeclaration(t); else if (t->isConst()) t->vtinfo = new TypeInfoConstDeclaration(t); else if (t->isImmutable()) t->vtinfo = new TypeInfoInvariantDeclaration(t); else if (t->isWild()) t->vtinfo = new TypeInfoWildDeclaration(t); else t->vtinfo = t->getTypeInfoDeclaration(); assert(t->vtinfo); vtinfo = t->vtinfo; /* If this has a custom implementation in std/typeinfo, then * do not generate a COMDAT for it. */ if (t->ty == Terror) vtinfo->errors = 1; else if (!t->builtinTypeInfo()) { // Generate COMDAT if (sc) // if in semantic() pass { // Find module that will go all the way to an object file Module *m = sc->module->importedFrom; m->members->push(t->vtinfo); if(m->semanticRun >= 3) { Module::addDeferredSemantic3(t->vtinfo); t->vtinfo->deferredScope = sc; sc->setNoFree(); } if (ty == Tstruct) { Dsymbol *s; StructDeclaration *sd = ((TypeStruct *)this)->sym; if (sd->members && (sd->xeq && sd->xeq != sd->xerreq || sd->xcmp && sd->xcmp != sd->xerrcmp || search_toHash(sd) || search_toString(sd) ) && inNonRoot(sd)) { //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), inNonRoot(sd)); Module::addDeferredSemantic3(sd); } } } else // if in obj generation pass { // it is always a problem if this is called from the backend without // being added to the AST for semantic analysis (no RTInfo generated) // to ease transition, modifier types are just put out as they just forward // to the actual TypeInfo if (t->typeInfoNeedsSemantic()) error(Loc(), "ICE: unexpected type info request for %s", t->toChars()); t->vtinfo->toObjFile(global.params.multiobj); } } } if (!vtinfo) vtinfo = t->vtinfo; // Types aren't merged, but we can share the vtinfo's return vtinfo; }
void AggregateDeclaration::semantic3(Scope *sc) { //printf("AggregateDeclaration::semantic3(%s)\n", toChars()); if (members) { StructDeclaration *sd = isStructDeclaration(); if (!sc) // from runDeferredSemantic3 for TypeInfo generation goto Lxop; sc = sc->push(this); sc->parent = this; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; s->semantic3(sc); } sc = sc->pop(); if (!getRTInfo && Type::rtinfo && (!isDeprecated() || global.params.useDeprecated) && // don't do it for unused deprecated types (type && type->ty != Terror)) // or error types { // Evaluate: RTinfo!type Objects *tiargs = new Objects(); tiargs->push(type); TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs); ti->semantic(sc); ti->semantic2(sc); ti->semantic3(sc); Dsymbol *s = ti->toAlias(); Expression *e = new DsymbolExp(Loc(), s, 0); Scope *sc2 = ti->tempdecl->scope->startCTFE(); sc2->instantiatingModule = sc->instantiatingModule ? sc->instantiatingModule : sc->module; e = e->semantic(sc2); sc2->endCTFE(); e = e->ctfeInterpret(); getRTInfo = e; } if (sd) { Lxop: if (sd->xeq && sd->xeq->scope && sd->xeq->semanticRun < PASSsemantic3done) { unsigned errors = global.startGagging(); sd->xeq->semantic3(sd->xeq->scope); if (global.endGagging(errors)) sd->xeq = sd->xerreq; } if (sd->xcmp && sd->xcmp->scope && sd->xcmp->semanticRun < PASSsemantic3done) { unsigned errors = global.startGagging(); sd->xcmp->semantic3(sd->xcmp->scope); if (global.endGagging(errors)) sd->xcmp = sd->xerrcmp; } FuncDeclaration *ftostr = search_toString(sd); if (ftostr && ftostr->scope && ftostr->semanticRun < PASSsemantic3done) { ftostr->semantic3(ftostr->scope); } FuncDeclaration *ftohash = search_toHash(sd); if (ftohash && ftohash->scope && ftohash->semanticRun < PASSsemantic3done) { ftohash->semantic3(ftohash->scope); } } } }
void AggregateDeclaration::semantic3(Scope *sc) { //printf("AggregateDeclaration::semantic3(%s)\n", toChars()); if (members) { StructDeclaration *sd = isStructDeclaration(); if (!sc) // from runDeferredSemantic3 for TypeInfo generation goto Lxop; sc = sc->push(this); sc->parent = this; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; s->semantic3(sc); } sc = sc->pop(); type->buildTypeInfo(sc, false); // implicitely calls generateTypeInfoData if (type->vtinfo && type->builtinTypeInfo()) type->vtinfo->semantic3(sc); if (sd) { Lxop: if (sd->xeq && sd->xeq->scope && sd->xeq->semanticRun < PASSsemantic3done) { unsigned errors = global.startGagging(); sd->xeq->semantic3(sd->xeq->scope); if (global.endGagging(errors)) sd->xeq = sd->xerreq; } if (sd->xcmp && sd->xcmp->scope && sd->xcmp->semanticRun < PASSsemantic3done) { unsigned errors = global.startGagging(); sd->xcmp->semantic3(sd->xcmp->scope); if (global.endGagging(errors)) sd->xcmp = sd->xerrcmp; } FuncDeclaration *ftostr = search_toString(sd); if (ftostr && ftostr->scope && ftostr->semanticRun < PASSsemantic3done) { ftostr->semantic3(ftostr->scope); } FuncDeclaration *ftohash = search_toHash(sd); if (ftohash && ftohash->scope && ftohash->semanticRun < PASSsemantic3done) { ftohash->semantic3(ftohash->scope); } } } }