unsigned AggregateDeclaration::size(Loc loc) { //printf("AggregateDeclaration::size() %s, scope = %p\n", toChars(), scope); if (loc.linnum == 0) loc = this->loc; if (sizeok != SIZEOKdone && scope) semantic(NULL); StructDeclaration *sd = isStructDeclaration(); if (sizeok != SIZEOKdone && sd && sd->members) { /* See if enough is done to determine the size, * meaning all the fields are done. */ struct SV { /* Returns: * 0 this member doesn't need further processing to determine struct size * 1 this member does */ static int func(Dsymbol *s, void *param) { VarDeclaration *v = s->isVarDeclaration(); if (v) { if (v->scope) v->semantic(NULL); if (v->storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter)) return 0; if (v->isField() && v->sem >= SemanticDone) return 0; return 1; } return 0; } }; SV sv; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; if (s->apply(&SV::func, &sv)) goto L1; } sd->finalizeSize(NULL); L1: ; } if (!members) { error(loc, "unknown size"); } else if (sizeok != SIZEOKdone) { error(loc, "no size yet for forward reference"); //*(char*)0=0; } return structsize; }
void AggregateDeclaration::semantic3(Scope *sc) { //printf("AggregateDeclaration::semantic3(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors); if (!members) return; StructDeclaration *sd = isStructDeclaration(); if (!sc) // from runDeferredSemantic3 for TypeInfo generation { assert(sd); sd->semanticTypeInfoMembers(); return; } Scope *sc2 = sc->push(this); sc2->stc &= STCsafe | STCtrusted | STCsystem; sc2->parent = this; if (isUnionDeclaration()) sc2->inunion = 1; sc2->protection = Prot(PROTpublic); sc2->explicitProtection = 0; sc2->structalign = STRUCTALIGN_DEFAULT; sc2->userAttribDecl = NULL; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; s->semantic3(sc2); } sc2->pop(); // don't do it for unused deprecated types // or error types if (!getRTInfo && Type::rtinfo && (!isDeprecated() || global.params.useDeprecated) && (type && type->ty != Terror)) { // 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 *sc3 = ti->tempdecl->scope->startCTFE(); sc3->tinst = sc->tinst; e = e->semantic(sc3); sc3->endCTFE(); e = e->ctfeInterpret(); getRTInfo = e; } if (sd) sd->semanticTypeInfoMembers(); }
void AggregateDeclaration::makeNested() { if (!enclosing && sizeok != SIZEOKdone && !isUnionDeclaration() && !isInterfaceDeclaration()) { // If nested struct, add in hidden 'this' pointer to outer scope if (!(storage_class & STCstatic)) { Dsymbol *s = toParent2(); if (s) { AggregateDeclaration *ad = s->isAggregateDeclaration(); FuncDeclaration *fd = s->isFuncDeclaration(); if (fd) { enclosing = fd; } else if (isClassDeclaration() && ad && ad->isClassDeclaration()) { enclosing = ad; } else if (isStructDeclaration() && ad) { if (TemplateInstance *ti = ad->parent->isTemplateInstance()) { enclosing = ti->enclosing; } } if (enclosing) { //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars()); Type *t; if (ad) t = ad->handleType(); else if (fd) { AggregateDeclaration *ad2 = fd->isMember2(); if (ad2) t = ad2->handleType(); else t = Type::tvoidptr; } else assert(0); if (t->ty == Tstruct) t = Type::tvoidptr; // t should not be a ref type assert(!vthis); vthis = new ThisDeclaration(loc, t); //vthis->storage_class |= STCref; members->push(vthis); } } } } }
void AggregateDeclaration::makeNested() { if (enclosing) // if already nested return; if (sizeok == SIZEOKdone) return; if (isUnionDeclaration() || isInterfaceDeclaration()) return; if (storage_class & STCstatic) return; // If nested struct, add in hidden 'this' pointer to outer scope Dsymbol *s = toParent2(); if (!s) return; AggregateDeclaration *ad = s->isAggregateDeclaration(); FuncDeclaration *fd = s->isFuncDeclaration(); Type *t = NULL; if (fd) { enclosing = fd; AggregateDeclaration *agg = fd->isMember2(); t = agg ? agg->handleType() : Type::tvoidptr; } else if (ad) { if (isClassDeclaration() && ad->isClassDeclaration()) { enclosing = ad; } else if (isStructDeclaration()) { if (TemplateInstance *ti = ad->parent->isTemplateInstance()) { enclosing = ti->enclosing; } } t = ad->handleType(); } if (enclosing) { //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars()); assert(t); if (t->ty == Tstruct) t = Type::tvoidptr; // t should not be a ref type assert(!vthis); vthis = new ThisDeclaration(loc, t); //vthis->storage_class |= STCref; members->push(vthis); } }
Symbol *AggregateDeclaration::toInitializer() { if (!sinit) { Classsym *stag = fake_classsym(Id::ClassInfo); Symbol *s = toSymbolX("__init", SCextern, stag->Stype, "Z"); s->Sfl = FLextern; s->Sflags |= SFLnodebug; StructDeclaration *sd = isStructDeclaration(); if (sd) s->Salignment = sd->alignment; slist_add(s); sinit = s; } return sinit; }
void AggregateDeclaration::semantic3(Scope *sc) { #if IN_LLVM if (!global.inExtraInliningSemantic) availableExternally = false; #endif //printf("AggregateDeclaration::semantic3(%s)\n", toChars()); if (members) { sc = sc->push(this); sc->parent = this; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; s->semantic3(sc); } if (StructDeclaration *sd = isStructDeclaration()) { //if (sd->xeq != NULL) printf("sd = %s xeq @ [%s]\n", sd->toChars(), sd->loc.toChars()); //assert(sd->xeq == NULL); if (sd->xeq == NULL) sd->xeq = sd->buildXopEquals(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: gcinfo!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); e = e->ctfeSemantic(ti->tempdecl->scope); e = e->ctfeInterpret(); getRTInfo = e; } } }
void AggregateDeclaration::semantic2(Scope *sc) { //printf("AggregateDeclaration::semantic2(%s)\n", toChars()); if (scope && members) { error("has forward references"); return; } if (members) { sc = sc->push(this); sc->parent = this; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; //printf("\t[%d] %s\n", i, s->toChars()); s->semantic2(sc); } if (StructDeclaration *sd = isStructDeclaration()) { /* Even if the struct exists in imported module, calculating * xeq and xcmp is necessary in order to generate correct TypeInfo. * However, immediately doing it at the end of StructDeclaration::semantic * might cause forward reference error during instantiation of * template opEquals/opCmp. So should be done at the end of semantic2. */ //if (sd->xeq != NULL) printf("sd = %s xeq @ [%s]\n", sd->toChars(), sd->loc.toChars()); //assert(sd->xeq == NULL); if (sd->xeq == NULL) sd->xeq = sd->buildXopEquals(sc); if (sd->xcmp == NULL) sd->xcmp = sd->buildXopCmp(sc); } sc->pop(); } }
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); } } } }
void AggregateDeclaration::semantic3(Scope *sc) { //printf("AggregateDeclaration::semantic3(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors); if (!members) return; StructDeclaration *sd = isStructDeclaration(); if (!sc) // from runDeferredSemantic3 for TypeInfo generation { assert(sd); sd->semanticTypeInfoMembers(); return; } Scope *sc2 = sc->push(this); sc2->stc &= STCsafe | STCtrusted | STCsystem; sc2->parent = this; if (isUnionDeclaration()) sc2->inunion = 1; sc2->protection = Prot(PROTpublic); sc2->explicitProtection = 0; sc2->structalign = STRUCTALIGN_DEFAULT; sc2->userAttribDecl = NULL; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; s->semantic3(sc2); } sc2->pop(); // don't do it for unused deprecated types // or error types if (!getRTInfo && Type::rtinfo && (!isDeprecated() || global.params.useDeprecated) && (type && type->ty != Terror)) { // we do not want to report deprecated uses of this type during RTInfo // generation, so we disable reporting deprecation temporarily // WARNING: Muting messages during analysis of RTInfo might silently instantiate // templates that use (other) deprecated types. If these template instances // are used in other parts of the program later, they will be reused without // ever producing the deprecation message. The implementation here restricts // muting to the types that RTInfo is currently generated for. bool wasmuted = mutedeprecation; mutedeprecation = true; // 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 *sc3 = ti->tempdecl->scope->startCTFE(); sc3->tinst = sc->tinst; e = e->semantic(sc3); sc3->endCTFE(); e = e->ctfeInterpret(); getRTInfo = e; mutedeprecation = wasmuted; } if (sd) sd->semanticTypeInfoMembers(); }