Expression *DeclarationExp::interpret(InterState *istate) { #if LOG printf("DeclarationExp::interpret() %s\n", toChars()); #endif Expression *e; VarDeclaration *v = declaration->isVarDeclaration(); if (v) { Dsymbol *s = v->toAlias(); if (s == v && !v->isStatic() && v->init) { ExpInitializer *ie = v->init->isExpInitializer(); if (ie) e = ie->exp->interpret(istate); else if (v->init->isVoidInitializer()) e = NULL; } #if V2 else if (s == v && (v->isConst() || v->isInvariant()) && v->init) #else else if (s == v && v->isConst() && v->init) #endif { e = v->init->toExpression(); if (!e) e = EXP_CANT_INTERPRET; else if (!e->type) e->type = v->type; } } else if (declaration->isAttribDeclaration() ||
Expression *DeclarationExp::doInline(InlineDoState *ids) { DeclarationExp *de = (DeclarationExp *)copy(); VarDeclaration *vd; //printf("DeclarationExp::doInline(%s)\n", toChars()); vd = declaration->isVarDeclaration(); if (vd) { #if 0 // Need to figure this out before inlining can work for tuples TupleDeclaration *td = vd->toAlias()->isTupleDeclaration(); if (td) { for (size_t i = 0; i < td->objects->dim; i++) { DsymbolExp *se = (DsymbolExp *)td->objects->data[i]; assert(se->op == TOKdsymbol); se->s; } return st->objects->dim; } #endif if (vd->isStatic() || vd->isConst()) ; else { VarDeclaration *vto; vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); *vto = *vd; vto->parent = ids->parent; #if IN_DMD vto->csym = NULL; vto->isym = NULL; #endif ids->from.push(vd); ids->to.push(vto); if (vd->init) { if (vd->init->isVoidInitializer()) { vto->init = new VoidInitializer(vd->init->loc); } else { ExpInitializer *ie = vd->init->isExpInitializer(); assert(ie); vto->init = new ExpInitializer(ie->loc, ie->exp->doInline(ids)); } } de->declaration = (Dsymbol *) (void *)vto; } } /* This needs work, like DeclarationExp::toElem(), if we are * to handle TemplateMixin's. For now, we just don't inline them. */ return de; }
Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) { Expression *e = EXP_CANT_INTERPRET; VarDeclaration *v = d->isVarDeclaration(); SymbolDeclaration *s = d->isSymbolDeclaration(); if (v) { #if V2 if ((v->isConst() || v->isInvariant()) && v->init && !v->value) #else if (v->isConst() && v->init) #endif { e = v->init->toExpression(); if (e && !e->type) e->type = v->type; } else { e = v->value; if (!e) {} // error(loc, "variable %s is used before initialization", v->toChars()); else if (e != EXP_CANT_INTERPRET) e = e->interpret(istate); } if (!e) e = EXP_CANT_INTERPRET; } else if (s) { /* if (s->dsym->toInitializer() == s->sym) { Expressions *exps = new Expressions(); e = new StructLiteralExp(0, s->dsym, exps); e = e->semantic(NULL); } */ } return e; }
Expression *fromConstInitializer(Expression *e1) { //printf("fromConstInitializer(%s)\n", e1->toChars()); if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; VarDeclaration *v = ve->var->isVarDeclaration(); if (v && !v->originalType && v->scope) // semantic() not yet run v->semantic (v->scope); if (v && v->isConst() && v->init) { Expression *ei = v->init->toExpression(); if (ei && ei->type) e1 = ei; } } return e1; }
void visit(VarExp *e) override { IF_LOG Logger::print("VarExp::toConstElem: %s @ %s\n", e->toChars(), e->type->toChars()); LOG_SCOPE; if (SymbolDeclaration *sdecl = e->var->isSymbolDeclaration()) { // this seems to be the static initialiser for structs Type *sdecltype = sdecl->type->toBasetype(); IF_LOG Logger::print("Sym: type=%s\n", sdecltype->toChars()); assert(sdecltype->ty == Tstruct); TypeStruct *ts = static_cast<TypeStruct *>(sdecltype); DtoResolveStruct(ts->sym); result = getIrAggr(ts->sym)->getDefaultInit(); return; } if (TypeInfoDeclaration *ti = e->var->isTypeInfoDeclaration()) { LLType *vartype = DtoType(e->type); result = DtoTypeInfoOf(ti->tinfo, false); if (result->getType() != getPtrToType(vartype)) { result = llvm::ConstantExpr::getBitCast(result, vartype); } return; } VarDeclaration *vd = e->var->isVarDeclaration(); if (vd && vd->isConst() && vd->_init) { if (vd->inuse) { e->error("recursive reference %s", e->toChars()); result = llvm::UndefValue::get(DtoType(e->type)); } else { vd->inuse++; // return the initializer result = DtoConstInitializer(e->loc, e->type, vd->_init); vd->inuse--; } } // fail else { e->error("non-constant expression %s", e->toChars()); result = llvm::UndefValue::get(DtoType(e->type)); } }