Expression *createTypeInfoArray(Scope *sc, Expression *exps[], size_t dim) { #if 1 /* * Pass a reference to the TypeInfo_Tuple corresponding to the types of the * arguments. Source compatibility is maintained by computing _arguments[] * at the start of the called function by offseting into the TypeInfo_Tuple * reference. */ Parameters *args = new Parameters; args->setDim(dim); for (size_t i = 0; i < dim; i++) { Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL); (*args)[i] = arg; } TypeTuple *tup = new TypeTuple(args); Expression *e = tup->getTypeInfo(sc); e = e->optimize(WANTvalue); assert(e->op == TOKsymoff); // should be SymOffExp return e; #else /* Improvements: * 1) create an array literal instead, * as it would eliminate the extra dereference of loading the * static variable. */ ArrayInitializer *ai = new ArrayInitializer(0); VarDeclaration *v; Type *t; Expression *e; OutBuffer buf; Identifier *id; char *name; // Generate identifier for _arguments[] buf.writestring("_arguments_"); for (int i = 0; i < dim; i++) { t = exps[i]->type; t->toDecoBuffer(&buf); } buf.writeByte(0); id = Lexer::idPool((char *)buf.data); Module *m = sc->module; Dsymbol *s = m->symtab->lookup(id); if (s && s->parent == m) { // Use existing one v = s->isVarDeclaration(); assert(v); } else { // Generate new one for (int i = 0; i < dim; i++) { t = exps[i]->type; e = t->getTypeInfo(sc); ai->addInit(new IntegerExp(i), new ExpInitializer(Loc(), e)); } t = Type::typeinfo->type->arrayOf(); ai->type = t; v = new VarDeclaration(0, t, id, ai); m->members->push(v); m->symtabInsert(v); sc = sc->push(); sc->linkage = LINKc; sc->stc = STCstatic | STCcomdat; ai->semantic(sc, t); v->semantic(sc); v->parent = m; sc = sc->pop(); } e = new VarExp(Loc(), v); e = e->semantic(sc); return e; #endif }
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim) { #if 1 /* Get the corresponding TypeInfo_Tuple and * point at its elements[]. */ /* Create the TypeTuple corresponding to the types of args[] */ Parameters *args = new Parameters; args->setDim(dim); for (size_t i = 0; i < dim; i++) { Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL); args->tdata()[i] = arg; } TypeTuple *tup = new TypeTuple(args); Expression *e = tup->getTypeInfo(sc); e = e->optimize(WANTvalue); assert(e->op == TOKsymoff); // should be SymOffExp #if BREAKABI /* * Should just pass a reference to TypeInfo_Tuple instead, * but that would require existing code to be recompiled. * Source compatibility can be maintained by computing _arguments[] * at the start of the called function by offseting into the * TypeInfo_Tuple reference. */ #else // Advance to elements[] member of TypeInfo_Tuple SymOffExp *se = (SymOffExp *)e; se->offset += PTRSIZE + PTRSIZE; // Set type to TypeInfo[]* se->type = Type::typeinfo->type->arrayOf()->pointerTo(); // Indirect to get the _arguments[] value e = new PtrExp(0, se); e->type = se->type->next; #endif return e; #else /* Improvements: * 1) create an array literal instead, * as it would eliminate the extra dereference of loading the * static variable. */ ArrayInitializer *ai = new ArrayInitializer(0); VarDeclaration *v; Type *t; Expression *e; OutBuffer buf; Identifier *id; char *name; // Generate identifier for _arguments[] buf.writestring("_arguments_"); for (int i = 0; i < dim; i++) { t = exps[i]->type; t->toDecoBuffer(&buf); } buf.writeByte(0); id = Lexer::idPool((char *)buf.data); Module *m = sc->module; Dsymbol *s = m->symtab->lookup(id); if (s && s->parent == m) { // Use existing one v = s->isVarDeclaration(); assert(v); } else { // Generate new one for (int i = 0; i < dim; i++) { t = exps[i]->type; e = t->getTypeInfo(sc); ai->addInit(new IntegerExp(i), new ExpInitializer(0, e)); } t = Type::typeinfo->type->arrayOf(); ai->type = t; v = new VarDeclaration(0, t, id, ai); m->members->push(v); m->symtabInsert(v); sc = sc->push(); sc->linkage = LINKc; sc->stc = STCstatic | STCcomdat; ai->semantic(sc, t); v->semantic(sc); v->parent = m; sc = sc->pop(); } e = new VarExp(0, v); e = e->semantic(sc); return e; #endif }