Merge pull request #484 from AlexeyProkhin/mtypeDiff2

Reduce mtype diff
This commit is contained in:
AlexeyProkhin
2013-10-05 09:16:56 -07:00
27 changed files with 251 additions and 374 deletions

View File

@@ -915,7 +915,7 @@ struct FuncDeclaration : Declaration
virtual FuncDeclaration *toAliasFunc() { return this; }
#if IN_LLVM
// LDC stuff
IrFuncTy irFty;
/// Codegen traversal
void codegen(Ir* ir);

View File

@@ -105,25 +105,6 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
allowInlining = false;
neverInline = false;
availableExternally = true; // assume this unless proven otherwise
// function types in ldc don't merge if the context parameter differs
// so we actually don't care about the function declaration, but only
// what kind of context parameter it has.
// however, this constructor is usually called from the parser, which
// unfortunately doesn't provide the information needed to get to the
// aggregate type. So we have to stick with the FuncDeclaration and
// just be sure we don't actually rely on the symbol it points to,
// but rather just the type of its context parameter.
// this means some function might have a function type pointing to
// another function declaration
if (type)
{
assert(type->ty == Tfunction && "invalid function type");
TypeFunction* tf = (TypeFunction*)type;
if (tf->funcdecl == NULL)
tf->funcdecl = this;
}
#endif
}

View File

@@ -87,11 +87,7 @@ L1:
tfn.isref = fd->storage_class & STCauto ? false : tfo->isref;
tfn.trust = tfo->trust;
tfn.next = NULL; // do not mangle return type
#if IN_LLVM
tfn.toDecoBuffer(&buf, 0, true);
#else
tfn.toDecoBuffer(&buf, 0);
#endif
}
else if (sthis->type->deco)
buf.writestring(sthis->type->deco);

View File

