*/
static void initInferAttributes(FuncDeclaration *fd)
{
- assert(fd->type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)fd->type;
+ //printf("initInferAttributes() for %s\n", toPrettyChars());
+ TypeFunction *tf = fd->type->toTypeFunction();
if (tf->purity == PUREimpure) // purity not specified
fd->flags |= FUNCFLAGpurityInprocess;
fld->tok = TOKfunction;
else
assert(0);
- linkage = ((TypeFunction *)treq->nextOf())->linkage;
+ linkage = treq->nextOf()->toTypeFunction()->linkage;
}
else
linkage = sc->linkage;
if (!originalType)
originalType = type->syntaxCopy();
+ if (type->ty != Tfunction)
+ {
+ if (type->ty != Terror)
+ {
+ error("%s must be a function instead of %s", toChars(), type->toChars());
+ type = Type::terror;
+ }
+ errors = true;
+ return;
+ }
if (!type->deco)
{
sc = sc->push();
sc->stc |= storage_class & (STCdisable | STCdeprecated); // forward to function type
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (sc->func)
{
{
// Merge back function attributes into 'originalType'.
// It's used for mangling, ddoc, and json output.
- TypeFunction *tfo = (TypeFunction *)originalType;
- TypeFunction *tfx = (TypeFunction *)type;
+ TypeFunction *tfo = originalType->toTypeFunction();
+ TypeFunction *tfx = type->toTypeFunction();
tfo->mod = tfx->mod;
tfo->isscope = tfx->isscope;
tfo->isscopeinferred = tfx->isscopeinferred;
error("override only applies to class member functions");
// Reflect this->type to f because it could be changed by findVtblIndex
- assert(type->ty == Tfunction);
- f = (TypeFunction *)type;
+ f = type->toTypeFunction();
/* Do not allow template instances to add virtual functions
* to a class.
if (sc && vresult->semanticRun == PASSinit)
{
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (tf->isref)
vresult->storage_class |= STCref;
vresult->type = tret;
return 0;
m->anyf = f;
- TypeFunction *tf = (TypeFunction *)f->type;
+ TypeFunction *tf = f->type->toTypeFunction();
//printf("tf = %s\n", tf->toChars());
MATCH match;
else // no match
{
hasOverloads = true;
- TypeFunction *tf = (TypeFunction *)this->type;
+ TypeFunction *tf = this->type->toTypeFunction();
assert(tthis);
assert(!MODimplicitConv(tthis->mod, tf->mod)); // modifier mismatch
{
* as g() is.
*/
- TypeFunction *tf = (TypeFunction *)type;
- TypeFunction *tg = (TypeFunction *)g->type;
+ TypeFunction *tf = type->toTypeFunction();
+ TypeFunction *tg = g->type->toTypeFunction();
size_t nfparams = Parameter::dim(tf->parameters);
/* If both functions have a 'this' pointer, and the mods are not
assert(fd);
bool hasOverloads = fd->overnext != NULL;
- TypeFunction *tf = (TypeFunction *)fd->type;
+ TypeFunction *tf = fd->type->toTypeFunction();
if (tthis && !MODimplicitConv(tthis->mod, tf->mod)) // modifier mismatch
{
OutBuffer thisBuf, funcBuf;
}
else if (m.nextf)
{
- TypeFunction *tf1 = (TypeFunction *)m.lastf->type;
- TypeFunction *tf2 = (TypeFunction *)m.nextf->type;
+ TypeFunction *tf1 = m.lastf->type->toTypeFunction();
+ TypeFunction *tf2 = m.nextf->type->toTypeFunction();
const char *lastprms = parametersTypeToChars(tf1->parameters, tf1->varargs);
const char *nextprms = parametersTypeToChars(tf2->parameters, tf2->varargs);
::error(loc, "%s.%s called with argument types %s matches both:\n"
const char *FuncDeclaration::toFullSignature()
{
OutBuffer buf;
- functionToBufferWithIdent((TypeFunction *)type, &buf, toChars());
+ functionToBufferWithIdent(type->toTypeFunction(), &buf, toChars());
return buf.extractString();
}
PURE FuncDeclaration::isPure()
{
//printf("FuncDeclaration::isPure() '%s'\n", toChars());
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (flags & FUNCFLAGpurityInprocess)
setImpure();
if (tf->purity == PUREfwdref)
bool FuncDeclaration::isSafe()
{
- assert(type->ty == Tfunction);
if (flags & FUNCFLAGsafetyInprocess)
setUnsafe();
- return ((TypeFunction *)type)->trust == TRUSTsafe;
+ return type->toTypeFunction()->trust == TRUSTsafe;
}
bool FuncDeclaration::isSafeBypassingInference()
bool FuncDeclaration::isTrusted()
{
- assert(type->ty == Tfunction);
if (flags & FUNCFLAGsafetyInprocess)
setUnsafe();
- return ((TypeFunction *)type)->trust == TRUSTtrusted;
+ return type->toTypeFunction()->trust == TRUSTtrusted;
}
/**************************************
if (flags & FUNCFLAGsafetyInprocess)
{
flags &= ~FUNCFLAGsafetyInprocess;
- ((TypeFunction *)type)->trust = TRUSTsystem;
+ type->toTypeFunction()->trust = TRUSTsystem;
if (fes)
fes->func->setUnsafe();
}
bool FuncDeclaration::isNogc()
{
- assert(type->ty == Tfunction);
if (flags & FUNCFLAGnogcInprocess)
setGC();
- return ((TypeFunction *)type)->isnogc;
+ return type->toTypeFunction()->isnogc;
}
bool FuncDeclaration::isNogcBypassingInference()
if (flags & FUNCFLAGnogcInprocess)
{
flags &= ~FUNCFLAGnogcInprocess;
- ((TypeFunction *)type)->isnogc = false;
+ type->toTypeFunction()->isnogc = false;
if (fes)
fes->func->setGC();
}
bool FuncDeclaration::isolateReturn()
{
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
assert(tf->next);
Type *treti = tf->next;
if (!isPureBypassingInference() || isNested())
return false;
- assert(type->ty == Tfunction);
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
//printf("parametersIntersect(%s) t = %s\n", tf->toChars(), t->toChars());
*/
void FuncDeclaration::checkDmain()
{
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
const size_t nparams = Parameter::dim(tf->parameters);
bool argerr = false;
if (nparams == 1)
if (type)
{
- assert(type->ty == Tfunction);
- TypeFunction *fdtype = (TypeFunction *)type;
+ TypeFunction *fdtype = type->toTypeFunction();
fparameters = fdtype->parameters;
fvarargs = fdtype->varargs;
}
// This is required so the code generator does not try to cast the
// modified returns back to the original type.
if (inferRetType && type->nextOf() != tret)
- ((TypeFunction *)type)->next = tret;
+ type->toTypeFunction()->next = tret;
}
const char *FuncLiteralDeclaration::kind() const
if (errors)
return;
- TypeFunction *tf = (TypeFunction *)type;
- assert(tf && tf->ty == Tfunction);
+ TypeFunction *tf = type->toTypeFunction();
/* See if it's the default constructor
* But, template constructor should not become a default constructor.
type = new TypeFunction(parameters, tret, varargs, LINKd, storage_class);
type = type->semantic(loc, sc);
- assert(type->ty == Tfunction);
// Check that there is at least one argument of type size_t
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (Parameter::dim(tf->parameters) < 1)
{
error("at least one argument of type size_t expected");
type = new TypeFunction(parameters, Type::tvoid, 0, LINKd, storage_class);
type = type->semantic(loc, sc);
- assert(type->ty == Tfunction);
// Check that there is only one argument of type void*
- TypeFunction *tf = (TypeFunction *)type;
+ TypeFunction *tf = type->toTypeFunction();
if (Parameter::dim(tf->parameters) != 1)
{
error("one argument of type void* expected");
return NULL;
}
+TypeFunction *Type::toTypeFunction()
+{
+ if (ty != Tfunction)
+ assert(0);
+ return (TypeFunction *)this;
+}
/***************************************
* Resolve 'this' type to either type, symbol, or expression.
Parameters *fparams = new Parameters();
fparams->push(new Parameter(STCin, this, NULL, NULL));
fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
- TypeFunction *tf = (TypeFunction *)fd_aaLen->type;
+ TypeFunction *tf = fd_aaLen->type->toTypeFunction();
tf->purity = PUREconst;
tf->isnothrow = true;
tf->isnogc = false;
}
Expression *ev = new VarExp(e->loc, fd_aaLen, false);
e = new CallExp(e->loc, ev, e);
- e->type = ((TypeFunction *)fd_aaLen->type)->next;
+ e->type = fd_aaLen->type->toTypeFunction()->next;
}
else
e = Type::dotExp(sc, e, ident, flag);
* This can produce redundant copies if inferring return type,
* as semantic() will get called again on this.
*/
- TypeFunction *tf = (TypeFunction *)copy();
+ TypeFunction *tf = copy()->toTypeFunction();
if (parameters)
{
tf->parameters = parameters->copy();
Type *TypeFunction::addStorageClass(StorageClass stc)
{
//printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
- TypeFunction *t = (TypeFunction *)Type::addStorageClass(stc);
+ TypeFunction *t = Type::addStorageClass(stc)->toTypeFunction();
if ((stc & STCpure && !t->purity) ||
(stc & STCnothrow && !t->isnothrow) ||
(stc & STCnogc && !t->isnogc) ||
if (tel->ty == Tdelegate)
{
TypeDelegate *td = (TypeDelegate *)tel;
- TypeFunction *tf = (TypeFunction *)td->next;
+ TypeFunction *tf = td->next->toTypeFunction();
if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
{