void AggregateDeclaration::toJsonBuffer(OutBuffer *buf) { //printf("AggregateDeclaration::toJsonBuffer()\n"); buf->writestring("{\n"); JsonProperty(buf, Pname, toChars()); JsonProperty(buf, Pkind, kind()); if (comment) JsonProperty(buf, Pcomment, (const char *)comment); if (loc.linnum) JsonProperty(buf, Pline, loc.linnum); ClassDeclaration *cd = isClassDeclaration(); if (cd) { if (cd->baseClass) { JsonProperty(buf, "base", cd->baseClass->toChars()); } if (cd->interfaces_dim) { JsonString(buf, "interfaces"); buf->writestring(" : [\n"); size_t offset = buf->offset; for (int i = 0; i < cd->interfaces_dim; i++) { BaseClass *b = cd->interfaces[i]; if (offset != buf->offset) { buf->writestring(",\n"); offset = buf->offset; } JsonString(buf, b->base->toChars()); } JsonRemoveComma(buf); buf->writestring("],\n"); } } if (members) { JsonString(buf, Pmembers); buf->writestring(" : [\n"); size_t offset = buf->offset; for (int i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; if (offset != buf->offset) { buf->writestring(",\n"); offset = buf->offset; } s->toJsonBuffer(buf); } JsonRemoveComma(buf); buf->writestring("]\n"); } JsonRemoveComma(buf); buf->writestring("}\n"); }
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); } }
void AggregateDeclaration::toJson(JsonOut *json) { json->objectStart(); jsonProperties(json); ClassDeclaration *cd = isClassDeclaration(); if (cd) { if (cd->baseClass && cd->baseClass->ident != Id::Object) { json->property("base", cd->baseClass->toChars()); } if (cd->interfaces_dim) { json->propertyStart("interfaces"); json->arrayStart(); for (size_t i = 0; i < cd->interfaces_dim; i++) { BaseClass *b = cd->interfaces[i]; json->item(b->base->toChars()); } json->arrayEnd(); } } if (members) { json->propertyStart("members"); json->arrayStart(); for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; s->toJson(json); } json->arrayEnd(); } json->objectEnd(); }
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); // Determine the instance size of base class first. if (ClassDeclaration *cd = isClassDeclaration()) cd->baseClass->size(loc); } if (sizeok != SIZEOKdone && 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) { /* Bugzilla 12799: enum a = ...; is a VarDeclaration and * STCmanifest is already set in parssing stage. So we can * check this before the semantic() call. */ if (v->storage_class & STCmanifest) return 0; 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; } 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; }