@@ -135,10 +135,6 @@ unsigned char Type::mangleChar[TMAX];
unsigned short Type::sizeTy[TMAX];
StringTable Type::stringtable;
#if IN_LLVM
StringTable Type::deco_stringtable;
#endif
Type::Type(TY ty)
{
@@ -208,9 +204,6 @@ void Type::init()
#endif
{
stringtable._init(1543);
#if IN_LLVM
deco_stringtable._init();
#endif
Lexer::initKeywords();
for (size_t i = 0; i < TMAX; i++)
@@ -1537,7 +1530,7 @@ char *MODtoChars(unsigned char mod)
* flag 0x100 do not do const/invariant
*/
void Type::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) // Possible conflict from merge
void Type::toDecoBuffer(OutBuffer *buf, int flag)
{
if (flag != mod && flag != 0x100)
{
@@ -1651,7 +1644,7 @@ Type *Type::merge()
//if (next)
//next = next->merge();
toDecoBuffer(&buf, 0, false);
toDecoBuffer(&buf, 0);
sv = stringtable.update((char *)buf.data, buf.offset);
if (sv->ptrvalue)
{ t = (Type *) sv->ptrvalue;
@@ -1665,28 +1658,7 @@ Type *Type::merge()
else
{
sv->ptrvalue = this;
#if IN_LLVM
// we still need deco strings to be unique
// or Type::equals fails, which breaks a bunch of stuff,
// like covariant member function overloads.
// TODO: Check if and why this is still needed.
OutBuffer mangle;
toDecoBuffer(&mangle, 0, true);
StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset);
if (sv2->ptrvalue)
{ Type* t2 = (Type *) sv2->ptrvalue;
assert(t2->deco);
deco = t2->deco;
}
else
{
sv2->ptrvalue = this;
deco = (char *)sv2->toDchars();
}
#else
deco = (char *)sv->toDchars();
#endif
//printf("new value, deco = '%s' %p\n", t->deco, t->deco);
}
}
@@ -1705,7 +1677,7 @@ Type *Type::merge2()
if (!t->deco)
return t->merge();
StringValue *sv = deco_stringtable.lookup((char *)t->deco, strlen(t->deco));
StringValue *sv = stringtable.lookup((char *)t->deco, strlen(t->deco));
if (sv && sv->ptrvalue)
{ t = (Type *) sv->ptrvalue;
assert(t->deco);
@@ -2243,7 +2215,7 @@ Identifier *Type::getTypeInfoIdent(int internal)
buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]);
}
else
toDecoBuffer(&buf, 0, true);
toDecoBuffer(&buf, 0);
size_t len = buf.offset;
buf.writeByte(0);
@@ -2398,12 +2370,12 @@ TypeNext::TypeNext(TY ty, Type *next)
this->next = next;
}
void TypeNext::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeNext::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
assert(next != this);
//printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty);
next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle);
next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
}
void TypeNext::checkDeprecated(Loc loc, Scope *sc)
@@ -3515,14 +3487,14 @@ void TypeVector::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
buf->writestring(")");
}
void TypeVector::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeVector::toDecoBuffer(OutBuffer *buf, int flag)
{
if (flag != mod && flag != 0x100)
{
MODtoDecoBuffer(buf, mod);
}
buf->writestring("Nh");
basetype->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle);
basetype->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
}
d_uns64 TypeVector::size(Loc loc)
@@ -4083,9 +4055,9 @@ Lerror:
return Type::terror;
}
void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
if (dim)
buf->printf("%llu", dim->toInteger());
if (next)
@@ -4094,7 +4066,7 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
* level, since for T[4][3], any const should apply to the T,
* not the [4].
*/
next->toDecoBuffer(buf, (flag & 0x100) ? flag : mod, mangle);
next->toDecoBuffer(buf, (flag & 0x100) ? flag : mod);
}
void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
@@ -4387,11 +4359,11 @@ void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol
}
}
void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
if (next)
next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle);
next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
}
void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
@@ -4753,11 +4725,11 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int
return e;
}
void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag, mangle);
index->toDecoBuffer(buf, 0, mangle);
next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle);
Type::toDecoBuffer(buf, flag);
index->toDecoBuffer(buf, 0);
next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
}
void TypeAArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
@@ -5144,9 +5116,6 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, e
this->iswild = false;
this->fargs = NULL;
#if IN_LLVM
this->funcdecl = NULL;
#endif
if (stc & STCpure)
this->purity = PUREfwdref;
if (stc & STCnothrow)
@@ -5374,7 +5343,7 @@ Lnotcovariant:
return 2;
}
void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag)
{ unsigned char mc;
//printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars());
@@ -5422,53 +5391,12 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
}
}
#if IN_LLVM
// if we're not producing a mangle string, add the this
// type to prevent merging different member function
if (!mangle && funcdecl)
{
if (funcdecl->needThis())
{
AggregateDeclaration* ad = funcdecl->isMember2();
buf->writeByte('M');
ad->type->toDecoBuffer(buf, 0, false);
}
if (FuncLiteralDeclaration *literal = funcdecl->isFuncLiteralDeclaration()) {
// Never merge types of function literals of different kind
if (literal->tok == TOKdelegate) {
buf->writeByte('D');
} else if (literal->tok == TOKfunction) {
buf->writeByte('F');
} else if (literal->tok == TOKreserved) {
static int counter = 0;
buf->writeByte('L');
// And never merge types of lambdas, because we don't know whether
// they need a nested context argument or not.
buf->printf("%i", counter++);
}
}
/* BUG This causes problems with delegate types
On the other hand, the llvm type for nested functions *is* different
so not doing anything here may be lead to bugs!
A sane solution would be DtoType(Dsymbol)...
if (funcdecl->isNested())
{
buf->writeByte('M');
if (funcdecl->toParent2() && funcdecl->toParent2()->isFuncDeclaration())
{
FuncDeclaration* fd = funcdecl->toParent2()->isFuncDeclaration();
fd->type->toDecoBuffer(buf, 0, false);
}
}*/
}
#endif
// Write argument types
Parameter::argsToDecoBuffer(buf, parameters, mangle);
Parameter::argsToDecoBuffer(buf, parameters);
//if (buf->data[buf->offset - 1] == '@') halt();
buf->writeByte('Z' - varargs); // mark end of arg list
if(next != NULL)
next->toDecoBuffer(buf, 0, mangle);
next->toDecoBuffer(buf, 0);
inuse--;
}
@@ -6345,10 +6273,6 @@ Type *TypeFunction::addStorageClass(StorageClass stc)
if (stc & STCsafe)
tf->trust = TRUSTsafe;
#if IN_LLVM
tf->funcdecl = t->funcdecl;
#endif
tf->deco = tf->merge()->deco;
t = tf;
}
@@ -6780,9 +6704,9 @@ Type *TypeIdentifier::syntaxCopy()
return t;
}
void TypeIdentifier::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeIdentifier::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
const char *name = ident->toChars();
size_t len = strlen(name);
buf->printf("%u%s", (unsigned)len, name);
@@ -7487,10 +7411,10 @@ Type *TypeEnum::toBasetype()
return sym->memtype->toBasetype();
}
void TypeEnum::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeEnum::toDecoBuffer(OutBuffer *buf, int flag)
{
const char *name = sym->mangle();
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
buf->printf("%s", name);
}
@@ -7730,9 +7654,9 @@ Dsymbol *TypeTypedef::toDsymbol(Scope *sc)
return sym;
}
void TypeTypedef::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeTypedef::toDecoBuffer(OutBuffer *buf, int flag)
{
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
const char *name = sym->mangle();
buf->printf("%s", name);
}
@@ -8031,11 +7955,11 @@ Dsymbol *TypeStruct::toDsymbol(Scope *sc)
return sym;
}
void TypeStruct::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeStruct::toDecoBuffer(OutBuffer *buf, int flag)
{
const char *name = sym->mangle();
//printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name);
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
buf->printf("%s", name);
}
@@ -8565,11 +8489,11 @@ Dsymbol *TypeClass::toDsymbol(Scope *sc)
return sym;
}
void TypeClass::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeClass::toDecoBuffer(OutBuffer *buf, int flag)
{
const char *name = sym->mangle();
//printf("TypeClass::toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name);
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
buf->printf("%s", name);
}
@@ -9230,12 +9154,12 @@ void TypeTuple::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
Parameter::argsToCBuffer(buf, hgs, arguments, 0);
}
void TypeTuple::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
void TypeTuple::toDecoBuffer(OutBuffer *buf, int flag)
{
//printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars());
Type::toDecoBuffer(buf, flag, mangle);
Type::toDecoBuffer(buf, flag);
OutBuffer buf2;
Parameter::argsToDecoBuffer(&buf2, arguments, mangle);
Parameter::argsToDecoBuffer(&buf2, arguments);
int len = (int)buf2.offset;
buf->printf("%d%.*s", len, len, (char *)buf2.extractData());
}
@@ -9465,18 +9389,10 @@ int TypeNull::checkBoolean()
return TRUE;
}
#if IN_LLVM
void TypeNull::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
#else
void TypeNull::toDecoBuffer(OutBuffer *buf, int flag)
#endif
{
//tvoidptr->toDecoBuffer(buf, flag);
#if IN_LLVM
Type::toDecoBuffer(buf, flag, mangle);
#else
Type::toDecoBuffer(buf, flag);
#endif
}
void TypeNull::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
@@ -9602,31 +9518,15 @@ void Parameter::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *argu
static int argsToDecoBufferDg(void *ctx, size_t n, Parameter *arg)
{
#if IN_LLVM
arg->toDecoBuffer((OutBuffer *)ctx, false);
#else
arg->toDecoBuffer((OutBuffer *)ctx);
#endif
return 0;
}
#if IN_LLVM
static int argsToDecoBufferDg2(void *ctx, size_t n, Parameter *arg)
{
arg->toDecoBuffer((OutBuffer *)ctx, true);
return 0;
}
#endif
void Parameter::argsToDecoBuffer(OutBuffer *buf, Parameters *arguments, bool mangle)
void Parameter::argsToDecoBuffer(OutBuffer *buf, Parameters *arguments)
{
//printf("Parameter::argsToDecoBuffer()\n");
// Write argument types
#if IN_LLVM
foreach(arguments, mangle ? &argsToDecoBufferDg2 : &argsToDecoBufferDg, buf);
#else
foreach(arguments, &argsToDecoBufferDg, buf);
#endif
}
/****************************************
@@ -9676,7 +9576,7 @@ Type *Parameter::isLazyArray()
return NULL;
}
void Parameter::toDecoBuffer(OutBuffer *buf, bool mangle)
void Parameter::toDecoBuffer(OutBuffer *buf)
{
if (storageClass & STCscope)
buf->writeByte('M');
@@ -9707,7 +9607,7 @@ void Parameter::toDecoBuffer(OutBuffer *buf, bool mangle)
type->toDecoBuffer(buf, mod);
#else
//type->toHeadMutable()->toDecoBuffer(buf, 0);
type->toDecoBuffer(buf, 0, mangle);
type->toDecoBuffer(buf, 0);
#endif
}

View File

@@ -229,9 +229,6 @@ struct Type : Object
static unsigned char mangleChar[TMAX];
static unsigned short sizeTy[TMAX];
static StringTable stringtable;
#if IN_LLVM
static StringTable deco_stringtable;
#endif
// These tables are for implicit conversion of binary ops;
// the indices are the type of operand one, followed by operand two.
@@ -263,7 +260,7 @@ struct Type : Object
virtual Type *semantic(Loc loc, Scope *sc);
Type *trySemantic(Loc loc, Scope *sc);
// append the mangleof or a string uniquely identifying this type to buf
virtual void toDecoBuffer(OutBuffer *buf, int flag = 0, bool mangle=false);
virtual void toDecoBuffer(OutBuffer *buf, int flag = 0);
Type *merge();
Type *merge2();
virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
@@ -400,7 +397,7 @@ struct TypeNext : Type
Type *next;
TypeNext(TY ty, Type *next);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void checkDeprecated(Loc loc, Scope *sc);
Type *reliesOnTident(TemplateParameters *tparams = NULL);
int hasWild();
@@ -468,11 +465,7 @@ struct TypeVector : Type
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
char *toChars();
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
#if IN_LLVM
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
#else
void toDecoBuffer(OutBuffer *buf, int flag);
#endif
void toJson(JsonOut *json);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL);
#if CPP_MANGLE
@@ -516,7 +509,7 @@ struct TypeSArray : TypeArray
unsigned alignsize();
Type *semantic(Loc loc, Scope *sc);
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -559,7 +552,7 @@ struct TypeDArray : TypeArray
unsigned alignsize();
Type *semantic(Loc loc, Scope *sc);
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -597,7 +590,7 @@ struct TypeAArray : TypeArray
Type *semantic(Loc loc, Scope *sc);
StructDeclaration *getImpl();
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -714,7 +707,7 @@ struct TypeFunction : TypeNext
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
void purityLevel();
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
void toCBufferWithAttributes(OutBuffer *buf, Identifier *ident, HdrGenState* hgs, TypeFunction *attrs, TemplateDeclaration *td);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
@@ -744,10 +737,7 @@ struct TypeFunction : TypeNext
Expression *defaultInit(Loc loc);
#if IN_LLVM
// LDC
IrFuncTy fty;
FuncDeclaration* funcdecl;
IrFuncTy irFty;
#endif
};
@@ -778,6 +768,10 @@ struct TypeDelegate : TypeNext
#if IN_DMD
type *toCtype();
#endif
#if IN_LLVM
IrFuncTy irFty;
#endif
};
struct TypeQualified : Type
@@ -806,7 +800,7 @@ struct TypeIdentifier : TypeQualified
const char *kind();
Type *syntaxCopy();
//char *toChars();
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
@@ -889,7 +883,7 @@ struct TypeStruct : Type
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
Dsymbol *toDsymbol(Scope *sc);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -939,7 +933,7 @@ struct TypeEnum : Type
char *toChars();
Type *semantic(Loc loc, Scope *sc);
Dsymbol *toDsymbol(Scope *sc);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -985,7 +979,7 @@ struct TypeTypedef : Type
char *toChars();
Type *semantic(Loc loc, Scope *sc);
Dsymbol *toDsymbol(Scope *sc);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -1039,7 +1033,7 @@ struct TypeClass : Type
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
Dsymbol *toDsymbol(Scope *sc);
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toJson(JsonOut *json);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
@@ -1084,11 +1078,7 @@ struct TypeTuple : Type
int equals(Object *o);
Type *reliesOnTident(TemplateParameters *tparams = NULL);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
#if IN_LLVM
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
#else
void toDecoBuffer(OutBuffer *buf, int flag);
#endif
void toJson(JsonOut *json);
Expression *getProperty(Loc loc, Identifier *ident, int flag);
Expression *defaultInit(Loc loc);
@@ -1115,7 +1105,7 @@ struct TypeNull : Type
const char *kind();
Type *syntaxCopy();
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toDecoBuffer(OutBuffer *buf, int flag);
MATCH implicitConvTo(Type *to);
int checkBoolean();
@@ -1141,7 +1131,7 @@ struct Parameter : Object
Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
Parameter *syntaxCopy();
Type *isLazyArray();
void toDecoBuffer(OutBuffer *buf, bool mangle);
void toDecoBuffer(OutBuffer *buf);
int dyncast() { return DYNCAST_PARAMETER; } // kludge for template.isType()
static Parameters *arraySyntaxCopy(Parameters *args);
static char *argsTypesToChars(Parameters *args, int varargs);
@@ -1149,7 +1139,7 @@ struct Parameter : Object
static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs);
#endif
static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *arguments, int varargs);
static void argsToDecoBuffer(OutBuffer *buf, Parameters *arguments, bool mangle);
static void argsToDecoBuffer(OutBuffer *buf, Parameters *arguments);
static int isTPL(Parameters *arguments);
static size_t dim(Parameters *arguments);
static Parameter *getNth(Parameters *arguments, size_t nth, size_t *pn = NULL);

View File

@@ -1,6 +1,6 @@
//===-- abi-ppc64.cpp -----------------------------------------------------===//
//
// LDC the LLVM D compiler
// LDC ? the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
@@ -63,7 +63,7 @@ struct PPC64TargetABI : TargetABI {
{
}
void rewriteFunctionType(TypeFunction* tf)
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
{
}
};

View File

@@ -97,7 +97,7 @@ struct Win64TargetABI : TargetABI
bool passByVal(Type* t);
void rewriteFunctionType(TypeFunction* tf);
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty);
};
@@ -153,9 +153,8 @@ bool Win64TargetABI::passByVal(Type* t)
return (t->ty == Tstruct || t->ty == Tsarray) && !canRewriteAsInt(t);
}
void Win64TargetABI::rewriteFunctionType(TypeFunction* tf)
void Win64TargetABI::rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
{
IrFuncTy& fty = tf->fty;
Type* rt = fty.ret->type->toBasetype();
// RETURN VALUE

View File

@@ -376,7 +376,7 @@ struct X86_64TargetABI : TargetABI {
bool passByVal(Type* t);
void rewriteFunctionType(TypeFunction* tf);
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty);
void doneWithFunctionType() {
funcTypeStack.pop_back();
@@ -539,8 +539,7 @@ void X86_64TargetABI::fixup(IrFuncTyArg& arg) {
}
}
void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
IrFuncTy& fty = tf->fty;
void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty) {
Type* rt = fty.ret->type->toBasetype();
if (tf->linkage == LINKd) {

View File

@@ -92,9 +92,8 @@ struct X86TargetABI : TargetABI
return t->toBasetype()->ty == Tstruct || t->toBasetype()->ty == Tsarray;
}
void rewriteFunctionType(TypeFunction* tf)
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
{
IrFuncTy& fty = tf->fty;
Type* rt = fty.ret->type->toBasetype();
// extern(D)

View File

@@ -74,7 +74,7 @@ struct UnknownTargetABI : TargetABI
return t->toBasetype()->ty == Tstruct;
}
void rewriteFunctionType(TypeFunction* t)
void rewriteFunctionType(TypeFunction* t, IrFuncTy &fty)
{
// why?
}
@@ -135,12 +135,10 @@ struct IntrinsicABI : TargetABI
}
}
void rewriteFunctionType(TypeFunction* tf)
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
{
assert(tf->linkage == LINKintrinsic);
IrFuncTy& fty = tf->fty;
if (!fty.arg_sret) {
Type* rt = fty.ret->type->toBasetype();
if (rt->ty == Tstruct) {

View File

@@ -27,6 +27,7 @@
struct Type;
struct TypeFunction;
struct IrFuncTy;
struct IrFuncTyArg;
class DValue;
@@ -88,7 +89,7 @@ struct TargetABI
virtual bool passByVal(Type* t) = 0;
/// Called to give ABI the chance to rewrite the types
virtual void rewriteFunctionType(TypeFunction* t) = 0;
virtual void rewriteFunctionType(TypeFunction* t, IrFuncTy &fty) = 0;
/// Called if resolution of new function type is done
virtual void doneWithFunctionType() {}

View File

@@ -538,7 +538,7 @@ LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl, char* n
Logger::cout() << "funcval: " << *funcval << '\n';
// cast to final funcptr type
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
funcval = DtoBitCast(funcval, getPtrToType(DtoFunctionType(fdecl)));
// postpone naming until after casting to get the name in call instructions
funcval->setName(name);

View File

@@ -101,6 +101,10 @@ LLValue* DSliceValue::getRVal()
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
DFuncValue::DFuncValue(Type *t, FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt)
: DValue(t), func(fd), val(v), vthis(vt)
{}
DFuncValue::DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt)
: DValue(fd->type), func(fd), val(v), vthis(vt)
{}

View File

@@ -152,6 +152,7 @@ public:
class DFuncValue : public DValue
{
public:
DFuncValue(Type *t, FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0);
DFuncValue(FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0);
virtual llvm::Value* getRVal();

View File

@@ -40,7 +40,7 @@
using namespace llvm::Attribute;
#endif
llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype, Type* nesttype, bool isMain, bool isCtor)
{
if (Logger::enabled())
Logger::println("DtoFunctionType(%s)", type->toChars());
@@ -54,17 +54,17 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
// Tell the ABI we're resolving a new function type
abi->newFunctionType(f);
// Do not modify f->fty yet; this function may be called recursively if any
// Do not modify irFty yet; this function may be called recursively if any
// of the argument types refer to this type.
IrFuncTy fty;
IrFuncTy newIrFty;
// llvm idx counter
size_t lidx = 0;
// main needs a little special handling
if (ismain)
if (isMain)
{
fty.ret = new IrFuncTyArg(Type::tint32, false);
newIrFty.ret = new IrFuncTyArg(Type::tint32, false);
}
// sane return value
else
@@ -81,11 +81,11 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
{
#if LDC_LLVM_VER >= 302
#if LDC_LLVM_VER >= 303
fty.arg_sret = new IrFuncTyArg(rt, true,
newIrFty.arg_sret = new IrFuncTyArg(rt, true,
llvm::AttrBuilder().addAttribute(llvm::Attribute::StructRet)
.addAttribute(llvm::Attribute::NoAlias)
#else
fty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attributes::get(gIR->context(),
newIrFty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attributes::get(gIR->context(),
llvm::AttrBuilder().addAttribute(llvm::Attributes::StructRet)
.addAttribute(llvm::Attributes::NoAlias)
#endif
@@ -94,7 +94,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
#endif
);
#else
fty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias
newIrFty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias
);
#endif
rt = Type::tvoid;
@@ -121,7 +121,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
#elif LDC_LLVM_VER == 302
llvm::Attributes a = llvm::Attributes::get(gIR->context(), attrBuilder);
#endif
fty.ret = new IrFuncTyArg(rt, f->isref, a);
newIrFty.ret = new IrFuncTyArg(rt, f->isref, a);
}
lidx++;
@@ -130,10 +130,10 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
{
#if LDC_LLVM_VER >= 303
llvm::AttrBuilder attrBuilder;
if (f->funcdecl && f->funcdecl->isCtorDeclaration())
if (isCtor)
attrBuilder.addAttribute(llvm::Attribute::Returned);
#endif
fty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct
newIrFty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct
#if LDC_LLVM_VER >= 303
, attrBuilder
#endif
@@ -144,7 +144,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
// and nested functions
else if (nesttype)
{
fty.arg_nest = new IrFuncTyArg(nesttype, false);
newIrFty.arg_nest = new IrFuncTyArg(nesttype, false);
lidx++;
}
@@ -158,19 +158,19 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
if (f->varargs == 1)
{
// _arguments
fty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
newIrFty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
lidx++;
// _argptr
#if LDC_LLVM_VER >= 303
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
newIrFty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
llvm::AttrBuilder().addAttribute(llvm::Attribute::NoAlias)
.addAttribute(llvm::Attribute::NoCapture));
#elif LDC_LLVM_VER == 302
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
newIrFty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
llvm::Attributes::get(gIR->context(), llvm::AttrBuilder().addAttribute(llvm::Attributes::NoAlias)
.addAttribute(llvm::Attributes::NoCapture)));
#else
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false, NoAlias | NoCapture);
newIrFty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false, NoAlias | NoCapture);
#endif
lidx++;
}
@@ -179,17 +179,17 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
{
// Default to C-style varargs for non-extern(D) variadic functions.
// This seems to be what DMD does.
fty.c_vararg = true;
newIrFty.c_vararg = true;
}
}
// if this _Dmain() doesn't have an argument, we force it to have one
int nargs = Parameter::dim(f->parameters);
if (ismain && nargs == 0)
if (isMain && nargs == 0)
{
Type* mainargs = Type::tchar->arrayOf()->arrayOf();
fty.args.push_back(new IrFuncTyArg(mainargs, false));
newIrFty.args.push_back(new IrFuncTyArg(mainargs, false));
lidx++;
}
// add explicit parameters
@@ -247,15 +247,15 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
#elif LDC_LLVM_VER == 302
llvm::Attributes a = llvm::Attributes::get(gIR->context(), attrBuilder);
#endif
fty.args.push_back(new IrFuncTyArg(argtype, byref, a));
newIrFty.args.push_back(new IrFuncTyArg(argtype, byref, a));
lidx++;
}
// Now we can modify f->fty safely.
f->fty = fty;
// Now we can modify irFty safely.
irFty = newIrFty;
// let the abi rewrite the types as necesary
abi->rewriteFunctionType(f);
abi->rewriteFunctionType(f, irFty);
// Tell the ABI we're done with this function type
abi->doneWithFunctionType();
@@ -264,26 +264,26 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
std::vector<LLType*> argtypes;
argtypes.reserve(lidx);
if (f->fty.arg_sret) argtypes.push_back(f->fty.arg_sret->ltype);
if (f->fty.arg_this) argtypes.push_back(f->fty.arg_this->ltype);
if (f->fty.arg_nest) argtypes.push_back(f->fty.arg_nest->ltype);
if (f->fty.arg_arguments) argtypes.push_back(f->fty.arg_arguments->ltype);
if (f->fty.arg_argptr) argtypes.push_back(f->fty.arg_argptr->ltype);
if (irFty.arg_sret) argtypes.push_back(irFty.arg_sret->ltype);
if (irFty.arg_this) argtypes.push_back(irFty.arg_this->ltype);
if (irFty.arg_nest) argtypes.push_back(irFty.arg_nest->ltype);
if (irFty.arg_arguments) argtypes.push_back(irFty.arg_arguments->ltype);
if (irFty.arg_argptr) argtypes.push_back(irFty.arg_argptr->ltype);
size_t beg = argtypes.size();
size_t nargs2 = f->fty.args.size();
size_t nargs2 = irFty.args.size();
for (size_t i = 0; i < nargs2; i++)
{
argtypes.push_back(f->fty.args[i]->ltype);
argtypes.push_back(irFty.args[i]->ltype);
}
// reverse params?
if (f->fty.reverseParams && nargs2 > 1)
if (irFty.reverseParams && nargs2 > 1)
{
std::reverse(argtypes.begin() + beg, argtypes.end());
}
LLFunctionType* functype = LLFunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
LLFunctionType* functype = LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg);
Logger::cout() << "Final function type: " << *functype << "\n";
@@ -377,26 +377,26 @@ LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl)
static llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
{
TypeFunction* f = static_cast<TypeFunction*>(fdecl->type);
LLFunctionType* fty = 0;
IrFuncTy &irFty = fdecl->irFty;
LLFunctionType* type = 0;
// create new ir funcTy
f->fty.reset();
f->fty.ret = new IrFuncTyArg(Type::tvoid, false);
irFty.reset();
irFty.ret = new IrFuncTyArg(Type::tvoid, false);
f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
irFty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
if (fdecl->llvmInternal == LLVMva_start)
fty = GET_INTRINSIC_DECL(vastart)->getFunctionType();
type = GET_INTRINSIC_DECL(vastart)->getFunctionType();
else if (fdecl->llvmInternal == LLVMva_copy) {
fty = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
type = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
irFty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
}
else if (fdecl->llvmInternal == LLVMva_end)
fty = GET_INTRINSIC_DECL(vaend)->getFunctionType();
assert(fty);
type = GET_INTRINSIC_DECL(vaend)->getFunctionType();
assert(type);
return fty;
return type;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -434,7 +434,7 @@ llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
dnest = Type::tvoid->pointerTo();
}
LLFunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain());
LLFunctionType* functype = DtoFunctionType(fdecl->type, fdecl->irFty, dthis, dnest, fdecl->isMain(), fdecl->isCtorDeclaration());
return functype;
}
@@ -551,6 +551,7 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
#if LDC_LLVM_VER >= 303
static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
{
IrFuncTy &irFty = fdecl->irFty;
llvm::AttributeSet old = func->getAttributes();
llvm::AttributeSet existingAttrs[] = { old.getFnAttributes(), old.getRetAttributes() };
llvm::AttributeSet newAttrs = llvm::AttributeSet::get(gIR->context(), existingAttrs);
@@ -559,9 +560,9 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
// handle implicit args
#define ADD_PA(X) \
if (f->fty.X) { \
if (f->fty.X->attrs.hasAttributes()) { \
llvm::AttributeSet a = llvm::AttributeSet::get(gIR->context(), idx, f->fty.X->attrs); \
if (irFty.X) { \
if (irFty.X->attrs.hasAttributes()) { \
llvm::AttributeSet a = llvm::AttributeSet::get(gIR->context(), idx, irFty.X->attrs); \
newAttrs = newAttrs.addAttributes(gIR->context(), idx, a); \
} \
idx++; \
@@ -583,10 +584,10 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
Parameter* fnarg = Parameter::getNth(f->parameters, k);
assert(fnarg);
llvm::AttrBuilder a = f->fty.args[k]->attrs;
llvm::AttrBuilder a = irFty.args[k]->attrs;
if (a.hasAttributes())
{
unsigned i = idx + (f->fty.reverseParams ? n-k-1 : k);
unsigned i = idx + (irFty.reverseParams ? n-k-1 : k);
llvm::AttributeSet as = llvm::AttributeSet::get(gIR->context(), i, a);
newAttrs = newAttrs.addAttributes(gIR->context(), i, as);
}
@@ -598,15 +599,16 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
#else
static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
{
IrFuncTy &irFty = fdecl->irFty;
LLSmallVector<llvm::AttributeWithIndex, 9> attrs;
int idx = 0;
// handle implicit args
#define ADD_PA(X) \
if (f->fty.X) { \
if (HAS_ATTRIBUTES(f->fty.X->attrs)) { \
attrs.push_back(llvm::AttributeWithIndex::get(idx, f->fty.X->attrs)); \
if (irFty.X) { \
if (HAS_ATTRIBUTES(irFty.X->attrs)) { \
attrs.push_back(llvm::AttributeWithIndex::get(idx, irFty.X->attrs)); \
} \
idx++; \
}
@@ -633,11 +635,11 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
Parameter* fnarg = Parameter::getNth(f->parameters, k);
assert(fnarg);
attrptr[k] = f->fty.args[k]->attrs;
attrptr[k] = irFty.args[k]->attrs;
}
// reverse params?
if (f->fty.reverseParams)
if (irFty.reverseParams)
{
std::reverse(attrptr.begin(), attrptr.end());
}
@@ -712,6 +714,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
Type* t = fdecl->type->toBasetype();
TypeFunction* f = static_cast<TypeFunction*>(t);
IrFuncTy &irFty = fdecl->irFty;
bool declareOnly = !mustDefineSymbol(fdecl);
if (fdecl->llvmInternal == LLVMva_start)
@@ -835,13 +838,13 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
// name parameters
llvm::Function::arg_iterator iarg = func->arg_begin();
if (f->fty.arg_sret) {
if (irFty.arg_sret) {
iarg->setName(".sret_arg");
fdecl->ir.irFunc->retArg = iarg;
++iarg;
}
if (f->fty.arg_this) {
if (irFty.arg_this) {
iarg->setName(".this_arg");
fdecl->ir.irFunc->thisArg = iarg;
@@ -855,21 +858,21 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
IrParameter* p = new IrParameter(v);
p->isVthis = true;
p->value = iarg;
p->arg = f->fty.arg_this;
p->arg = irFty.arg_this;
v->ir.irParam = p;
}
++iarg;
}
else if (f->fty.arg_nest) {
else if (irFty.arg_nest) {
iarg->setName(".nest_arg");
fdecl->ir.irFunc->nestArg = iarg;
assert(fdecl->ir.irFunc->nestArg);
++iarg;
}
if (f->fty.arg_argptr) {
if (irFty.arg_argptr) {
iarg->setName("._arguments");
fdecl->ir.irFunc->_arguments = iarg;
++iarg;
@@ -884,7 +887,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
{
if (fdecl->parameters && fdecl->parameters->dim > k)
{
int paramIndex = f->fty.reverseParams ? fdecl->parameters->dim-k-1 : k;
int paramIndex = irFty.reverseParams ? fdecl->parameters->dim-k-1 : k;
Dsymbol* argsym = static_cast<Dsymbol*>(fdecl->parameters->data[paramIndex]);
VarDeclaration* argvd = argsym->isVarDeclaration();
@@ -892,7 +895,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
assert(!argvd->ir.irLocal);
argvd->ir.irParam = new IrParameter(argvd);
argvd->ir.irParam->value = iarg;
argvd->ir.irParam->arg = f->fty.args[paramIndex];
argvd->ir.irParam->arg = irFty.args[paramIndex];
str = argvd->ident->toChars();
str.append("_arg");
@@ -940,6 +943,8 @@ void DtoDefineFunction(FuncDeclaration* fd)
return;
}
IrFuncTy &irFty = fd->irFty;
// debug info
fd->ir.irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd);
@@ -1006,13 +1011,13 @@ void DtoDefineFunction(FuncDeclaration* fd)
}
// give the 'this' argument storage and debug info
if (f->fty.arg_this)
if (irFty.arg_this)
{
LLValue* thisvar = irfunction->thisArg;
assert(thisvar);
LLValue* thismem = thisvar;
if (!f->fty.arg_this->byref)
if (!irFty.arg_this->byref)
{
thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
DtoStore(thisvar, thismem);
@@ -1026,7 +1031,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
}
// give the 'nestArg' storage
if (f->fty.arg_nest)
if (irFty.arg_nest)
{
LLValue *nestArg = irfunction->nestArg;
LLValue *val = DtoRawAlloca(nestArg->getType(), 0, "nestedFrame");
@@ -1038,7 +1043,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
// and debug info
if (fd->parameters)
{
size_t n = f->fty.args.size();
size_t n = irFty.args.size();
assert(n == fd->parameters->dim);
for (size_t i=0; i < n; ++i)
{
@@ -1063,7 +1068,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
// let the abi transform the argument back first
DImValue arg_dval(vd->type, irparam->value);
f->fty.getParam(vd->type, i, &arg_dval, mem);
irFty.getParam(vd->type, i, &arg_dval, mem);
// set the arg var value to the alloca
irparam->value = mem;

View File

@@ -20,6 +20,7 @@ class DValue;
struct Expression;
struct FuncDeclaration;
struct IRAsmBlock;
struct IrFuncTy;
struct Parameter;
struct Type;
namespace llvm
@@ -28,7 +29,7 @@ namespace llvm
class Value;
}
llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false);
llvm::FunctionType* DtoFunctionType(Type* t, IrFuncTy &irFty, Type* thistype, Type* nesttype, bool isMain = false, bool isCtor = false);
llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl);
llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl);

View File

@@ -28,6 +28,7 @@
#include "gen/runtime.h"
#include "gen/tollvm.h"
#include "gen/typeinf.h"
#include "gen/abi.h"
#include "ir/irmodule.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -1060,19 +1061,24 @@ void DtoVarDeclaration(VarDeclaration* vd)
if (ae->e2->op == TOKcall) {
CallExp *ce = static_cast<CallExp *>(ae->e2);
TypeFunction *tf = static_cast<TypeFunction *>(ce->e1->type->toBasetype());
if (tf->ty == Tfunction && tf->fty.arg_sret) {
LLValue* const val = ce->toElem(gIR)->getLVal();
if (isSpecialRefVar(vd))
{
vd->ir.irLocal->value = DtoAlloca(
vd->type->pointerTo(), vd->toChars());
DtoStore(val, vd->ir.irLocal->value);
if (tf->ty == Tfunction && tf->linkage != LINKintrinsic) {
gABI->newFunctionType(tf);
bool retInArg = gABI->returnInArg(tf);
gABI->doneWithFunctionType();
if (retInArg) {
LLValue* const val = ce->toElem(gIR)->getLVal();
if (isSpecialRefVar(vd))
{
vd->ir.irLocal->value = DtoAlloca(
vd->type->pointerTo(), vd->toChars());
DtoStore(val, vd->ir.irLocal->value);
}
else
{
vd->ir.irLocal->value = val;
}
return;
}
else
{
vd->ir.irLocal->value = val;
}
return;
}
}
}

View File

@@ -185,6 +185,8 @@ void tokToIcmpPred(TOK op, bool isUnsigned, llvm::ICmpInst::Predicate* outPred,
// gen/tocall.cpp stuff below
////////////////////////////////////////////
///
IrFuncTy &DtoIrTypeFunction(DValue* fnval);
///
TypeFunction* DtoTypeFunction(DValue* fnval);

View File

@@ -925,12 +925,12 @@ static void LLVM_D_BuildRuntimeModule()
M
);
gABI->newFunctionType(dty);
gABI->rewriteFunctionType(dty);
gABI->rewriteFunctionType(dty, dty->irFty);
gABI->doneWithFunctionType();
#if LDC_LLVM_VER < 303
fn->addAttribute(1, dty->fty.args[0]->attrs);
fn->addAttribute(1, dty->irFty.args[0]->attrs);
#else
fn->addAttributes(1, llvm::AttributeSet::get(gIR->context(), 1, dty->fty.args[0]->attrs));
fn->addAttributes(1, llvm::AttributeSet::get(gIR->context(), 1, dty->irFty.args[0]->attrs));
#endif
fn->setCallingConv(gABI->callingConv(LINKd));
}

View File

@@ -117,7 +117,7 @@ void ReturnStatement::toIR(IRState* p)
dval = ae->toElemDtor(p);
}
// do abi specific transformations on the return value
v = p->func()->type->fty.putRet(exp->type, dval);
v = p->func()->decl->irFty.putRet(exp->type, dval);
}
if (Logger::enabled())

View File

@@ -23,6 +23,23 @@
//////////////////////////////////////////////////////////////////////////////////////////
IrFuncTy &DtoIrTypeFunction(DValue* fnval)
{
if (DFuncValue* dfnval = fnval->isFunc())
{
if (dfnval->func)
return dfnval->func->irFty;
}
Type* type = stripModifiers(fnval->getType()->toBasetype());
if (type->ty == Tfunction)
return static_cast<TypeFunction*>(type)->irFty;
else if (type->ty == Tdelegate)
return static_cast<TypeDelegate*>(type)->irFty;
llvm_unreachable("Cannot get IrFuncTy from non lazy/function/delegate");
}
TypeFunction* DtoTypeFunction(DValue* fnval)
{
Type* type = fnval->getType()->toBasetype();
@@ -113,7 +130,7 @@ LLFunctionType* DtoExtractFunctionType(LLType* type)
//////////////////////////////////////////////////////////////////////////////////////////
static LLValue *fixArgument(DValue *argval, TypeFunction* tf, LLType *callableArgType, size_t argIndex)
static LLValue *fixArgument(DValue *argval, IrFuncTy &irFty, LLType *callableArgType, size_t argIndex)
{
#if 0
if (Logger::enabled()) {
@@ -123,7 +140,7 @@ static LLValue *fixArgument(DValue *argval, TypeFunction* tf, LLType *callableAr
#endif
// give the ABI a say
LLValue* arg = tf->fty.putParam(argval->getType(), argIndex, argval);
LLValue* arg = irFty.putParam(argval->getType(), argIndex, argval);
#if 0
if (Logger::enabled()) {
@@ -189,8 +206,8 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
#else
std::vector<llvm::AttributeWithIndex> &attrs,
#endif
TypeFunction* tf, Expressions* arguments,
size_t argidx,
TypeFunction* tf, IrFuncTy &irFty,
Expressions* arguments, size_t argidx,
LLFunctionType* callableTy)
{
Logger::println("doing d-style variadic arguments");
@@ -284,14 +301,14 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
// specify arguments
args.push_back(DtoLoad(typeinfoarrayparam));
if (HAS_ATTRIBUTES(tf->fty.arg_arguments->attrs)) {
addToAttributes(attrs, argidx, tf->fty.arg_arguments->attrs);
if (HAS_ATTRIBUTES(irFty.arg_arguments->attrs)) {
addToAttributes(attrs, argidx, irFty.arg_arguments->attrs);
}
++argidx;
args.push_back(gIR->ir->CreateBitCast(mem, getPtrToType(LLType::getInt8Ty(gIR->context())), "tmp"));
if (HAS_ATTRIBUTES(tf->fty.arg_argptr->attrs)) {
addToAttributes(attrs, argidx, tf->fty.arg_argptr->attrs);
if (HAS_ATTRIBUTES(irFty.arg_argptr->attrs)) {
addToAttributes(attrs, argidx, irFty.arg_argptr->attrs);
}
// pass non variadic args
@@ -299,11 +316,11 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
{
Parameter* fnarg = Parameter::getNth(tf->parameters, i);
DValue* argval = DtoArgument(fnarg, static_cast<Expression*>(arguments->data[i]));
args.push_back(fixArgument(argval, tf, callableTy->getParamType(argidx++), i));
args.push_back(fixArgument(argval, irFty, callableTy->getParamType(argidx++), i));
if (HAS_ATTRIBUTES(tf->fty.args[i]->attrs))
if (HAS_ATTRIBUTES(irFty.args[i]->attrs))
{
addToAttributes(attrs, argidx, tf->fty.args[i]->attrs);
addToAttributes(attrs, argidx, irFty.args[i]->attrs);
}
}
}
@@ -332,13 +349,14 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
bool va_intrinsic = (dfnval && dfnval->func && dfnval->func->isVaIntrinsic());
// get function type info
IrFuncTy &irFty = DtoIrTypeFunction(fnval);
TypeFunction* tf = DtoTypeFunction(fnval);
// misc
bool retinptr = tf->fty.arg_sret;
bool thiscall = tf->fty.arg_this;
bool retinptr = irFty.arg_sret;
bool thiscall = irFty.arg_this;
bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate);
bool nestedcall = tf->fty.arg_nest;
bool nestedcall = irFty.arg_nest;
bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1);
llvm::CallingConv::ID callconv = gABI->callingConv(tf->linkage);
@@ -366,14 +384,14 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
#endif
// return attrs
if (HAS_ATTRIBUTES(tf->fty.ret->attrs))
if (HAS_ATTRIBUTES(irFty.ret->attrs))
{
addToAttributes(attrs, 0, tf->fty.ret->attrs);
addToAttributes(attrs, 0, irFty.ret->attrs);
}
// handle implicit arguments
std::vector<LLValue*> args;
args.reserve(tf->fty.args.size());
args.reserve(irFty.args.size());
// return in hidden ptr is first
if (retinptr)
@@ -385,7 +403,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// add attrs for hidden ptr
#if LDC_LLVM_VER >= 303
const unsigned Index = 1;
llvm::AttrBuilder builder(tf->fty.arg_sret->attrs);
llvm::AttrBuilder builder(irFty.arg_sret->attrs);
assert((builder.contains(llvm::Attribute::StructRet) || builder.contains(llvm::Attribute::InReg))
&& "Sret arg not sret or inreg?");
llvm::AttributeSet as = llvm::AttributeSet::get(gIR->context(), Index, builder);
@@ -393,7 +411,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
#else
llvm::AttributeWithIndex Attr;
Attr.Index = 1;
Attr.Attrs = tf->fty.arg_sret->attrs;
Attr.Attrs = irFty.arg_sret->attrs;
#if LDC_LLVM_VER == 302
assert((Attr.Attrs.hasAttribute(llvm::Attributes::StructRet) || Attr.Attrs.hasAttribute(llvm::Attributes::InReg))
&& "Sret arg not sret or inreg?");
@@ -461,13 +479,13 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
}
// add attributes for context argument
if (tf->fty.arg_this && HAS_ATTRIBUTES(tf->fty.arg_this->attrs))
if (irFty.arg_this && HAS_ATTRIBUTES(irFty.arg_this->attrs))
{
addToAttributes(attrs, retinptr ? 2 : 1, tf->fty.arg_this->attrs);
addToAttributes(attrs, retinptr ? 2 : 1, irFty.arg_this->attrs);
}
else if (tf->fty.arg_nest && HAS_ATTRIBUTES(tf->fty.arg_nest->attrs))
else if (irFty.arg_nest && HAS_ATTRIBUTES(irFty.arg_nest->attrs))
{
addToAttributes(attrs, retinptr ? 2 : 1, tf->fty.arg_nest->attrs);
addToAttributes(attrs, retinptr ? 2 : 1, irFty.arg_nest->attrs);
}
}
@@ -490,7 +508,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// d style varargs needs a few more hidden arguments as well as special passing
else if (dvarargs)
{
DtoBuildDVarArgList(args, attrs, tf, arguments, argiter-argbegin+1, callableTy);
DtoBuildDVarArgList(args, attrs, tf, irFty, arguments, argiter-argbegin+1, callableTy);
}
// otherwise we're looking at a normal function call
@@ -543,20 +561,20 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
{
DValue* argval = argvals.at(i);
int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i;
LLValue *arg = fixArgument(argval, tf, callableTy->getParamType(j), i);
int j = irFty.reverseParams ? beg + n - i - 1 : beg + i;
LLValue *arg = fixArgument(argval, irFty, callableTy->getParamType(j), i);
args.push_back(arg);
#if LDC_LLVM_VER >= 303
addToAttributes(attrs, beg + 1 + (tf->fty.reverseParams ? n-i-1: i), tf->fty.args[i]->attrs);
addToAttributes(attrs, beg + 1 + (irFty.reverseParams ? n-i-1: i), irFty.args[i]->attrs);
#else
attrptr[i] = tf->fty.args[i]->attrs;
attrptr[i] = irFty.args[i]->attrs;
#endif
++argiter;
}
// reverse the relevant params as well as the param attrs
if (tf->fty.reverseParams)
if (irFty.reverseParams)
{
std::reverse(args.begin() + beg, args.end());
#if LDC_LLVM_VER < 303
@@ -623,7 +641,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
{
// do abi specific return value fixups
DImValue dretval(tf->next, retllval);
retllval = tf->fty.getRet(tf->next, &dretval);
retllval = irFty.getRet(tf->next, &dretval);
}
// Hack around LDC assuming structs and static arrays are in memory:

View File

@@ -1465,7 +1465,11 @@ DValue* PtrExp::toElem(IRState* p)
if (type->toBasetype()->ty == Tfunction)
{
assert(!cachedLvalue);
return new DImValue(type, e1->toElem(p)->getRVal());
DValue *dv = e1->toElem(p);
if (DFuncValue *dfv = dv->isFunc())
return new DFuncValue(type, dfv->func, dfv->getRVal());
else
return new DImValue(type, dv->getRVal());
}
// get the rvalue and return it as an lvalue
@@ -2798,7 +2802,7 @@ DValue* FuncExp::toElem(IRState* p)
return new DImValue(type, DtoAggrPair(cval, castfptr, ".func"));
} else {
return new DImValue(type, fd->ir.irFunc->func);
return new DFuncValue(type, fd, fd->ir.irFunc->func);
}
}

View File

@@ -24,11 +24,19 @@
#include "gen/structs.h"
// D->LLVM type handling stuff
/* The function takes a d type and returns an appropriate llvm type.
*
* Notice that the function does not support function types with context arguments.
* DtoTypeFunction(FuncDeclaration*) is to be used instead.
*/
LLType* DtoType(Type* t);
LLType* voidToI8(LLType* t);
LLType* i1ToI8(LLType* t);
// returns true is the type must be passed by pointer
// returns true if the type must be passed by pointer
bool DtoIsPassedByRef(Type* type);
// should argument be zero or sign extended

View File

@@ -29,6 +29,7 @@
#include "gen/arrays.h"
#include "gen/metadata.h"
#include "gen/runtime.h"
#include "gen/functions.h"
#include "ir/iraggr.h"
#include "ir/irtypeclass.h"
@@ -177,7 +178,7 @@ LLConstant * IrAggr::getVtblInit()
if (cd->isAbstract() || (fd->isAbstract() && !fd->fbody))
{
c = getNullValue(DtoType(fd->type->pointerTo()));
c = getNullValue(getPtrToType(DtoFunctionType(fd)));
}
else
{
@@ -329,8 +330,7 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
// the function, we place into the vtable a small wrapper, called thunk,
// that casts 'this' to the object and then pass it to the real function.
if (b->base->isCPPinterface()) {
TypeFunction *f = (TypeFunction*)fd->type->toBasetype();
assert(f->fty.arg_this);
assert(fd->irFty.arg_this);
// create the thunk function
OutBuffer name;
@@ -352,7 +352,7 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
args.push_back(iarg);
// cast 'this' to Object
LLValue* &thisArg = args[(f->fty.arg_sret == 0) ? 0 : 1];
LLValue* &thisArg = args[(fd->irFty.arg_sret == 0) ? 0 : 1];
LLType* thisType = thisArg->getType();
thisArg = DtoBitCast(thisArg, getVoidPtrType());
thisArg = DtoGEP1(thisArg, DtoConstInt(-b->offset));

View File

@@ -166,28 +166,6 @@ IrTypePointer* IrTypePointer::get(Type* dt)
}
else
{
if (dt->nextOf()->ty == Tfunction)
{
TypeFunction* tf = static_cast<TypeFunction*>(dt->nextOf());
if (tf->funcdecl)
{
if (FuncLiteralDeclaration* fld =
tf->funcdecl->isFuncLiteralDeclaration())
{
if (fld->tok == TOKreserved)
{
// This is the type of a lambda that was inferred to be
// a function literal instead of a delegate, so set tok
// here in order to get correct types/mangling. Horrible
// hack, but DMD does the same thing in FuncExp::toElem
// and other random places.
fld->tok = TOKfunction;
fld->vthis = NULL;
}
}
}
}
elemType = i1ToI8(voidToI8(DtoType(dt->nextOf())));
// DtoType could have already created the same type, e.g. for

View File

@@ -25,6 +25,7 @@
#include "gen/tollvm.h"
#include "gen/utils.h"
#include "gen/llvmhelpers.h"
#include "gen/functions.h"
#include "ir/irtypeclass.h"
//////////////////////////////////////////////////////////////////////////////
@@ -346,7 +347,7 @@ std::vector<llvm::Type*> IrTypeClass::buildVtblType(Type* first, Array* vtbl_arr
continue;
}
types.push_back(DtoType(fd->type->pointerTo()));
types.push_back(getPtrToType(DtoFunctionType(fd)));
}

View File

@@ -30,14 +30,8 @@ IrTypeFunction* IrTypeFunction::get(Type* dt, Type* nestedContextOverride)
assert(!dt->irtype);
assert(dt->ty == Tfunction);
// We can't get cycles here, but we can end up building the type as part of
// a class vtbl, ...
llvm::Type* lt;
TypeFunction* tf = static_cast<TypeFunction*>(dt);
if (tf->funcdecl)
lt = DtoFunctionType(tf->funcdecl);
else
lt = DtoFunctionType(tf, NULL, nestedContextOverride);
llvm::Type* lt = DtoFunctionType(tf, tf->irFty, NULL, nestedContextOverride);
if (!dt->irtype)
dt->irtype = new IrTypeFunction(dt, lt);
@@ -51,29 +45,21 @@ IrTypeDelegate::IrTypeDelegate(Type * dt, LLType* lt)
{
}
IrTypeDelegate* IrTypeDelegate::get(Type* dt)
IrTypeDelegate* IrTypeDelegate::get(Type* t)
{
assert(!dt->irtype);
assert(dt->ty == Tdelegate);
assert(!t->irtype);
assert(t->ty == Tdelegate);
assert(t->nextOf()->ty == Tfunction);
TypeDelegate *dt = (TypeDelegate*)t;
// We can't get cycles here, but we could end up building the type as part
// of a class vtbl, ...
if (!dt->nextOf()->irtype)
{
// Build the underlying function type. Be sure to set irtype here, so
// the nested context arg doesn't disappear if DtoType is ever called
// on dt->nextOf().
IrTypeFunction::get(dt->nextOf(), Type::tvoid->pointerTo());
}
if (!dt->irtype)
{
assert(static_cast<TypeFunction*>(dt->nextOf())->fty.arg_nest &&
"Underlying function type should have nested context arg, "
"picked up random pre-existing type?"
);
TypeFunction* tf = static_cast<TypeFunction*>(dt->nextOf());
llvm::Type* ltf = DtoFunctionType(tf, dt->irFty, NULL, Type::tvoid->pointerTo());
llvm::Type *types[] = { getVoidPtrType(),
getPtrToType(dt->nextOf()->irtype->getLLType()) };
getPtrToType(ltf) };
LLStructType* lt = LLStructType::get(gIR->context(), types, false);
dt->irtype = new IrTypeDelegate(dt, lt);
}