mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-28 22:21:31 +03:00
Removed KDevelop3 project files, CMake can generate them just fine!
Fixed function literals in static initializers. Changed alignment of delegates from 2*PTRSIZE to just PTRSIZE. Changed errors to go to stderr instead of stdout. Fairly major rewriting of struct/union/class handling, STILL A BIT BUGGY !!!
This commit is contained in:
parent
049e24cef8
commit
f46f865375
47 changed files with 2103 additions and 2398 deletions
|
@ -45,7 +45,6 @@ namespace llvm
|
|||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
struct DUnion;
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
|
@ -258,9 +257,6 @@ struct ClassDeclaration : AggregateDeclaration
|
|||
|
||||
Symbol *vtblsym;
|
||||
|
||||
// llvm
|
||||
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
};
|
||||
|
||||
|
|
|
@ -616,7 +616,6 @@ void AnonDeclaration::semantic(Scope *sc)
|
|||
sc->flags = 0;
|
||||
aad.structalign = sc->structalign;
|
||||
aad.parent = ad;
|
||||
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)decl->data[i];
|
||||
|
@ -672,6 +671,9 @@ void AnonDeclaration::semantic(Scope *sc)
|
|||
{
|
||||
VarDeclaration *v = (VarDeclaration *)aad.fields.data[i];
|
||||
|
||||
// LDC
|
||||
v->offset2 = sc->offset;
|
||||
|
||||
v->offset += sc->offset;
|
||||
|
||||
// LDC
|
||||
|
|
|
@ -50,7 +50,7 @@ struct AttribDeclaration : Dsymbol
|
|||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
AttribDeclaration *isAttribDeclaration() { return this; }
|
||||
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
};
|
||||
|
||||
|
@ -107,6 +107,9 @@ struct AnonDeclaration : AttribDeclaration
|
|||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
// LDC
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
};
|
||||
|
||||
struct PragmaDeclaration : AttribDeclaration
|
||||
|
|
|
@ -624,6 +624,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
|
|||
|
||||
// LDC
|
||||
anonDecl = NULL;
|
||||
offset2 = 0;
|
||||
}
|
||||
|
||||
Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
|
|
@ -273,6 +273,7 @@ struct VarDeclaration : Declaration
|
|||
|
||||
// LDC
|
||||
AnonDeclaration* anonDecl;
|
||||
unsigned offset2;
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
|
|
|
@ -628,6 +628,9 @@ struct FuncExp : Expression
|
|||
int inlineCost(InlineCostState *ics);
|
||||
//Expression *doInline(InlineDoState *ids);
|
||||
//Expression *inlineScan(InlineScanState *iss);
|
||||
|
||||
// LDC
|
||||
virtual llvm::Constant *toConstElem(IRState *irs);
|
||||
};
|
||||
|
||||
// Declaration of a symbol
|
||||
|
|
|
@ -1196,9 +1196,9 @@ int main(int argc, char *argv[], char** envp)
|
|||
m->inlineScan();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (global.errors)
|
||||
fatal();
|
||||
#endif
|
||||
|
||||
// Generate output files
|
||||
for (i = 0; i < modules.dim; i++)
|
||||
|
|
|
@ -345,7 +345,7 @@ void inifile(char *argv0, char *inifile);
|
|||
void halt();
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC
|
||||
#if IN_GCC || IN_LLVM
|
||||
#define stdmsg stderr
|
||||
#else
|
||||
#define stdmsg stdout
|
||||
|
|
|
@ -3186,6 +3186,14 @@ d_uns64 TypeDelegate::size(Loc loc)
|
|||
return PTRSIZE * 2;
|
||||
}
|
||||
|
||||
// LDC added, no reason to align to 2*PTRSIZE
|
||||
unsigned TypeDelegate::alignsize()
|
||||
{
|
||||
// A Delegate consists of two ptr values, so align it on pointer size
|
||||
// boundary
|
||||
return PTRSIZE;
|
||||
}
|
||||
|
||||
void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||
{
|
||||
if (mod != this->mod)
|
||||
|
|
|
@ -451,6 +451,7 @@ struct TypeDelegate : Type
|
|||
Type *syntaxCopy();
|
||||
Type *semantic(Loc loc, Scope *sc);
|
||||
d_uns64 size(Loc loc);
|
||||
unsigned alignsize(); // added in LDC
|
||||
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
|
|
|
@ -45,7 +45,6 @@ namespace llvm
|
|||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
struct DUnion;
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
|
@ -264,9 +263,6 @@ struct ClassDeclaration : AggregateDeclaration
|
|||
|
||||
Symbol *vtblsym;
|
||||
|
||||
// llvm
|
||||
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
};
|
||||
|
||||
|
|
|
@ -629,7 +629,6 @@ void AnonDeclaration::semantic(Scope *sc)
|
|||
sc->flags = 0;
|
||||
aad.structalign = sc->structalign;
|
||||
aad.parent = ad;
|
||||
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)decl->data[i];
|
||||
|
@ -685,6 +684,9 @@ void AnonDeclaration::semantic(Scope *sc)
|
|||
{
|
||||
VarDeclaration *v = (VarDeclaration *)aad.fields.data[i];
|
||||
|
||||
// LDC
|
||||
v->offset2 = sc->offset;
|
||||
|
||||
v->offset += sc->offset;
|
||||
|
||||
// LDC
|
||||
|
|
|
@ -50,7 +50,7 @@ struct AttribDeclaration : Dsymbol
|
|||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
AttribDeclaration *isAttribDeclaration() { return this; }
|
||||
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
};
|
||||
|
||||
|
|
|
@ -618,6 +618,7 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
|
|||
|
||||
// LDC
|
||||
anonDecl = NULL;
|
||||
offset2 = 0;
|
||||
}
|
||||
|
||||
Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
|
|
@ -279,6 +279,7 @@ struct VarDeclaration : Declaration
|
|||
|
||||
// LDC
|
||||
AnonDeclaration* anonDecl;
|
||||
unsigned offset2;
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
|
|
|
@ -653,6 +653,9 @@ struct FuncExp : Expression
|
|||
int inlineCost(InlineCostState *ics);
|
||||
//Expression *doInline(InlineDoState *ids);
|
||||
//Expression *inlineScan(InlineScanState *iss);
|
||||
|
||||
// LDC
|
||||
virtual llvm::Constant *toConstElem(IRState *irs);
|
||||
};
|
||||
|
||||
// Declaration of a symbol
|
||||
|
|
|
@ -1220,9 +1220,9 @@ int main(int argc, char *argv[], char** envp)
|
|||
m->inlineScan();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (global.errors)
|
||||
fatal();
|
||||
#endif
|
||||
|
||||
// Generate output files
|
||||
for (i = 0; i < modules.dim; i++)
|
||||
|
|
|
@ -350,7 +350,7 @@ void inifile(const char *argv0, const char *inifile);
|
|||
void halt();
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC
|
||||
#if IN_GCC || IN_LLVM
|
||||
#define stdmsg stderr
|
||||
#else
|
||||
#define stdmsg stdout
|
||||
|
|
|
@ -3694,6 +3694,14 @@ d_uns64 TypeDelegate::size(Loc loc)
|
|||
return PTRSIZE * 2;
|
||||
}
|
||||
|
||||
// LDC added, no reason to align to 2*PTRSIZE
|
||||
unsigned TypeDelegate::alignsize()
|
||||
{
|
||||
// A Delegate consists of two ptr values, so align it on pointer size
|
||||
// boundary
|
||||
return PTRSIZE;
|
||||
}
|
||||
|
||||
void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||
{
|
||||
if (mod != this->mod)
|
||||
|
|
|
@ -516,6 +516,7 @@ struct TypeDelegate : TypeNext
|
|||
Type *syntaxCopy();
|
||||
Type *semantic(Loc loc, Scope *sc);
|
||||
d_uns64 size(Loc loc);
|
||||
unsigned alignsize(); // added in LDC
|
||||
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit();
|
||||
|
|
|
@ -208,6 +208,9 @@ void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FIXME: this looks like it could use a cleanup
|
||||
|
||||
LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
|
||||
{
|
||||
Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars());
|
||||
|
@ -241,6 +244,9 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
|
|||
Type* arrnext = arrinittype->nextOf();
|
||||
const LLType* elemty = DtoType(arrinittype->nextOf());
|
||||
|
||||
// true if there is a mismatch with one of the initializers
|
||||
bool mismatch = false;
|
||||
|
||||
assert(arrinit->index.dim == arrinit->value.dim);
|
||||
for (unsigned i=0,j=0; i < tdim; ++i)
|
||||
{
|
||||
|
@ -292,23 +298,51 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
|
|||
v = DtoConstInitializer(arrinit->loc, t->nextOf(), init);
|
||||
assert(v);
|
||||
|
||||
// global arrays of unions might have type mismatch for each element
|
||||
// if there is any mismatch at all, we need to use a struct instead :/
|
||||
if (v->getType() != elemty)
|
||||
mismatch = true;
|
||||
|
||||
inits[i] = v;
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "llval: " << *v << '\n';
|
||||
}
|
||||
|
||||
Logger::println("building constant array");
|
||||
|
||||
LLConstant* constarr;
|
||||
const LLArrayType* arrty = LLArrayType::get(elemty,tdim);
|
||||
LLConstant* constarr = LLConstantArray::get(arrty, inits);
|
||||
|
||||
if (mismatch)
|
||||
{
|
||||
constarr = LLConstantStruct::get(inits);
|
||||
}
|
||||
else
|
||||
{
|
||||
constarr = LLConstantArray::get(arrty, inits);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (Logger::enabled())
|
||||
{
|
||||
Logger::cout() << "array type: " << *arrty << '\n';
|
||||
size_t n = inits.size();
|
||||
for (size_t i=0; i<n; i++)
|
||||
Logger::cout() << " init " << i << " = " << *inits[i] << '\n';
|
||||
}
|
||||
#endif
|
||||
|
||||
if (arrinittype->ty == Tsarray)
|
||||
return constarr;
|
||||
else
|
||||
assert(arrinittype->ty == Tarray);
|
||||
|
||||
LLGlobalVariable* gvar = new LLGlobalVariable(arrty,true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module);
|
||||
LLGlobalVariable* gvar = new LLGlobalVariable(constarr->getType(),true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module);
|
||||
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
|
||||
|
||||
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
|
||||
gep = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(elemty));
|
||||
|
||||
return DtoConstSlice(DtoConstSize_t(tdim),gep);
|
||||
}
|
||||
|
||||
|
@ -794,24 +828,6 @@ LLValue* DtoDynArrayIs(TOK op, DValue* l, DValue* r)
|
|||
return (op == TOKnotidentity) ? gIR->ir->CreateNot(res) : res;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c)
|
||||
{
|
||||
const LLArrayType* at = isaArray(t);
|
||||
assert(at);
|
||||
|
||||
if (isaArray(at->getElementType()))
|
||||
{
|
||||
c = DtoConstStaticArray(at->getElementType(), c);
|
||||
}
|
||||
else {
|
||||
assert(at->getElementType() == c->getType());
|
||||
}
|
||||
std::vector<LLConstant*> initvals;
|
||||
initvals.resize(at->getNumElements(), c);
|
||||
return llvm::ConstantArray::get(at, initvals);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
LLValue* DtoArrayLen(DValue* v)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@ const llvm::ArrayType* DtoStaticArrayType(Type* sarrayTy);
|
|||
|
||||
LLConstant* DtoConstArrayInitializer(ArrayInitializer* si);
|
||||
LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr);
|
||||
LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c);
|
||||
|
||||
void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src);
|
||||
void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
|
||||
|
|
1484
gen/classes.cpp
1484
gen/classes.cpp
File diff suppressed because it is too large
Load diff
|
@ -97,16 +97,8 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co
|
|||
}
|
||||
|
||||
if (dVararg) {
|
||||
ClassDeclaration* ti = Type::typeinfo;
|
||||
ti->toObjFile(0); // TODO: multiobj
|
||||
DtoForceConstInitDsymbol(ti);
|
||||
assert(ti->ir.irStruct->constInit);
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(DtoSize_t());
|
||||
types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType())));
|
||||
const LLType* t1 = llvm::StructType::get(types);
|
||||
paramvec.push_back(t1);
|
||||
paramvec.push_back(getPtrToType(LLType::Int8Ty));
|
||||
paramvec.push_back(DtoType(Type::typeinfo->type->arrayOf())); // _arguments
|
||||
paramvec.push_back(getVoidPtrType()); // _argptr
|
||||
}
|
||||
|
||||
// number of formal params
|
||||
|
@ -286,7 +278,7 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
|
|||
Logger::println("isMember = this is: %s", ad->type->toChars());
|
||||
thisty = DtoType(ad->type);
|
||||
//Logger::cout() << "this llvm type: " << *thisty << '\n';
|
||||
if (isaStruct(thisty) || (!gIR->structs.empty() && thisty == gIR->topstruct()->recty.get()))
|
||||
if (isaStruct(thisty) || (!gIR->structs.empty() && thisty == gIR->topstruct()->type->ir.type->get()))
|
||||
thisty = getPtrToType(thisty);
|
||||
}
|
||||
else {
|
||||
|
@ -547,35 +539,36 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
}
|
||||
|
||||
// we never reference parameters of function prototypes
|
||||
std::string str;
|
||||
if (!declareOnly)
|
||||
{
|
||||
// name parameters
|
||||
llvm::Function::arg_iterator iarg = func->arg_begin();
|
||||
|
||||
if (f->retInPtr) {
|
||||
iarg->setName(".sretarg");
|
||||
iarg->setName(".sret_arg");
|
||||
fdecl->ir.irFunc->retArg = iarg;
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (f->usesThis) {
|
||||
iarg->setName("this");
|
||||
iarg->setName(".this_arg");
|
||||
fdecl->ir.irFunc->thisArg = iarg;
|
||||
assert(fdecl->ir.irFunc->thisArg);
|
||||
++iarg;
|
||||
}
|
||||
else if (f->usesNest) {
|
||||
iarg->setName(".nest");
|
||||
iarg->setName(".nest_arg");
|
||||
fdecl->ir.irFunc->nestArg = iarg;
|
||||
assert(fdecl->ir.irFunc->nestArg);
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (f->linkage == LINKd && f->varargs == 1) {
|
||||
iarg->setName("_arguments");
|
||||
iarg->setName("._arguments");
|
||||
fdecl->ir.irFunc->_arguments = iarg;
|
||||
++iarg;
|
||||
iarg->setName("_argptr");
|
||||
iarg->setName("._argptr");
|
||||
fdecl->ir.irFunc->_argptr = iarg;
|
||||
++iarg;
|
||||
}
|
||||
|
@ -597,7 +590,10 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
assert(!argvd->ir.irLocal);
|
||||
argvd->ir.irLocal = new IrLocal(argvd);
|
||||
argvd->ir.irLocal->value = iarg;
|
||||
iarg->setName(argvd->ident->toChars());
|
||||
|
||||
str = argvd->ident->toChars();
|
||||
str.append("_arg");
|
||||
iarg->setName(str);
|
||||
|
||||
k++;
|
||||
}
|
||||
|
@ -671,8 +667,7 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
|||
if (fd->isMain())
|
||||
gIR->emitMain = true;
|
||||
|
||||
std::string entryname("entry_");
|
||||
entryname.append(fd->toPrettyChars());
|
||||
std::string entryname("entry");
|
||||
|
||||
llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func);
|
||||
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func);
|
||||
|
@ -710,7 +705,7 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
|||
LLValue* thisvar = irfunction->thisArg;
|
||||
assert(thisvar);
|
||||
|
||||
LLValue* thismem = DtoAlloca(thisvar->getType(), ".this");
|
||||
LLValue* thismem = DtoAlloca(thisvar->getType(), "this");
|
||||
DtoStore(thisvar, thismem);
|
||||
irfunction->thisArg = thismem;
|
||||
|
||||
|
@ -760,7 +755,7 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
|||
if (!refout && (!DtoIsPassedByRef(vd->type) || lazy))
|
||||
{
|
||||
LLValue* a = irloc->value;
|
||||
LLValue* v = DtoAlloca(a->getType(), "."+a->getName());
|
||||
LLValue* v = DtoAlloca(a->getType(), vd->ident->toChars());
|
||||
DtoStore(a,v);
|
||||
irloc->value = v;
|
||||
}
|
||||
|
@ -822,7 +817,7 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
|||
ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
|
||||
assert(cd);
|
||||
assert(cd->vthis);
|
||||
src = DtoLoad(DtoGEPi(thisval, 0,2+cd->vthis->ir.irField->index, ".vthis"));
|
||||
src = DtoLoad(DtoGEPi(thisval, 0,cd->vthis->ir.irField->index, ".vthis"));
|
||||
}
|
||||
DtoMemCpy(nestedVars, src, DtoConstSize_t(nparelems*PTRSIZE));
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ struct FuncDeclaration;
|
|||
struct Module;
|
||||
struct TypeStruct;
|
||||
struct BaseClass;
|
||||
struct AnonDeclaration;
|
||||
struct EnclosingHandler;
|
||||
|
||||
struct IrModule;
|
||||
|
@ -147,10 +148,6 @@ struct IRState
|
|||
StructVector structs;
|
||||
IrStruct* topstruct();
|
||||
|
||||
// classes TODO move into IRClass
|
||||
typedef std::vector<ClassDeclaration*> ClassDeclVec;
|
||||
ClassDeclVec classes;
|
||||
|
||||
// D main function
|
||||
bool emitMain;
|
||||
llvm::Function* mainFunc;
|
||||
|
|
|
@ -338,7 +338,7 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
|
|||
{
|
||||
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
|
||||
LLValue* val = DtoLoad(irfunc->thisArg);
|
||||
ctx = DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis"));
|
||||
ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
|
||||
}
|
||||
else
|
||||
ctx = irfunc->nestArg;
|
||||
|
@ -374,7 +374,7 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
|||
if (!cd || !cd->vthis)
|
||||
return getNullPtr(getVoidPtrType());
|
||||
LLValue* val = DtoLoad(irfunc->thisArg);
|
||||
return DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis"));
|
||||
return DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -964,73 +964,68 @@ void DtoConstInitGlobal(VarDeclaration* vd)
|
|||
if (vd->ir.initialized) return;
|
||||
vd->ir.initialized = gIR->dmodule;
|
||||
|
||||
Logger::println("* DtoConstInitGlobal(%s)", vd->toChars());
|
||||
Logger::println("DtoConstInitGlobal(%s) @ %s", vd->toChars(), vd->locToChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
bool emitRTstaticInit = false;
|
||||
// if the variable is a function local static variable with a runtime initializer
|
||||
// we must do lazy initialization, which involves a boolean flag to make sure it happens only once
|
||||
// FIXME: I don't think it's thread safe ...
|
||||
|
||||
LLConstant* _init = 0;
|
||||
if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) {
|
||||
_init = DtoConstInitializer(vd->loc, vd->type, NULL);
|
||||
emitRTstaticInit = true;
|
||||
}
|
||||
else {
|
||||
_init = DtoConstInitializer(vd->loc, vd->type, vd->init);
|
||||
}
|
||||
bool doLazyInit = false;
|
||||
Dsymbol* par = vd->toParent2();
|
||||
|
||||
const LLType* _type = DtoType(vd->type);
|
||||
Type* t = vd->type->toBasetype();
|
||||
|
||||
//Logger::cout() << "initializer: " << *_init << '\n';
|
||||
if (_type != _init->getType()) {
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
|
||||
|
||||
// zero initalizer
|
||||
if (_init->isNullValue())
|
||||
_init = llvm::Constant::getNullValue(_type);
|
||||
// pointer to global constant (struct.init)
|
||||
else if (llvm::isa<llvm::GlobalVariable>(_init))
|
||||
if (par && par->isFuncDeclaration() && vd->init)
|
||||
{
|
||||
if (ExpInitializer* einit = vd->init->isExpInitializer())
|
||||
{
|
||||
assert(_init->getType()->getContainedType(0) == _type);
|
||||
llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
|
||||
assert(t->ty == Tstruct);
|
||||
TypeStruct* ts = (TypeStruct*)t;
|
||||
assert(ts->sym->ir.irStruct->constInit);
|
||||
_init = ts->sym->ir.irStruct->constInit;
|
||||
}
|
||||
// array single value init
|
||||
else if (isaArray(_type))
|
||||
{
|
||||
_init = DtoConstStaticArray(_type, _init);
|
||||
}
|
||||
else {
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
|
||||
//assert(0);
|
||||
if (!einit->exp->isConst())
|
||||
{
|
||||
// mark as needing lazy now
|
||||
doLazyInit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we do lazy init, we start out with an undefined initializer
|
||||
LLConstant* initVal;
|
||||
if (doLazyInit)
|
||||
{
|
||||
initVal = llvm::UndefValue::get(DtoType(vd->type));
|
||||
}
|
||||
// otherwise we build it
|
||||
else
|
||||
{
|
||||
initVal = DtoConstInitializer(vd->loc, vd->type, vd->init);
|
||||
}
|
||||
|
||||
// set the initializer if appropriate
|
||||
IrGlobal* glob = vd->ir.irGlobal;
|
||||
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(glob->value);
|
||||
|
||||
// refine the global's opaque type to the type of the initializer
|
||||
llvm::cast<LLOpaqueType>(glob->type.get())->refineAbstractTypeTo(initVal->getType());
|
||||
|
||||
glob->constInit = initVal;
|
||||
|
||||
bool istempl = false;
|
||||
if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) {
|
||||
istempl = true;
|
||||
}
|
||||
|
||||
if (_init && _init->getType() != _type)
|
||||
_type = _init->getType();
|
||||
llvm::cast<LLOpaqueType>(vd->ir.irGlobal->type.get())->refineAbstractTypeTo(_type);
|
||||
_type = vd->ir.irGlobal->type.get();
|
||||
// assign the initializer
|
||||
llvm::GlobalVariable* globalvar = llvm::cast<llvm::GlobalVariable>(glob->value);
|
||||
|
||||
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value);
|
||||
if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
|
||||
{
|
||||
if (Logger::enabled())
|
||||
{
|
||||
Logger::println("setting initializer");
|
||||
Logger::cout() << "global: " << *gvar << '\n';
|
||||
Logger::cout() << "init: " << *_init << '\n';
|
||||
Logger::cout() << "init: " << *initVal << '\n';
|
||||
}
|
||||
gvar->setInitializer(_init);
|
||||
|
||||
gvar->setInitializer(initVal);
|
||||
|
||||
// do debug info
|
||||
if (global.params.symdebug)
|
||||
{
|
||||
|
@ -1040,8 +1035,8 @@ void DtoConstInitGlobal(VarDeclaration* vd)
|
|||
}
|
||||
}
|
||||
|
||||
if (emitRTstaticInit)
|
||||
DtoLazyStaticInit(istempl, gvar, vd->init, t);
|
||||
if (doLazyInit)
|
||||
DtoLazyStaticInit(istempl, gvar, vd->init, vd->type);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1396,18 +1391,18 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var)
|
|||
// INITIALIZER HELPERS
|
||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
LLConstant* DtoConstInitializer(Loc& loc, Type* type, Initializer* init)
|
||||
LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
|
||||
{
|
||||
LLConstant* _init = 0; // may return zero
|
||||
if (!init)
|
||||
{
|
||||
Logger::println("const default initializer for %s", type->toChars());
|
||||
_init = DtoDefaultInit(loc, type);
|
||||
_init = DtoConstExpInit(loc, type, type->defaultInit());
|
||||
}
|
||||
else if (ExpInitializer* ex = init->isExpInitializer())
|
||||
{
|
||||
Logger::println("const expression initializer");
|
||||
_init = ex->exp->toConstElem(gIR);
|
||||
_init = DtoConstExpInit(loc, type, ex->exp);;
|
||||
}
|
||||
else if (StructInitializer* si = init->isStructInitializer())
|
||||
{
|
||||
|
@ -1433,7 +1428,7 @@ LLConstant* DtoConstInitializer(Loc& loc, Type* type, Initializer* init)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLConstant* DtoConstFieldInitializer(Loc& loc, Type* t, Initializer* init)
|
||||
LLConstant* DtoConstFieldInitializer(Loc loc, Type* t, Initializer* init)
|
||||
{
|
||||
Logger::println("DtoConstFieldInitializer");
|
||||
LOG_SCOPE;
|
||||
|
@ -1530,7 +1525,7 @@ DValue* DtoInitializer(LLValue* target, Initializer* init)
|
|||
|
||||
static LLConstant* expand_to_sarray(Type *base, Expression* exp)
|
||||
{
|
||||
Logger::println("building type %s to expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
|
||||
Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
|
||||
const LLType* dstTy = DtoType(base);
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
|
||||
|
@ -1538,12 +1533,25 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp)
|
|||
LLConstant* val = exp->toConstElem(gIR);
|
||||
|
||||
Type* expbase = exp->type->toBasetype();
|
||||
Type* t = base;
|
||||
Logger::println("expbase: %s", expbase->toChars());
|
||||
Type* t = base->toBasetype();
|
||||
|
||||
LLSmallVector<size_t, 4> dims;
|
||||
|
||||
// handle zero initializers
|
||||
if (expbase->isintegral() && exp->isConst())
|
||||
{
|
||||
if (!exp->toInteger())
|
||||
return LLConstant::getNullValue(dstTy);
|
||||
}
|
||||
else if (exp->op == TOKnull)
|
||||
{
|
||||
return LLConstant::getNullValue(dstTy);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
Logger::println("t: %s", t->toChars());
|
||||
if (t->equals(expbase))
|
||||
break;
|
||||
assert(t->ty == Tsarray);
|
||||
|
@ -1568,10 +1576,8 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp)
|
|||
return val;
|
||||
}
|
||||
|
||||
LLConstant* DtoDefaultInit(Loc& loc, Type* type)
|
||||
LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
|
||||
{
|
||||
Expression* exp = type->defaultInit();
|
||||
|
||||
Type* expbase = exp->type->toBasetype();
|
||||
Type* base = type->toBasetype();
|
||||
|
||||
|
@ -1584,7 +1590,6 @@ LLConstant* DtoDefaultInit(Loc& loc, Type* type)
|
|||
error(loc, "static arrays of voids have no default initializer");
|
||||
fatal();
|
||||
}
|
||||
|
||||
Logger::println("type is a static array, building constant array initializer to single value");
|
||||
return expand_to_sarray(base, exp);
|
||||
}
|
||||
|
@ -1594,7 +1599,6 @@ LLConstant* DtoDefaultInit(Loc& loc, Type* type)
|
|||
fatal();
|
||||
}
|
||||
assert(0);
|
||||
|
||||
}
|
||||
|
||||
return exp->toConstElem(gIR);
|
||||
|
@ -1615,6 +1619,7 @@ void DtoAnnotation(const char* str)
|
|||
++p;
|
||||
}
|
||||
// create a noop with the code as the result name!
|
||||
// FIXME: this is const folded and eliminated immediately ... :/
|
||||
gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,9 @@ DValue* DtoDeclarationExp(Dsymbol* declaration);
|
|||
LLValue* DtoRawVarDeclaration(VarDeclaration* var);
|
||||
|
||||
// initializer helpers
|
||||
LLConstant* DtoConstInitializer(Loc& loc, Type* type, Initializer* init);
|
||||
LLConstant* DtoConstFieldInitializer(Loc& loc, Type* type, Initializer* init);
|
||||
LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init);
|
||||
LLConstant* DtoConstFieldInitializer(Loc loc, Type* type, Initializer* init);
|
||||
LLConstant* DtoConstExpInit(Loc loc, Type* t, Expression* exp);
|
||||
DValue* DtoInitializer(LLValue* target, Initializer* init);
|
||||
|
||||
// annotation generator
|
||||
|
@ -108,9 +109,6 @@ DValue* DtoBinRem(Type* resulttype, DValue* lhs, DValue* rhs);
|
|||
// target stuff
|
||||
void findDefaultTarget();
|
||||
|
||||
/// get the default initializer of the type
|
||||
LLConstant* DtoDefaultInit(Loc& loc, Type* t);
|
||||
|
||||
// fixup an overloaded intrinsic name string
|
||||
void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, std::string& name);
|
||||
|
||||
|
|
|
@ -134,8 +134,10 @@ static const LLType* rt_dg2()
|
|||
|
||||
static void LLVM_D_BuildRuntimeModule()
|
||||
{
|
||||
Logger::println("building module");
|
||||
M = new llvm::Module("ldc internal runtime");
|
||||
|
||||
Logger::println("building basic types");
|
||||
const LLType* voidTy = LLType::VoidTy;
|
||||
const LLType* boolTy = LLType::Int1Ty;
|
||||
const LLType* byteTy = LLType::Int8Ty;
|
||||
|
@ -144,6 +146,7 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
const LLType* longTy = LLType::Int64Ty;
|
||||
const LLType* sizeTy = DtoSize_t();
|
||||
|
||||
Logger::println("building float types");
|
||||
const LLType* floatTy = LLType::FloatTy;
|
||||
const LLType* doubleTy = LLType::DoubleTy;
|
||||
const LLType* realTy;
|
||||
|
@ -156,15 +159,22 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
const LLType* cdoubleTy = llvm::StructType::get(doubleTy, doubleTy, NULL);
|
||||
const LLType* crealTy = llvm::StructType::get(realTy, realTy, NULL);
|
||||
|
||||
Logger::println("building aggr types");
|
||||
const LLType* voidPtrTy = rt_ptr(byteTy);
|
||||
const LLType* stringTy = rt_array(byteTy);
|
||||
const LLType* wstringTy = rt_array(shortTy);
|
||||
const LLType* dstringTy = rt_array(intTy);
|
||||
const LLType* objectTy = rt_ptr(ClassDeclaration::object->type->ir.type->get());
|
||||
const LLType* classInfoTy = rt_ptr(ClassDeclaration::classinfo->type->ir.type->get());
|
||||
const LLType* typeInfoTy = rt_ptr(Type::typeinfo->type->ir.type->get());
|
||||
|
||||
Logger::println("building class types");
|
||||
const LLType* objectTy = DtoType(ClassDeclaration::object->type);
|
||||
const LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type);
|
||||
const LLType* typeInfoTy = DtoType(Type::typeinfo->type);
|
||||
|
||||
Logger::println("building aa type");
|
||||
const LLType* aaTy = rt_ptr(llvm::OpaqueType::get());
|
||||
|
||||
Logger::println("building functions");
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -897,7 +897,7 @@ void UnrolledLoopStatement::toIR(IRState* p)
|
|||
DtoDwarfStopPoint(loc.linnum);
|
||||
|
||||
// DMD doesn't fold stuff like continue/break, and since this isn't really a loop
|
||||
// we have to keep track of each statement and jump to next the next/end on continue/break
|
||||
// we have to keep track of each statement and jump to the next/end on continue/break
|
||||
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
|
||||
|
|
681
gen/structs.cpp
681
gen/structs.cpp
|
@ -18,36 +18,279 @@
|
|||
#include "ir/irstruct.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void addZeros(std::vector<llvm::Constant*>& inits, unsigned pos, unsigned offset); // defined in irstruct.cpp
|
||||
|
||||
// pair of var and its init
|
||||
typedef std::pair<VarDeclaration*,Initializer*> VarInitPair;
|
||||
|
||||
// comparison func for qsort
|
||||
static int varinit_offset_cmp_func(const void* p1, const void* p2)
|
||||
{
|
||||
VarDeclaration* v1 = ((VarInitPair*)p1)->first;
|
||||
VarDeclaration* v2 = ((VarInitPair*)p2)->first;
|
||||
if (v1->offset < v2->offset)
|
||||
return -1;
|
||||
else if (v1->offset > v2->offset)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
this uses a simple algorithm to build the correct constant
|
||||
|
||||
(1) first sort the explicit initializers by offset... well, DMD doesn't :)
|
||||
|
||||
(2) if there is NO space before the next explicit initializeer, goto (9)
|
||||
(3) find the next default initializer that fits before it, if NOT found goto (7)
|
||||
(4) insert zero padding up to the next default initializer
|
||||
(5) insert the next default initializer
|
||||
(6) goto (2)
|
||||
|
||||
(7) insert zero padding up to the next explicit initializer
|
||||
|
||||
(9) insert the next explicit initializer
|
||||
(10) goto (2)
|
||||
|
||||
(11) done
|
||||
|
||||
(next can be the end too)
|
||||
|
||||
*/
|
||||
|
||||
// return the next default initializer to use or null
|
||||
static VarDeclaration* nextDefault(IrStruct* irstruct, size_t& idx, size_t pos, size_t offset)
|
||||
{
|
||||
IrStruct::VarDeclVector& defaults = irstruct->defVars;
|
||||
size_t ndefaults = defaults.size();
|
||||
|
||||
// for each valid index
|
||||
while(idx < ndefaults)
|
||||
{
|
||||
VarDeclaration* v = defaults[idx];
|
||||
|
||||
// skip defaults before pos
|
||||
if (v->offset < pos)
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// this var default fits
|
||||
if (v->offset >= pos && v->offset + v->type->size() <= offset)
|
||||
return v;
|
||||
|
||||
// not usable
|
||||
break;
|
||||
}
|
||||
|
||||
// not usable
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLConstant* DtoConstStructInitializer(StructInitializer* si)
|
||||
{
|
||||
Logger::println("DtoConstStructInitializer: %s", si->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// get TypeStruct
|
||||
assert(si->ad);
|
||||
TypeStruct* ts = (TypeStruct*)si->ad->type;
|
||||
|
||||
DtoResolveDsymbol(si->ad);
|
||||
// force constant initialization of the symbol
|
||||
DtoForceConstInitDsymbol(si->ad);
|
||||
|
||||
// get formal type
|
||||
const llvm::StructType* structtype = isaStruct(ts->ir.type->get());
|
||||
|
||||
// log it
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "llvm struct type: " << *structtype << '\n';
|
||||
|
||||
// sanity check
|
||||
assert(si->value.dim > 0);
|
||||
assert(si->value.dim == si->vars.dim);
|
||||
|
||||
std::vector<DUnionIdx> inits;
|
||||
for (int i = 0; i < si->value.dim; ++i)
|
||||
// vector of final initializer constants
|
||||
std::vector<LLConstant*> inits;
|
||||
|
||||
// get the ir struct
|
||||
IrStruct* irstruct = si->ad->ir.irStruct;
|
||||
|
||||
// get default fields
|
||||
IrStruct::VarDeclVector& defaults = irstruct->defVars;
|
||||
size_t ndefaults = defaults.size();
|
||||
|
||||
// make sure si->vars is sorted by offset
|
||||
std::vector<VarInitPair> vars;
|
||||
size_t nvars = si->vars.dim;
|
||||
vars.resize(nvars);
|
||||
|
||||
// fill pair vector
|
||||
for (size_t i = 0; i < nvars; i++)
|
||||
{
|
||||
VarDeclaration* var = (VarDeclaration*)si->vars.data[i];
|
||||
Initializer* ini = (Initializer*)si->value.data[i];
|
||||
assert(var);
|
||||
assert(ini);
|
||||
VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
|
||||
assert(vd);
|
||||
LLConstant* v = DtoConstInitializer(vd->loc, vd->type, ini);
|
||||
inits.push_back(DUnionIdx(vd->ir.irField->index, vd->ir.irField->indexOffset, v));
|
||||
vars[i] = std::make_pair(var, ini);
|
||||
}
|
||||
// sort it
|
||||
qsort(&vars[0], nvars, sizeof(VarInitPair), &varinit_offset_cmp_func);
|
||||
|
||||
// check integrity
|
||||
// and do error checking, since the frontend does verify static struct initializers
|
||||
size_t lastoffset = 0;
|
||||
size_t lastsize = 0;
|
||||
bool overlap = false;
|
||||
for (size_t i=0; i < nvars; i++)
|
||||
{
|
||||
// next explicit init var
|
||||
VarDeclaration* var = vars[i].first;
|
||||
Logger::println("var = %s : +%u", var->toChars(), var->offset);
|
||||
|
||||
// I would have thought this to be a frontend check
|
||||
for (size_t j=i+1; j<nvars; j++)
|
||||
{
|
||||
if (j == i)
|
||||
continue;
|
||||
VarDeclaration* var2 = vars[j].first;
|
||||
if (var2->offset >= var->offset && var2->offset < var->offset + var->type->size())
|
||||
{
|
||||
fprintf(stdmsg, "Error: %s: initializer '%s' overlaps with '%s'\n", si->loc.toChars(), var->toChars(), var2->toChars());
|
||||
overlap = true;
|
||||
}
|
||||
}
|
||||
|
||||
// update offsets
|
||||
lastoffset = var->offset;
|
||||
lastsize = var->type->size();
|
||||
}
|
||||
|
||||
DtoConstInitStruct((StructDeclaration*)si->ad);
|
||||
return si->ad->ir.irStruct->dunion->getConst(inits);
|
||||
// error handling, report all overlaps before aborting
|
||||
if (overlap)
|
||||
{
|
||||
error("%s: overlapping union initializers", si->loc.toChars());
|
||||
}
|
||||
|
||||
// go through each explicit initalizer, falling back to defaults or zeros when necessary
|
||||
lastoffset = 0;
|
||||
lastsize = 0;
|
||||
|
||||
size_t j=0; // defaults
|
||||
|
||||
for (size_t i=0; i < nvars; i++)
|
||||
{
|
||||
// get var and init
|
||||
VarDeclaration* var = vars[i].first;
|
||||
Initializer* ini = vars[i].second;
|
||||
|
||||
size_t offset = var->offset;
|
||||
size_t size = var->type->size();
|
||||
|
||||
// if there is space before the next explicit initializer
|
||||
Lpadding:
|
||||
size_t pos = lastoffset+lastsize;
|
||||
if (offset > pos)
|
||||
{
|
||||
// find the the next default initializer that fits in this space
|
||||
VarDeclaration* nextdef = nextDefault(irstruct, j, lastoffset+lastsize, offset);
|
||||
|
||||
// found
|
||||
if (nextdef)
|
||||
{
|
||||
// need zeros before the default
|
||||
if (nextdef->offset > pos)
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", nextdef->offset - pos, pos);
|
||||
addZeros(inits, pos, nextdef->offset);
|
||||
}
|
||||
|
||||
// do the default
|
||||
Logger::println("adding default field: %s : +%u", nextdef->toChars(), nextdef->offset);
|
||||
LLConstant* c = nextdef->ir.irField->constInit;
|
||||
inits.push_back(c);
|
||||
|
||||
// update offsets
|
||||
lastoffset = nextdef->offset;
|
||||
lastsize = nextdef->type->size();
|
||||
|
||||
// check if more defaults would fit
|
||||
goto Lpadding;
|
||||
}
|
||||
// not found, pad with zeros
|
||||
else
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", offset - pos, pos);
|
||||
addZeros(inits, pos, offset);
|
||||
// offsets are updated by the explicit initializer
|
||||
}
|
||||
}
|
||||
|
||||
// insert next explicit
|
||||
Logger::println("adding explicit field: %s : +%lu", var->toChars(), offset);
|
||||
LOG_SCOPE;
|
||||
LLConstant* c = DtoConstInitializer(var->loc, var->type, ini);
|
||||
inits.push_back(c);
|
||||
|
||||
lastoffset = offset;
|
||||
lastsize = size;
|
||||
}
|
||||
|
||||
// there might still be padding after the last one, make sure that is defaulted/zeroed as well
|
||||
size_t structsize = getABITypeSize(structtype);
|
||||
|
||||
// if there is space before the next explicit initializer
|
||||
// FIXME: this should be handled in the loop above as well
|
||||
Lpadding2:
|
||||
size_t pos = lastoffset+lastsize;
|
||||
if (structsize > pos)
|
||||
{
|
||||
// find the the next default initializer that fits in this space
|
||||
VarDeclaration* nextdef = nextDefault(irstruct, j, lastoffset+lastsize, structsize);
|
||||
|
||||
// found
|
||||
if (nextdef)
|
||||
{
|
||||
// need zeros before the default
|
||||
if (nextdef->offset > pos)
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", nextdef->offset - pos, pos);
|
||||
addZeros(inits, pos, nextdef->offset);
|
||||
}
|
||||
|
||||
// do the default
|
||||
Logger::println("adding default field: %s : +%u", nextdef->toChars(), nextdef->offset);
|
||||
LLConstant* c = nextdef->ir.irField->constInit;
|
||||
inits.push_back(c);
|
||||
|
||||
// update offsets
|
||||
lastoffset = nextdef->offset;
|
||||
lastsize = nextdef->type->size();
|
||||
|
||||
// check if more defaults would fit
|
||||
goto Lpadding2;
|
||||
}
|
||||
// not found, pad with zeros
|
||||
else
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", structsize - pos, pos);
|
||||
addZeros(inits, pos, structsize);
|
||||
lastoffset = pos;
|
||||
lastsize = structsize - pos;
|
||||
}
|
||||
}
|
||||
|
||||
assert(lastoffset+lastsize == structsize);
|
||||
|
||||
// make the constant struct
|
||||
LLConstant* c = LLConstantStruct::get(inits, si->ad->ir.irStruct->packed);
|
||||
if (Logger::enabled())
|
||||
{
|
||||
Logger::cout() << "constant struct initializer: " << *c << '\n';
|
||||
}
|
||||
assert(getABITypeSize(c->getType()) == structsize);
|
||||
return c;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -61,17 +304,26 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
|
|||
IrField* field = vd->ir.irField;
|
||||
assert(field);
|
||||
|
||||
unsigned idx = field->index;
|
||||
unsigned off = field->indexOffset;
|
||||
|
||||
// get the start pointer
|
||||
const LLType* st = getPtrToType(DtoType(sd->type));
|
||||
|
||||
// cast to the formal struct type
|
||||
src = DtoBitCast(src, st);
|
||||
|
||||
LLValue* val = DtoGEPi(src, 0,idx);
|
||||
val = DtoBitCast(val, getPtrToType(DtoType(vd->type)));
|
||||
// gep to the index
|
||||
LLValue* val = DtoGEPi(src, 0, field->index);
|
||||
|
||||
if (off)
|
||||
val = DtoGEPi1(val, off);
|
||||
// do we need to offset further? (union area)
|
||||
if (field->unionOffset)
|
||||
{
|
||||
// cast to void*
|
||||
val = DtoBitCast(val, getVoidPtrType());
|
||||
// offset
|
||||
val = DtoGEPi1(val, field->unionOffset);
|
||||
}
|
||||
|
||||
// cast it to the right type
|
||||
val = DtoBitCast(val, getPtrToType(DtoType(vd->type)));
|
||||
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "value: " << *val << '\n';
|
||||
|
@ -79,46 +331,46 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
|
|||
return val;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoResolveStruct(StructDeclaration* sd)
|
||||
{
|
||||
// don't do anything if already been here
|
||||
if (sd->ir.resolved) return;
|
||||
// make sure above works :P
|
||||
sd->ir.resolved = true;
|
||||
|
||||
Logger::println("DtoResolveStruct(%s): %s", sd->toChars(), sd->loc.toChars());
|
||||
// log what we're doing
|
||||
Logger::println("Resolving struct type: %s (%s)", sd->toChars(), sd->locToChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
TypeStruct* ts = (TypeStruct*)sd->type->toBasetype();
|
||||
// get the DMD TypeStruct
|
||||
TypeStruct* ts = (TypeStruct*)sd->type;
|
||||
|
||||
// this struct is a forward declaration
|
||||
// create the IrStruct
|
||||
IrStruct* irstruct = new IrStruct(sd);
|
||||
sd->ir.irStruct = irstruct;
|
||||
|
||||
// create the type
|
||||
ts->ir.type = new LLPATypeHolder(llvm::OpaqueType::get());
|
||||
|
||||
// handle forward declaration structs (opaques)
|
||||
// didn't even know D had those ...
|
||||
if (sd->sizeok != 1)
|
||||
{
|
||||
sd->ir.irStruct = new IrStruct(ts);
|
||||
ts->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get());
|
||||
// nothing more to do
|
||||
return;
|
||||
}
|
||||
|
||||
bool ispacked = (ts->alignsize() == 1);
|
||||
|
||||
// create the IrStruct
|
||||
IrStruct* irstruct = new IrStruct(ts);
|
||||
sd->ir.irStruct = irstruct;
|
||||
// make this struct current
|
||||
gIR->structs.push_back(irstruct);
|
||||
|
||||
// add fields
|
||||
Array* fields = &sd->fields;
|
||||
for (int k=0; k < fields->dim; k++)
|
||||
{
|
||||
VarDeclaration* v = (VarDeclaration*)fields->data[k];
|
||||
Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars());
|
||||
// init fields, used to happen in VarDeclaration::toObjFile
|
||||
irstruct->addField(v);
|
||||
}
|
||||
// get some info
|
||||
bool ispacked = (ts->alignsize() == 1);
|
||||
bool isunion = sd->isUnionDeclaration();
|
||||
|
||||
// set irstruct info
|
||||
irstruct->packed = ispacked;
|
||||
|
||||
// defined in this module?
|
||||
bool thisModule = false;
|
||||
if (sd->getModule() == gIR->dmodule)
|
||||
thisModule = true;
|
||||
|
@ -127,21 +379,29 @@ void DtoResolveStruct(StructDeclaration* sd)
|
|||
Array* arr = sd->members;
|
||||
for (int k=0; k < arr->dim; k++) {
|
||||
Dsymbol* s = (Dsymbol*)arr->data[k];
|
||||
if (FuncDeclaration* fd = s->isFuncDeclaration()) {
|
||||
if (thisModule || (fd->prot() != PROTprivate)) {
|
||||
fd->toObjFile(0); // TODO: multiobj
|
||||
}
|
||||
}
|
||||
else if (s->isAttribDeclaration() ||
|
||||
s->isVarDeclaration() ||
|
||||
s->isTemplateMixin()) {
|
||||
s->toObjFile(0); // TODO: multiobj
|
||||
}
|
||||
else {
|
||||
Logger::println("Ignoring dsymbol '%s' in this->members of kind '%s'", s->toPrettyChars(), s->kind());
|
||||
}
|
||||
s->toObjFile(0);
|
||||
}
|
||||
|
||||
const LLType* ST = irstruct->build();
|
||||
|
||||
#if 0
|
||||
std::cout << sd->kind() << ' ' << sd->toPrettyChars() << " type: " << *ST << '\n';
|
||||
|
||||
// add fields
|
||||
for (int k=0; k < fields->dim; k++)
|
||||
{
|
||||
VarDeclaration* v = (VarDeclaration*)fields->data[k];
|
||||
printf(" field: %s %s\n", v->type->toChars(), v->toChars());
|
||||
printf(" index: %u offset: %u\n", v->ir.irField->index, v->ir.irField->unionOffset);
|
||||
}
|
||||
|
||||
unsigned llvmSize = (unsigned)getABITypeSize(ST);
|
||||
unsigned dmdSize = (unsigned)sd->type->size();
|
||||
printf(" llvm size: %u dmd size: %u\n", llvmSize, dmdSize);
|
||||
assert(llvmSize == dmdSize);
|
||||
|
||||
#endif
|
||||
|
||||
/*for (int k=0; k < sd->members->dim; k++) {
|
||||
Dsymbol* dsym = (Dsymbol*)(sd->members->data[k]);
|
||||
dsym->toObjFile();
|
||||
|
@ -149,98 +409,13 @@ void DtoResolveStruct(StructDeclaration* sd)
|
|||
|
||||
Logger::println("doing struct fields");
|
||||
|
||||
const llvm::StructType* structtype = 0;
|
||||
std::vector<const LLType*> fieldtypes;
|
||||
|
||||
if (irstruct->offsets.empty())
|
||||
{
|
||||
Logger::println("has no fields");
|
||||
fieldtypes.push_back(LLType::Int8Ty);
|
||||
structtype = llvm::StructType::get(fieldtypes, ispacked);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::println("has fields");
|
||||
unsigned prevsize = (unsigned)-1;
|
||||
unsigned lastoffset = (unsigned)-1;
|
||||
const LLType* fieldtype = NULL;
|
||||
VarDeclaration* fieldinit = NULL;
|
||||
size_t fieldpad = 0;
|
||||
int idx = 0;
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
// first iteration
|
||||
if (lastoffset == (unsigned)-1) {
|
||||
lastoffset = i->first;
|
||||
assert(lastoffset == 0);
|
||||
fieldtype = i->second.type;
|
||||
fieldinit = i->second.var;
|
||||
prevsize = fieldinit->type->size();
|
||||
i->second.var->ir.irField->index = idx;
|
||||
}
|
||||
// colliding offset?
|
||||
else if (lastoffset == i->first) {
|
||||
size_t s = i->second.var->type->size();
|
||||
if (s > prevsize) {
|
||||
fieldpad += s - prevsize;
|
||||
prevsize = s;
|
||||
}
|
||||
sd->ir.irStruct->hasUnions = true;
|
||||
i->second.var->ir.irField->index = idx;
|
||||
}
|
||||
// intersecting offset?
|
||||
else if (i->first < (lastoffset + prevsize)) {
|
||||
size_t s = i->second.var->type->size();
|
||||
assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
|
||||
sd->ir.irStruct->hasUnions = true;
|
||||
i->second.var->ir.irField->index = idx;
|
||||
i->second.var->ir.irField->indexOffset = (i->first - lastoffset) / s;
|
||||
}
|
||||
// fresh offset
|
||||
else {
|
||||
// commit the field
|
||||
fieldtypes.push_back(fieldtype);
|
||||
irstruct->defaultFields.push_back(fieldinit);
|
||||
if (fieldpad) {
|
||||
fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
|
||||
irstruct->defaultFields.push_back(NULL);
|
||||
idx++;
|
||||
}
|
||||
|
||||
idx++;
|
||||
|
||||
// start new
|
||||
lastoffset = i->first;
|
||||
fieldtype = i->second.type;
|
||||
fieldinit = i->second.var;
|
||||
prevsize = fieldinit->type->size();
|
||||
i->second.var->ir.irField->index = idx;
|
||||
fieldpad = 0;
|
||||
}
|
||||
}
|
||||
fieldtypes.push_back(fieldtype);
|
||||
irstruct->defaultFields.push_back(fieldinit);
|
||||
if (fieldpad) {
|
||||
fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
|
||||
irstruct->defaultFields.push_back(NULL);
|
||||
}
|
||||
|
||||
Logger::println("creating struct type");
|
||||
structtype = llvm::StructType::get(fieldtypes, ispacked);
|
||||
}
|
||||
|
||||
// refine abstract types for stuff like: struct S{S* next;}
|
||||
if (irstruct->recty != 0)
|
||||
{
|
||||
llvm::PATypeHolder& pa = irstruct->recty;
|
||||
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(structtype);
|
||||
structtype = isaStruct(pa.get());
|
||||
}
|
||||
|
||||
assert(ts->ir.type == 0);
|
||||
ts->ir.type = new llvm::PATypeHolder(structtype);
|
||||
llvm::cast<llvm::OpaqueType>(ts->ir.type->get())->refineAbstractTypeTo(ST);
|
||||
ST = ts->ir.type->get();
|
||||
|
||||
// name type
|
||||
if (sd->parent->isModule()) {
|
||||
gIR->module->addTypeName(sd->mangle(),structtype);
|
||||
gIR->module->addTypeName(sd->mangle(),ST);
|
||||
}
|
||||
|
||||
gIR->structs.pop_back();
|
||||
|
@ -265,7 +440,7 @@ void DtoDeclareStruct(StructDeclaration* sd)
|
|||
initname.append("6__initZ");
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd);
|
||||
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->ir.type->get(), true, _linkage, NULL, initname, gIR->module);
|
||||
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(sd->ir.irStruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
|
||||
sd->ir.irStruct->init = initvar;
|
||||
|
||||
gIR->constInitList.push_back(sd);
|
||||
|
@ -286,59 +461,33 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
|||
IrStruct* irstruct = sd->ir.irStruct;
|
||||
gIR->structs.push_back(irstruct);
|
||||
|
||||
// make sure each offset knows its default initializer
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
||||
{
|
||||
IrStruct::Offset* so = &i->second;
|
||||
LLConstant* finit = DtoConstFieldInitializer(so->var->loc, so->var->type, so->var->init);
|
||||
so->init = finit;
|
||||
so->var->ir.irField->constInit = finit;
|
||||
}
|
||||
|
||||
const llvm::StructType* structtype = isaStruct(sd->type->ir.type->get());
|
||||
|
||||
// go through the field inits and build the default initializer
|
||||
std::vector<LLConstant*> fieldinits_ll;
|
||||
size_t nfi = irstruct->defaultFields.size();
|
||||
for (size_t i=0; i<nfi; ++i) {
|
||||
LLConstant* c;
|
||||
if (irstruct->defaultFields[i] != NULL) {
|
||||
c = irstruct->defaultFields[i]->ir.irField->constInit;
|
||||
assert(c);
|
||||
}
|
||||
else {
|
||||
const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i));
|
||||
std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
|
||||
c = llvm::ConstantArray::get(arrty, vals);
|
||||
}
|
||||
fieldinits_ll.push_back(c);
|
||||
// make sure each offset knows its default initializer
|
||||
Array* fields = &sd->fields;
|
||||
for (int k=0; k < fields->dim; k++)
|
||||
{
|
||||
VarDeclaration* v = (VarDeclaration*)fields->data[k];
|
||||
LLConstant* finit = DtoConstFieldInitializer(v->loc, v->type, v->init);
|
||||
v->ir.irField->constInit = finit;
|
||||
}
|
||||
|
||||
// generate the union mapper
|
||||
sd->ir.irStruct->dunion = new DUnion(); // uses gIR->topstruct()
|
||||
|
||||
// always generate the constant initalizer
|
||||
if (!sd->zeroInit) {
|
||||
Logger::println("Not zero initialized");
|
||||
#if 0
|
||||
//assert(tk == gIR->gIR->topstruct()().size());
|
||||
#ifndef LLVMD_NO_LOGGER
|
||||
Logger::cout() << "struct type: " << *structtype << '\n';
|
||||
for (size_t k=0; k<fieldinits_ll.size(); ++k) {
|
||||
Logger::cout() << "Type:" << '\n';
|
||||
Logger::cout() << *fieldinits_ll[k]->getType() << '\n';
|
||||
Logger::cout() << "Value:" << '\n';
|
||||
Logger::cout() << *fieldinits_ll[k] << '\n';
|
||||
}
|
||||
Logger::cout() << "Initializer printed" << '\n';
|
||||
#endif
|
||||
#endif
|
||||
sd->ir.irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
|
||||
}
|
||||
else {
|
||||
if (sd->zeroInit)
|
||||
{
|
||||
Logger::println("Zero initialized");
|
||||
sd->ir.irStruct->constInit = llvm::ConstantAggregateZero::get(structtype);
|
||||
irstruct->constInit = llvm::ConstantAggregateZero::get(structtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::println("Not zero initialized");
|
||||
|
||||
LLConstant* c = irstruct->buildDefaultConstInit();
|
||||
irstruct->constInit = c;
|
||||
}
|
||||
|
||||
// refine __initZ global type to the one of the initializer
|
||||
llvm::cast<llvm::OpaqueType>(irstruct->initOpaque.get())->refineAbstractTypeTo(irstruct->constInit->getType());
|
||||
|
||||
gIR->structs.pop_back();
|
||||
|
||||
|
@ -385,163 +534,3 @@ LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs)
|
|||
LLValue* val = DtoMemCmp(lhs->getRVal(), rhs->getRVal(), DtoConstSize_t(sz));
|
||||
return gIR->ir->CreateICmp(cmpop, val, LLConstantInt::get(val->getType(), 0, false), "tmp");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// D UNION HELPER CLASS ////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DUnion::DUnion()
|
||||
{
|
||||
DUnionField* f = NULL;
|
||||
IrStruct* topstruct = gIR->topstruct();
|
||||
bool unions = false;
|
||||
for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
|
||||
{
|
||||
unsigned o = i->first;
|
||||
IrStruct::Offset* so = &i->second;
|
||||
const LLType* ft = so->init->getType();
|
||||
size_t sz = getABITypeSize(ft);
|
||||
if (f == NULL) { // new field
|
||||
fields.push_back(DUnionField());
|
||||
f = &fields.back();
|
||||
f->size = sz;
|
||||
f->offset = o;
|
||||
f->init = so->init;
|
||||
f->initsize = sz;
|
||||
f->types.push_back(ft);
|
||||
}
|
||||
else if (o == f->offset) { // same offset
|
||||
if (sz > f->size)
|
||||
f->size = sz;
|
||||
f->types.push_back(ft);
|
||||
unions = true;
|
||||
}
|
||||
else if (o < f->offset+f->size) {
|
||||
assert((o+sz) <= (f->offset+f->size));
|
||||
unions = true;
|
||||
}
|
||||
else {
|
||||
fields.push_back(DUnionField());
|
||||
f = &fields.back();
|
||||
f->size = sz;
|
||||
f->offset = o;
|
||||
f->init = so->init;
|
||||
f->initsize = sz;
|
||||
f->types.push_back(ft);
|
||||
}
|
||||
}
|
||||
|
||||
ispacked = topstruct->packed;
|
||||
|
||||
/*{
|
||||
LOG_SCOPE;
|
||||
Logger::println("******** DUnion BEGIN");
|
||||
size_t n = fields.size();
|
||||
for (size_t i=0; i<n; ++i) {
|
||||
Logger::cout()<<"field #"<<i<<" offset: "<<fields[i].offset<<" size: "<<fields[i].size<<'('<<fields[i].initsize<<")\n";
|
||||
LOG_SCOPE;
|
||||
size_t nt = fields[i].types.size();
|
||||
for (size_t j=0; j<nt; ++j) {
|
||||
Logger::cout()<<*fields[i].types[j]<<'\n';
|
||||
}
|
||||
}
|
||||
Logger::println("******** DUnion END");
|
||||
}*/
|
||||
}
|
||||
|
||||
static void push_nulls(size_t nbytes, std::vector<LLConstant*>& out)
|
||||
{
|
||||
assert(nbytes > 0);
|
||||
std::vector<LLConstant*> i(nbytes, llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
|
||||
out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(LLType::Int8Ty, nbytes), i));
|
||||
}
|
||||
|
||||
LLConstant* DUnion::getConst(std::vector<DUnionIdx>& in)
|
||||
{
|
||||
std::sort(in.begin(), in.end());
|
||||
std::vector<LLConstant*> out;
|
||||
|
||||
size_t nin = in.size();
|
||||
size_t nfields = fields.size();
|
||||
|
||||
size_t fi = 0;
|
||||
size_t last = 0;
|
||||
size_t ii = 0;
|
||||
size_t os = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if (fi == nfields) break;
|
||||
|
||||
bool nextSame = (ii+1 < nin) && (in[ii+1].idx == fi);
|
||||
|
||||
if (ii < nin && fi == in[ii].idx)
|
||||
{
|
||||
size_t s = getABITypeSize(in[ii].c->getType());
|
||||
if (in[ii].idx == last)
|
||||
{
|
||||
size_t nos = in[ii].idxos * s;
|
||||
if (nos && nos-os) {
|
||||
assert(nos >= os);
|
||||
push_nulls(nos-os, out);
|
||||
}
|
||||
os = nos + s;
|
||||
}
|
||||
else
|
||||
{
|
||||
os = s;
|
||||
}
|
||||
out.push_back(in[ii].c);
|
||||
ii++;
|
||||
if (!nextSame)
|
||||
{
|
||||
if (os < fields[fi].size)
|
||||
push_nulls(fields[fi].size - os, out);
|
||||
os = 0;
|
||||
last = fi++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// default initialize if necessary
|
||||
if (ii == nin || fi < in[ii].idx)
|
||||
{
|
||||
DUnionField& f = fields[fi];
|
||||
out.push_back(f.init);
|
||||
if (f.initsize < f.size)
|
||||
push_nulls(f.size - f.initsize, out);
|
||||
last = fi++;
|
||||
os = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const LLType*> tys;
|
||||
size_t nout = out.size();
|
||||
for (size_t i=0; i<nout; ++i)
|
||||
tys.push_back(out[i]->getType());
|
||||
|
||||
const llvm::StructType* st = llvm::StructType::get(tys, ispacked);
|
||||
return llvm::ConstantStruct::get(st, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -33,43 +33,4 @@ LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs);
|
|||
// index a struct one level
|
||||
LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd);
|
||||
|
||||
struct DUnionField
|
||||
{
|
||||
unsigned offset;
|
||||
size_t size;
|
||||
std::vector<const LLType*> types;
|
||||
LLConstant* init;
|
||||
size_t initsize;
|
||||
|
||||
DUnionField() {
|
||||
offset = 0;
|
||||
size = 0;
|
||||
init = NULL;
|
||||
initsize = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct DUnionIdx
|
||||
{
|
||||
unsigned idx,idxos;
|
||||
LLConstant* c;
|
||||
|
||||
DUnionIdx()
|
||||
: idx(0), c(0) {}
|
||||
DUnionIdx(unsigned _idx, unsigned _idxos, LLConstant* _c)
|
||||
: idx(_idx), idxos(_idxos), c(_c) {}
|
||||
bool operator<(const DUnionIdx& i) const {
|
||||
return (idx < i.idx) || (idx == i.idx && idxos < i.idxos);
|
||||
}
|
||||
};
|
||||
|
||||
class DUnion
|
||||
{
|
||||
std::vector<DUnionField> fields;
|
||||
bool ispacked;
|
||||
public:
|
||||
DUnion();
|
||||
LLConstant* getConst(std::vector<DUnionIdx>& in);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,11 +41,12 @@ unsigned DtoCallingConv(LINK l)
|
|||
{
|
||||
//TODO: StdCall is not a good base on Windows due to extra name mangling
|
||||
// applied there
|
||||
if (global.params.cpu == ARCHx86 && global.params.os != OSWindows)
|
||||
return llvm::CallingConv::X86_StdCall;
|
||||
if (global.params.cpu == ARCHx86)
|
||||
return (global.params.os != OSWindows) ? llvm::CallingConv::X86_StdCall : llvm::CallingConv::C;
|
||||
else
|
||||
return llvm::CallingConv::Fast;
|
||||
}
|
||||
// on the other hand, here, it's exactly what we want!!! TODO: right?
|
||||
else if (l == LINKwindows)
|
||||
return llvm::CallingConv::X86_StdCall;
|
||||
else
|
||||
|
@ -155,7 +156,6 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args, std::vector<llvm::Attribut
|
|||
}
|
||||
|
||||
// build type info array
|
||||
assert(Type::typeinfo->ir.irStruct->constInit);
|
||||
const LLType* typeinfotype = DtoType(Type::typeinfo->type);
|
||||
const LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements());
|
||||
|
||||
|
|
|
@ -452,14 +452,19 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* co
|
|||
definedCU = DtoDwarfCompileUnit(sd->getModule());
|
||||
|
||||
std::vector<LLConstant*> elems;
|
||||
elems.reserve(ir->offsets.size());
|
||||
for (IrStruct::OffsetMap::iterator i=ir->offsets.begin(); i!=ir->offsets.end(); ++i)
|
||||
if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
|
||||
{
|
||||
unsigned offset = i->first;
|
||||
IrStruct::Offset& o = i->second;
|
||||
std::vector<VarDeclaration*>& arr = ir->varDecls;
|
||||
size_t narr = arr.size();
|
||||
elems.reserve(narr);
|
||||
for (int k=0; k<narr; k++)
|
||||
{
|
||||
VarDeclaration* vd = arr[k];
|
||||
assert(vd);
|
||||
|
||||
LLGlobalVariable* ptr = dwarfMemberType(o.var->loc.linnum, o.var->type, compileUnit, definedCU, o.var->toChars(), offset);
|
||||
elems.push_back(DBG_CAST(ptr));
|
||||
LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset);
|
||||
elems.push_back(DBG_CAST(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
const LLArrayType* at = LLArrayType::get(DBG_TYPE, elems.size());
|
||||
|
|
215
gen/toir.cpp
215
gen/toir.cpp
|
@ -135,20 +135,27 @@ DValue* VarExp::toElem(IRState* p)
|
|||
}
|
||||
else {
|
||||
Logger::println("a normal variable");
|
||||
|
||||
// take care of forward references of global variables
|
||||
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
|
||||
vd->toObjFile(0); // TODO: multiobj
|
||||
}
|
||||
if (!vd->ir.isSet() || !vd->ir.getIrValue()) {
|
||||
|
||||
LLValue* val;
|
||||
|
||||
if (!vd->ir.isSet() || !(val = vd->ir.getIrValue())) {
|
||||
error("variable %s not resolved", vd->toChars());
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "unresolved variable had type: " << *DtoType(vd->type) << '\n';
|
||||
fatal();
|
||||
}
|
||||
|
||||
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
|
||||
DtoConstInitGlobal(vd);
|
||||
val = DtoBitCast(val, DtoType(type->pointerTo()));
|
||||
}
|
||||
return new DVarValue(type, vd, vd->ir.getIrValue());
|
||||
|
||||
return new DVarValue(type, vd, val);
|
||||
}
|
||||
}
|
||||
else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
|
||||
|
@ -369,7 +376,7 @@ DValue* StringExp::toElem(IRState* p)
|
|||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module);
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".str",gIR->module);
|
||||
|
||||
llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||
LLConstant* idxs[2] = { zero, zero };
|
||||
|
@ -443,7 +450,7 @@ LLConstant* StringExp::toConstElem(IRState* p)
|
|||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module);
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".str",gIR->module);
|
||||
|
||||
llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||
LLConstant* idxs[2] = { zero, zero };
|
||||
|
@ -1008,19 +1015,21 @@ DValue* DotVarExp::toElem(IRState* p)
|
|||
assert(fdecl->vtblIndex > 0);
|
||||
assert(e1type->ty == Tclass);
|
||||
|
||||
LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
|
||||
LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false);
|
||||
LLValue* zero = DtoConstUint(0);
|
||||
size_t vtblidx = fdecl->vtblIndex;
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "vthis: " << *vthis << '\n';
|
||||
funcval = DtoGEP(vthis, zero, zero);
|
||||
funcval = vthis;
|
||||
if (!fdecl->isMember2()->isInterfaceDeclaration())
|
||||
funcval = DtoGEP(funcval, zero, zero);
|
||||
funcval = DtoLoad(funcval);
|
||||
funcval = DtoGEP(funcval, zero, vtblidx, toChars());
|
||||
Logger::println("vtblidx = %lu", vtblidx);
|
||||
funcval = DtoGEP(funcval, zero, DtoConstUint(vtblidx), toChars());
|
||||
funcval = DtoLoad(funcval);
|
||||
#if OPAQUE_VTBLS
|
||||
|
||||
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "funcval casted: " << *funcval << '\n';
|
||||
#endif
|
||||
}
|
||||
// static call
|
||||
else {
|
||||
|
@ -2143,6 +2152,22 @@ DValue* FuncExp::toElem(IRState* p)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLConstant* FuncExp::toConstElem(IRState* p)
|
||||
{
|
||||
Logger::print("FuncExp::toConstElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(fd);
|
||||
assert(fd->tok == TOKfunction);
|
||||
|
||||
DtoForceDefineDsymbol(fd);
|
||||
assert(fd->ir.irFunc->func);
|
||||
|
||||
return fd->ir.irFunc->func;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* ArrayLiteralExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
|
@ -2252,91 +2277,147 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addZeros(std::vector<llvm::Value*>& inits, unsigned pos, unsigned offset);
|
||||
|
||||
DValue* StructLiteralExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
const LLType* llt = DtoType(type);
|
||||
// get arrays
|
||||
size_t n = elements->dim;
|
||||
Expression** exprs = (Expression**)elements->data;
|
||||
|
||||
LLValue* mem = 0;
|
||||
assert(sd->fields.dim == n);
|
||||
VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
|
||||
|
||||
LLValue* sptr = DtoAlloca(llt,"tmpstructliteral");
|
||||
// vector of values to build aggregate from
|
||||
std::vector<llvm::Value*> values;
|
||||
|
||||
// default init the struct to take care of padding
|
||||
// and unspecified members
|
||||
TypeStruct* ts = (TypeStruct*)type->toBasetype();
|
||||
assert(ts->sym);
|
||||
DtoForceConstInitDsymbol(ts->sym);
|
||||
assert(ts->sym->ir.irStruct->init);
|
||||
DtoAggrCopy(sptr, ts->sym->ir.irStruct->init);
|
||||
// trackers
|
||||
size_t lastoffset = 0;
|
||||
size_t lastsize = 0;
|
||||
|
||||
// num elements in literal
|
||||
unsigned n = elements->dim;
|
||||
|
||||
// unions might have different types for each literal
|
||||
if (sd->ir.irStruct->hasUnions) {
|
||||
// build the type of the literal
|
||||
std::vector<const LLType*> tys;
|
||||
for (unsigned i=0; i<n; ++i) {
|
||||
Expression* vx = (Expression*)elements->data[i];
|
||||
if (!vx) continue;
|
||||
tys.push_back(DtoType(vx->type));
|
||||
}
|
||||
const LLStructType* t = LLStructType::get(tys, sd->ir.irStruct->packed);
|
||||
if (t != llt) {
|
||||
if (getABITypeSize(t) != getABITypeSize(llt)) {
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';
|
||||
assert(0 && "type size mismatch");
|
||||
}
|
||||
sptr = DtoBitCast(sptr, getPtrToType(t));
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "sptr type is now: " << *t << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// build
|
||||
unsigned j = 0;
|
||||
for (unsigned i=0; i<n; ++i)
|
||||
// for through each field and build up the struct, padding with zeros
|
||||
for (size_t i=0; i<n; i++)
|
||||
{
|
||||
Expression* vx = (Expression*)elements->data[i];
|
||||
if (!vx) continue;
|
||||
Expression* e = exprs[i];
|
||||
VarDeclaration* var = vars[i];
|
||||
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "getting index " << j << " of " << *sptr << '\n';
|
||||
LLValue* arrptr = DtoGEPi(sptr,0,j);
|
||||
DValue* darrptr = new DVarValue(vx->type, arrptr);
|
||||
// field is skipped
|
||||
if (!e)
|
||||
continue;
|
||||
|
||||
DValue* ve = vx->toElem(p);
|
||||
DtoAssign(loc, darrptr, ve);
|
||||
// add any 0 padding needed before this field
|
||||
if (var->offset > lastoffset + lastsize)
|
||||
{
|
||||
addZeros(values, lastoffset + lastsize, var->offset);
|
||||
}
|
||||
|
||||
j++;
|
||||
// add the expression value
|
||||
DValue* v = e->toElem(p);
|
||||
values.push_back(v->getRVal());
|
||||
|
||||
// update offsets
|
||||
lastoffset = var->offset;
|
||||
lastsize = var->type->size();
|
||||
}
|
||||
|
||||
return new DImValue(type, sptr);
|
||||
// add any 0 padding needed at the end of the literal
|
||||
const LLType* structtype = DtoType(sd->type);
|
||||
size_t structsize = getABITypeSize(structtype);
|
||||
|
||||
if (structsize > lastoffset+lastsize)
|
||||
{
|
||||
addZeros(values, lastoffset + lastsize, structsize);
|
||||
}
|
||||
|
||||
// get the struct type from the values
|
||||
n = values.size();
|
||||
std::vector<const LLType*> types(n, NULL);
|
||||
|
||||
for (size_t i=0; i<n; i++)
|
||||
{
|
||||
types[i] = values[i]->getType();
|
||||
}
|
||||
|
||||
const LLStructType* sty = LLStructType::get(types, sd->ir.irStruct->packed);
|
||||
|
||||
// allocate storage for the struct literal on the stack
|
||||
LLValue* mem = DtoAlloca(sty, "tmpstructliteral");
|
||||
|
||||
// put all the values into the storage
|
||||
for (size_t i=0; i<n; i++)
|
||||
{
|
||||
LLValue* ptr = DtoGEPi(mem, 0, i);
|
||||
DtoStore(values[i], ptr);
|
||||
}
|
||||
|
||||
// cast the alloca pointer to the "formal" struct type
|
||||
mem = DtoBitCast(mem, getPtrToType(structtype));
|
||||
|
||||
// return as a var
|
||||
return new DVarValue(type, mem);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addZeros(std::vector<llvm::Constant*>& inits, unsigned pos, unsigned offset);
|
||||
|
||||
LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
||||
{
|
||||
Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
unsigned n = elements->dim;
|
||||
std::vector<LLConstant*> vals(n, NULL);
|
||||
// get arrays
|
||||
size_t n = elements->dim;
|
||||
Expression** exprs = (Expression**)elements->data;
|
||||
|
||||
for (unsigned i=0; i<n; ++i)
|
||||
assert(sd->fields.dim == n);
|
||||
VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
|
||||
|
||||
// vector of values to build aggregate from
|
||||
std::vector<llvm::Constant*> values;
|
||||
|
||||
// trackers
|
||||
size_t lastoffset = 0;
|
||||
size_t lastsize = 0;
|
||||
|
||||
// for through each field and build up the struct, padding with zeros
|
||||
for (size_t i=0; i<n; i++)
|
||||
{
|
||||
Expression* vx = (Expression*)elements->data[i];
|
||||
vals[i] = vx->toConstElem(p);
|
||||
Expression* e = exprs[i];
|
||||
VarDeclaration* var = vars[i];
|
||||
|
||||
// field is skipped
|
||||
if (!e)
|
||||
continue;
|
||||
|
||||
// add any 0 padding needed before this field
|
||||
if (var->offset > lastoffset + lastsize)
|
||||
{
|
||||
addZeros(values, lastoffset + lastsize, var->offset);
|
||||
}
|
||||
|
||||
// add the expression value
|
||||
values.push_back(e->toConstElem(p));
|
||||
|
||||
// update offsets
|
||||
lastoffset = var->offset;
|
||||
lastsize = var->type->size();
|
||||
}
|
||||
|
||||
assert(type->toBasetype()->ty == Tstruct);
|
||||
const LLType* t = DtoType(type);
|
||||
const LLStructType* st = isaStruct(t);
|
||||
return llvm::ConstantStruct::get(st,vals);
|
||||
// add any 0 padding needed at the end of the literal
|
||||
const LLType* structtype = DtoType(sd->type);
|
||||
size_t structsize = getABITypeSize(structtype);
|
||||
|
||||
if (structsize > lastoffset+lastsize)
|
||||
{
|
||||
addZeros(values, lastoffset + lastsize, structsize);
|
||||
}
|
||||
|
||||
// return constant struct
|
||||
return LLConstantStruct::get(values, sd->ir.irStruct->packed);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -119,14 +119,14 @@ const LLType* DtoType(Type* t)
|
|||
TypeStruct* ts = (TypeStruct*)t;
|
||||
assert(ts->sym);
|
||||
DtoResolveDsymbol(ts->sym);
|
||||
return ts->sym->ir.irStruct->recty.get(); // t->ir.type->get();
|
||||
return ts->ir.type->get();
|
||||
}
|
||||
|
||||
case Tclass: {
|
||||
TypeClass* tc = (TypeClass*)t;
|
||||
assert(tc->sym);
|
||||
DtoResolveDsymbol(tc->sym);
|
||||
return getPtrToType(tc->sym->ir.irStruct->recty.get()); // t->ir.type->get());
|
||||
return getPtrToType(tc->ir.type->get());
|
||||
}
|
||||
|
||||
// functions
|
||||
|
@ -584,6 +584,13 @@ LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name)
|
|||
return gIR->ir->CreateBitCast(v, t, name ? name : "tmp");
|
||||
}
|
||||
|
||||
LLConstant* DtoBitCast(LLConstant* v, const LLType* t)
|
||||
{
|
||||
if (v->getType() == t)
|
||||
return v;
|
||||
return llvm::ConstantExpr::getBitCast(v, t);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const LLPointerType* isaPointer(LLValue* v)
|
||||
|
@ -695,6 +702,33 @@ unsigned char getPrefTypeAlign(const LLType* t)
|
|||
return gTargetData->getPrefTypeAlignment(t);
|
||||
}
|
||||
|
||||
const LLType* getBiggestType(const LLType** begin, size_t n)
|
||||
{
|
||||
const LLType* bigTy = 0;
|
||||
size_t bigSize = 0;
|
||||
size_t bigAlign = 0;
|
||||
|
||||
const LLType** end = begin+n;
|
||||
while (begin != end)
|
||||
{
|
||||
const LLType* T = *begin;
|
||||
|
||||
size_t sz = getABITypeSize(T);
|
||||
size_t ali = getABITypeAlign(T);
|
||||
if (sz > bigSize || (sz == bigSize && ali > bigAlign))
|
||||
{
|
||||
bigTy = T;
|
||||
bigSize = sz;
|
||||
bigAlign = ali;
|
||||
}
|
||||
|
||||
++begin;
|
||||
}
|
||||
|
||||
// will be null for n==0
|
||||
return bigTy;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const LLStructType* DtoInterfaceInfoType()
|
||||
|
|
|
@ -67,6 +67,7 @@ LLConstant* DtoConstBool(bool);
|
|||
LLValue* DtoLoad(LLValue* src, const char* name=0);
|
||||
void DtoStore(LLValue* src, LLValue* dst);
|
||||
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
|
||||
LLConstant* DtoBitCast(LLConstant* v, const LLType* t);
|
||||
|
||||
// llvm::dyn_cast wrappers
|
||||
const LLPointerType* isaPointer(LLValue* v);
|
||||
|
@ -96,6 +97,9 @@ size_t getABITypeSize(const LLType* t);
|
|||
unsigned char getABITypeAlign(const LLType* t);
|
||||
unsigned char getPrefTypeAlign(const LLType* t);
|
||||
|
||||
// get biggest type, for unions ...
|
||||
const LLType* getBiggestType(const LLType** begin, size_t n);
|
||||
|
||||
// pair type helpers
|
||||
LLValue* DtoAggrPair(const LLType* type, LLValue* V1, LLValue* V2, const char* name = 0);
|
||||
LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name = 0);
|
||||
|
|
|
@ -77,6 +77,8 @@ void Module::genobjfile(int multiobj, char** envp)
|
|||
|
||||
//printf("codegen: %s\n", srcfile->toChars());
|
||||
|
||||
assert(!global.errors);
|
||||
|
||||
// start by deleting the old object file
|
||||
deleteObjFile();
|
||||
|
||||
|
@ -156,16 +158,6 @@ void Module::genobjfile(int multiobj, char** envp)
|
|||
fatal();
|
||||
}
|
||||
|
||||
// start out by providing opaque for the built-in class types
|
||||
if (!ClassDeclaration::object->type->ir.type)
|
||||
ClassDeclaration::object->type->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get());
|
||||
|
||||
if (!Type::typeinfo->type->ir.type)
|
||||
Type::typeinfo->type->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get());
|
||||
|
||||
if (!ClassDeclaration::classinfo->type->ir.type)
|
||||
ClassDeclaration::classinfo->type->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get());
|
||||
|
||||
// process module members
|
||||
for (int k=0; k < members->dim; k++) {
|
||||
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
|
||||
|
@ -638,7 +630,7 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
|
|||
const LLStructType* modulerefTy = DtoModuleReferenceType();
|
||||
std::vector<LLConstant*> mrefvalues;
|
||||
mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0)));
|
||||
mrefvalues.push_back(moduleinfo);
|
||||
mrefvalues.push_back(llvm::ConstantExpr::getBitCast(moduleinfo, modulerefTy->getContainedType(1)));
|
||||
LLConstant* thismrefinit = LLConstantStruct::get(modulerefTy, mrefvalues);
|
||||
|
||||
// create the ModuleReference node for this module
|
||||
|
@ -704,6 +696,13 @@ void Module::genmoduleinfo()
|
|||
assert(moduleinfo);
|
||||
DtoForceConstInitDsymbol(moduleinfo);
|
||||
|
||||
// check for patch
|
||||
if (moduleinfo->ir.irStruct->constInit->getNumOperands() != 11)
|
||||
{
|
||||
error("unpatched object.d detected, ModuleInfo incorrect");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// moduleinfo llvm struct type
|
||||
const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->ir.type->get());
|
||||
|
||||
|
@ -783,9 +782,15 @@ void Module::genmoduleinfo()
|
|||
Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
|
||||
continue;
|
||||
}
|
||||
else if (cd->sizeok != 1)
|
||||
{
|
||||
Logger::println("skipping opaque class declaration '%s' in moduleinfo", cd->toPrettyChars());
|
||||
continue;
|
||||
}
|
||||
Logger::println("class: %s", cd->toPrettyChars());
|
||||
assert(cd->ir.irStruct->classInfo);
|
||||
classInits.push_back(cd->ir.irStruct->classInfo);
|
||||
c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->classInfo, getPtrToType(classinfoTy));
|
||||
classInits.push_back(c);
|
||||
}
|
||||
// has class array?
|
||||
if (!classInits.empty())
|
||||
|
@ -842,7 +847,7 @@ void Module::genmoduleinfo()
|
|||
}*/
|
||||
|
||||
// create initializer
|
||||
LLConstant* constMI = llvm::ConstantStruct::get(moduleinfoTy, initVec);
|
||||
LLConstant* constMI = llvm::ConstantStruct::get(initVec);
|
||||
|
||||
// create name
|
||||
std::string MIname("_D");
|
||||
|
@ -853,7 +858,8 @@ void Module::genmoduleinfo()
|
|||
// flags will be modified at runtime so can't make it constant
|
||||
|
||||
llvm::GlobalVariable* gvar = gIR->module->getGlobalVariable(MIname);
|
||||
if (!gvar) gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module);
|
||||
if (!gvar) gvar = new llvm::GlobalVariable(constMI->getType(), false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module);
|
||||
else assert(gvar->getType()->getContainedType(0) == constMI->getType());
|
||||
gvar->setInitializer(constMI);
|
||||
|
||||
// build the modulereference and ctor for registering it
|
||||
|
@ -988,7 +994,8 @@ void VarDeclaration::toObjFile(int multiobj)
|
|||
#else
|
||||
bool _isconst = isConst();
|
||||
#endif
|
||||
if (parent && parent->isFuncDeclaration())
|
||||
Dsymbol* par = toParent2();
|
||||
if (par && par->isFuncDeclaration())
|
||||
{
|
||||
static_local = true;
|
||||
if (init && init->isExpInitializer()) {
|
||||
|
@ -1015,20 +1022,17 @@ void VarDeclaration::toObjFile(int multiobj)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if DMDV2
|
||||
#if 0
|
||||
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
|
||||
if (!ir.irField)
|
||||
{
|
||||
printf("dataseg: %d\n", isDataseg());
|
||||
printf("parent: %s %s\n", parent->kind(), parent->toPrettyChars());
|
||||
printf("this: %s %s\n", this->kind(), this->toPrettyChars());
|
||||
assert(!ir.isSet());
|
||||
ir.irField = new IrField(this);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
assert(ir.irField != 0);
|
||||
#endif
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
irstruct->addVar(this);
|
||||
|
||||
Logger::println("added offset %u", offset);
|
||||
}
|
||||
Logger::println("VarDeclaration::toObjFile is done");
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
@ -1056,3 +1060,28 @@ void FuncDeclaration::toObjFile(int multiobj)
|
|||
{
|
||||
gIR->resolveList.push_back(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void AnonDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
// get real aggregate parent
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
|
||||
// push a block on the stack
|
||||
irstruct->pushAnon(isunion);
|
||||
|
||||
// go over children
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
s->toObjFile(multiobj);
|
||||
}
|
||||
|
||||
// finish
|
||||
irstruct->popAnon();
|
||||
}
|
||||
}
|
||||
|
|
157
gen/typinf.cpp
157
gen/typinf.cpp
|
@ -379,7 +379,7 @@ void TypeInfoTypedefDeclaration::llvmDeclare()
|
|||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::llvmDefine()
|
||||
|
@ -390,10 +390,6 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
|||
ClassDeclaration* base = Type::typeinfotypedef;
|
||||
DtoForceConstInitDsymbol(base);
|
||||
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "got stype: " << *stype << '\n';
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
|
@ -408,13 +404,11 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
sd->basetype = sd->basetype->merge(); // DMD does this!
|
||||
LLConstant* castbase = DtoTypeInfoOf(sd->basetype, true);
|
||||
assert(castbase->getType() == stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// char[] name
|
||||
char *name = sd->toPrettyChars();
|
||||
sinits.push_back(DtoConstString(name));
|
||||
assert(sinits.back()->getType() == stype->getElementType(3));
|
||||
|
||||
// void[] init
|
||||
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
||||
|
@ -433,9 +427,14 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
|||
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
||||
}
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -453,10 +452,8 @@ void TypeInfoEnumDeclaration::llvmDeclare()
|
|||
ClassDeclaration* base = Type::typeinfoenum;
|
||||
DtoResolveClass(base);
|
||||
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::llvmDefine()
|
||||
|
@ -467,8 +464,6 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
|||
ClassDeclaration* base = Type::typeinfoenum;
|
||||
DtoForceConstInitDsymbol(base);
|
||||
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
|
@ -482,13 +477,11 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
|||
|
||||
// TypeInfo base
|
||||
LLConstant* castbase = DtoTypeInfoOf(sd->memtype, true);
|
||||
assert(castbase->getType() == stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// char[] name
|
||||
char *name = sd->toPrettyChars();
|
||||
sinits.push_back(DtoConstString(name));
|
||||
assert(sinits.back()->getType() == stype->getElementType(3));
|
||||
|
||||
// void[] init
|
||||
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
||||
|
@ -512,9 +505,14 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
|||
#endif
|
||||
}
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -529,10 +527,8 @@ static LLConstant* LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, ClassDe
|
|||
ClassDeclaration* base = cd;
|
||||
DtoResolveClass(base);
|
||||
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
tid->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
||||
tid->ir.irGlobal->value = new llvm::GlobalVariable(tid->ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
||||
}
|
||||
|
||||
static LLConstant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
|
||||
|
@ -540,8 +536,6 @@ static LLConstant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaratio
|
|||
ClassDeclaration* base = cd;
|
||||
DtoForceConstInitDsymbol(base);
|
||||
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
|
@ -551,11 +545,15 @@ static LLConstant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaratio
|
|||
|
||||
// TypeInfo base
|
||||
LLConstant* castbase = DtoTypeInfoOf(basetype, true);
|
||||
assert(castbase->getType() == stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(tid->ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(tid->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
|
@ -628,11 +626,8 @@ void TypeInfoStaticArrayDeclaration::llvmDeclare()
|
|||
ClassDeclaration* base = Type::typeinfostaticarray;
|
||||
DtoResolveClass(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||
|
@ -665,9 +660,14 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
|||
// length
|
||||
sinits.push_back(DtoConstSize_t(tc->dim->toInteger()));
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -686,11 +686,8 @@ void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
|
|||
ClassDeclaration* base = Type::typeinfoassociativearray;
|
||||
DtoResolveClass(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||
|
@ -702,9 +699,6 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
|||
ClassDeclaration* base = Type::typeinfoassociativearray;
|
||||
DtoForceConstInitDsymbol(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
|
@ -719,17 +713,20 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
|||
|
||||
// value typeinfo
|
||||
LLConstant* castbase = DtoTypeInfoOf(tc->next, true);
|
||||
assert(castbase->getType() == stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// key typeinfo
|
||||
castbase = DtoTypeInfoOf(tc->index, true);
|
||||
assert(castbase->getType() == stype->getElementType(3));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -810,10 +807,8 @@ void TypeInfoStructDeclaration::llvmDeclare()
|
|||
ClassDeclaration* base = Type::typeinfostruct;
|
||||
DtoResolveClass(base);
|
||||
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::llvmDefine()
|
||||
|
@ -1001,9 +996,14 @@ void TypeInfoStructDeclaration::llvmDefine()
|
|||
|
||||
#endif
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -1023,11 +1023,8 @@ void TypeInfoClassDeclaration::llvmDeclare()
|
|||
assert(base);
|
||||
DtoResolveClass(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, llvm::GlobalValue::WeakLinkage, NULL, toChars(), gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::llvmDefine()
|
||||
|
@ -1040,9 +1037,6 @@ void TypeInfoClassDeclaration::llvmDefine()
|
|||
assert(base);
|
||||
DtoForceConstInitDsymbol(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
|
@ -1058,9 +1052,14 @@ void TypeInfoClassDeclaration::llvmDefine()
|
|||
assert(tc->sym->ir.irStruct->classInfo);
|
||||
sinits.push_back(tc->sym->ir.irStruct->classInfo);
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -1080,11 +1079,8 @@ void TypeInfoInterfaceDeclaration::llvmDeclare()
|
|||
assert(base);
|
||||
DtoResolveClass(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||
|
@ -1114,9 +1110,14 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
|||
assert(tc->sym->ir.irStruct->classInfo);
|
||||
sinits.push_back(tc->sym->ir.irStruct->classInfo);
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
|
||||
|
@ -1136,11 +1137,8 @@ void TypeInfoTupleDeclaration::llvmDeclare()
|
|||
assert(base);
|
||||
DtoResolveClass(base);
|
||||
|
||||
// get type of typeinfo class
|
||||
const LLStructType* stype = isaStruct(base->type->ir.type->get());
|
||||
|
||||
// create the symbol
|
||||
this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoTupleDeclaration::llvmDefine()
|
||||
|
@ -1199,9 +1197,14 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
|||
LLConstant* slice = DtoConstSlice(DtoConstSize_t(dim), arrptr);
|
||||
sinits.push_back(slice);
|
||||
|
||||
// create the symbol
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(this->ir.irGlobal->value)->setInitializer(tiInit);
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
|
||||
// refine global type
|
||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||
|
||||
// set the initializer
|
||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
|
||||
|
|
335
ir/irstruct.cpp
335
ir/irstruct.cpp
|
@ -3,54 +3,57 @@
|
|||
#include "mtype.h"
|
||||
#include "aggregate.h"
|
||||
#include "declaration.h"
|
||||
#include "init.h"
|
||||
|
||||
#include "ir/irstruct.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/logger.h"
|
||||
|
||||
IrInterface::IrInterface(BaseClass* b)
|
||||
: vtblInitTy(llvm::OpaqueType::get())
|
||||
{
|
||||
base = b;
|
||||
decl = b->base;
|
||||
vtblTy = NULL;
|
||||
vtblInit = NULL;
|
||||
vtbl = NULL;
|
||||
infoTy = NULL;
|
||||
infoInit = NULL;
|
||||
info = NULL;
|
||||
|
||||
index = -1;
|
||||
}
|
||||
|
||||
IrInterface::~IrInterface()
|
||||
{
|
||||
delete vtblTy;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrStruct::IrStruct(Type* t)
|
||||
: recty((t->ir.type) ? *t->ir.type : llvm::OpaqueType::get())
|
||||
IrStruct::IrStruct(AggregateDeclaration* aggr)
|
||||
: initOpaque(llvm::OpaqueType::get()),
|
||||
classInfoOpaque(llvm::OpaqueType::get()),
|
||||
vtblTy(llvm::OpaqueType::get()),
|
||||
vtblInitTy(llvm::OpaqueType::get())
|
||||
{
|
||||
type = t;
|
||||
aggrdecl = aggr;
|
||||
defaultFound = false;
|
||||
anon = NULL;
|
||||
index = 0;
|
||||
|
||||
type = aggr->type;
|
||||
defined = false;
|
||||
constinited = false;
|
||||
interfaceInfosTy = NULL;
|
||||
interfaceInfos = NULL;
|
||||
|
||||
interfaceInfos = NULL;
|
||||
vtbl = NULL;
|
||||
constVtbl = NULL;
|
||||
|
||||
init = NULL;
|
||||
constInit = NULL;
|
||||
|
||||
classInfo = NULL;
|
||||
constClassInfo = NULL;
|
||||
hasUnions = false;
|
||||
dunion = NULL;
|
||||
|
||||
classDeclared = false;
|
||||
classDefined = false;
|
||||
classInfoDeclared = false;
|
||||
classInfoDefined = false;
|
||||
|
||||
packed = false;
|
||||
|
||||
|
@ -61,14 +64,294 @@ IrStruct::~IrStruct()
|
|||
{
|
||||
}
|
||||
|
||||
void IrStruct::addField(VarDeclaration* v)
|
||||
//////////////////////////////////////////
|
||||
|
||||
void IrStruct::pushAnon(bool isunion)
|
||||
{
|
||||
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
|
||||
if (!v->ir.irField)
|
||||
{
|
||||
assert(!v->ir.isSet());
|
||||
v->ir.irField = new IrField(v);
|
||||
}
|
||||
const LLType* _type = DtoType(v->type);
|
||||
offsets.insert(std::make_pair(v->offset, IrStruct::Offset(v, _type)));
|
||||
anon = new Anon(isunion, anon);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
void IrStruct::popAnon()
|
||||
{
|
||||
assert(anon);
|
||||
|
||||
const LLType* BT;
|
||||
|
||||
// get the anon type
|
||||
if (anon->isunion)
|
||||
{
|
||||
// get biggest type in block
|
||||
const LLType* biggest = getBiggestType(&anon->types[0], anon->types.size());
|
||||
std::vector<const LLType*> vec(1, biggest);
|
||||
BT = LLStructType::get(vec, aggrdecl->ir.irStruct->packed);
|
||||
}
|
||||
else
|
||||
{
|
||||
// build a struct from the types
|
||||
BT = LLStructType::get(anon->types, aggrdecl->ir.irStruct->packed);
|
||||
}
|
||||
|
||||
// pop anon
|
||||
Anon* tmp = anon;
|
||||
anon = anon->parent;
|
||||
delete tmp;
|
||||
|
||||
// is there a parent anon?
|
||||
if (anon)
|
||||
{
|
||||
// make sure type gets pushed in the anon, not the main
|
||||
anon->types.push_back(BT);
|
||||
// index is only manipulated at the top level, anons use raw offsets
|
||||
}
|
||||
// no parent anon, finally add to aggrdecl
|
||||
else
|
||||
{
|
||||
types.push_back(BT);
|
||||
// only advance to next position if main is not a union
|
||||
if (!aggrdecl->isUnionDeclaration())
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
void addZeros(std::vector<const llvm::Type*>& inits, size_t pos, size_t offset);
|
||||
|
||||
void IrStruct::addVar(VarDeclaration * var)
|
||||
{
|
||||
TypeVector* tvec = &types;
|
||||
if (anon)
|
||||
{
|
||||
// make sure type gets pushed in the anon, not the main
|
||||
tvec = &anon->types;
|
||||
|
||||
// set but don't advance index
|
||||
var->ir.irField->index = index;
|
||||
|
||||
// set offset in bytes from start of anon block
|
||||
var->ir.irField->unionOffset = var->offset - var->offset2;
|
||||
}
|
||||
else if (aggrdecl->isUnionDeclaration())
|
||||
{
|
||||
// set but don't advance index
|
||||
var->ir.irField->index = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set and advance index
|
||||
var->ir.irField->index = index++;
|
||||
}
|
||||
|
||||
// add type
|
||||
tvec->push_back(DtoType(var->type));
|
||||
|
||||
// add var
|
||||
varDecls.push_back(var);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
const LLType* IrStruct::build()
|
||||
{
|
||||
// if types is empty, add a byte
|
||||
if (types.empty())
|
||||
{
|
||||
types.push_back(LLType::Int8Ty);
|
||||
}
|
||||
|
||||
// union type
|
||||
if (aggrdecl->isUnionDeclaration())
|
||||
{
|
||||
const LLType* biggest = getBiggestType(&types[0], types.size());
|
||||
std::vector<const LLType*> vec(1, biggest);
|
||||
return LLStructType::get(vec, aggrdecl->ir.irStruct->packed);
|
||||
}
|
||||
// struct/class type
|
||||
else
|
||||
{
|
||||
return LLStructType::get(types, aggrdecl->ir.irStruct->packed);
|
||||
}
|
||||
}
|
||||
|
||||
void addZeros(std::vector<const llvm::Type*>& inits, size_t pos, size_t offset)
|
||||
{
|
||||
assert(offset > pos);
|
||||
size_t diff = offset - pos;
|
||||
|
||||
size_t sz;
|
||||
|
||||
do
|
||||
{
|
||||
if (pos%8 == 0 && diff >= 8)
|
||||
sz = 8;
|
||||
else if (pos%4 == 0 && diff >= 4)
|
||||
sz = 4;
|
||||
else if (pos%2 == 0 && diff >= 2)
|
||||
sz = 2;
|
||||
else // if (pos % 1 == 0)
|
||||
sz = 1;
|
||||
inits.push_back(LLIntegerType::get(sz*8));
|
||||
pos += sz;
|
||||
diff -= sz;
|
||||
} while (pos < offset);
|
||||
|
||||
assert(pos == offset);
|
||||
}
|
||||
|
||||
void addZeros(std::vector<llvm::Constant*>& inits, size_t pos, size_t offset)
|
||||
{
|
||||
assert(offset > pos);
|
||||
size_t diff = offset - pos;
|
||||
|
||||
size_t sz;
|
||||
|
||||
do
|
||||
{
|
||||
if (pos%8 == 0 && diff >= 8)
|
||||
sz = 8;
|
||||
else if (pos%4 == 0 && diff >= 4)
|
||||
sz = 4;
|
||||
else if (pos%2 == 0 && diff >= 2)
|
||||
sz = 2;
|
||||
else // if (pos % 1 == 0)
|
||||
sz = 1;
|
||||
inits.push_back(LLConstant::getNullValue(LLIntegerType::get(sz*8)));
|
||||
pos += sz;
|
||||
diff -= sz;
|
||||
} while (pos < offset);
|
||||
|
||||
assert(pos == offset);
|
||||
}
|
||||
|
||||
// FIXME: body is exact copy of above
|
||||
void addZeros(std::vector<llvm::Value*>& inits, size_t pos, size_t offset)
|
||||
{
|
||||
assert(offset > pos);
|
||||
size_t diff = offset - pos;
|
||||
|
||||
size_t sz;
|
||||
|
||||
do
|
||||
{
|
||||
if (pos%8 == 0 && diff >= 8)
|
||||
sz = 8;
|
||||
else if (pos%4 == 0 && diff >= 4)
|
||||
sz = 4;
|
||||
else if (pos%2 == 0 && diff >= 2)
|
||||
sz = 2;
|
||||
else // if (pos % 1 == 0)
|
||||
sz = 1;
|
||||
inits.push_back(LLConstant::getNullValue(LLIntegerType::get(sz*8)));
|
||||
pos += sz;
|
||||
diff -= sz;
|
||||
} while (pos < offset);
|
||||
|
||||
assert(pos == offset);
|
||||
}
|
||||
|
||||
void IrStruct::buildDefaultConstInit(std::vector<llvm::Constant*>& inits)
|
||||
{
|
||||
assert(!defaultFound);
|
||||
defaultFound = true;
|
||||
|
||||
const llvm::StructType* structtype = isaStruct(aggrdecl->type->ir.type->get());
|
||||
Logger::cout() << "struct type: " << *structtype << '\n';
|
||||
|
||||
size_t lastoffset = 0;
|
||||
size_t lastsize = 0;
|
||||
|
||||
{
|
||||
Logger::println("Find the default fields");
|
||||
LOG_SCOPE;
|
||||
|
||||
// go through all vars and find the ones that contribute to the default
|
||||
size_t nvars = varDecls.size();
|
||||
for (size_t i=0; i<nvars; i++)
|
||||
{
|
||||
VarDeclaration* var = varDecls[i];
|
||||
|
||||
Logger::println("field %s %s = %s : +%u", var->type->toChars(), var->toChars(), var->init ? var->init->toChars() : var->type->defaultInit(var->loc)->toChars(), var->offset);
|
||||
|
||||
// only add vars that don't overlap
|
||||
size_t offset = var->offset;
|
||||
size_t size = var->type->size();
|
||||
if (offset >= lastoffset+lastsize)
|
||||
{
|
||||
Logger::println(" added");
|
||||
lastoffset = offset;
|
||||
lastsize = size;
|
||||
defVars.push_back(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Logger::println("Build the default initializer");
|
||||
LOG_SCOPE;
|
||||
|
||||
lastoffset = 0;
|
||||
lastsize = 0;
|
||||
|
||||
// go through the default vars and build the default constant initializer
|
||||
// adding zeros along the way to live up to alignment expectations
|
||||
size_t nvars = defVars.size();
|
||||
for (size_t i=0; i<nvars; i++)
|
||||
{
|
||||
VarDeclaration* var = defVars[i];
|
||||
|
||||
Logger::println("field %s %s = %s : +%u", var->type->toChars(), var->toChars(), var->init ? var->init->toChars() : var->type->defaultInit(var->loc)->toChars(), var->offset);
|
||||
|
||||
// get offset and size
|
||||
size_t offset = var->offset;
|
||||
size_t size = var->type->size();
|
||||
|
||||
// is there space in between last last offset and this one?
|
||||
// if so, fill it with zeros
|
||||
if (offset > lastoffset+lastsize)
|
||||
{
|
||||
size_t pos = lastoffset + lastsize;
|
||||
addZeros(inits, pos, offset);
|
||||
}
|
||||
|
||||
// add the field
|
||||
assert(var->ir.irField->constInit);
|
||||
inits.push_back(var->ir.irField->constInit);
|
||||
|
||||
lastoffset = offset;
|
||||
lastsize = var->type->size();
|
||||
}
|
||||
|
||||
// there might still be padding after the last one, make sure that is zeroed as well
|
||||
// is there space in between last last offset and this one?
|
||||
size_t structsize = getABITypeSize(structtype);
|
||||
|
||||
if (structsize > lastoffset+lastsize)
|
||||
{
|
||||
size_t pos = lastoffset + lastsize;
|
||||
addZeros(inits, pos, structsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLConstant* IrStruct::buildDefaultConstInit()
|
||||
{
|
||||
// doesn't work for classes, they add stuff before and maybe after data fields
|
||||
assert(!aggrdecl->isClassDeclaration());
|
||||
|
||||
// initializer llvm constant list
|
||||
std::vector<LLConstant*> inits;
|
||||
|
||||
// just start with an empty list
|
||||
buildDefaultConstInit(inits);
|
||||
|
||||
// build the constant
|
||||
// note that the type matches the initializer, not the aggregate in cases with unions
|
||||
LLConstant* c = LLConstantStruct::get(inits, aggrdecl->ir.irStruct->packed);
|
||||
Logger::cout() << "llvm constant: " << *c << '\n';
|
||||
// assert(0);
|
||||
return c;
|
||||
}
|
||||
|
|
174
ir/irstruct.h
174
ir/irstruct.h
|
@ -6,86 +6,168 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
struct IrInterface : IrBase
|
||||
{
|
||||
BaseClass* base;
|
||||
ClassDeclaration* decl;
|
||||
|
||||
llvm::PATypeHolder* vtblTy;
|
||||
LLConstant* vtblInit;
|
||||
LLGlobalVariable* vtbl;
|
||||
|
||||
const LLStructType* infoTy;
|
||||
LLConstantStruct* infoInit;
|
||||
LLConstant* info;
|
||||
|
||||
int index;
|
||||
|
||||
IrInterface(BaseClass* b);
|
||||
~IrInterface();
|
||||
};
|
||||
struct IrInterface;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// represents a struct or class
|
||||
// it is used during codegen to hold all the vital info we need
|
||||
struct IrStruct : IrBase
|
||||
{
|
||||
struct Offset
|
||||
{
|
||||
VarDeclaration* var;
|
||||
const LLType* type;
|
||||
LLConstant* init;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
Offset(VarDeclaration* v, const LLType* ty)
|
||||
: var(v), type(ty), init(NULL) {}
|
||||
};
|
||||
|
||||
typedef std::multimap<unsigned, Offset> OffsetMap;
|
||||
typedef std::vector<VarDeclaration*> VarDeclVector;
|
||||
typedef std::map<ClassDeclaration*, IrInterface*> InterfaceMap;
|
||||
typedef InterfaceMap::iterator InterfaceMapIter;
|
||||
|
||||
typedef std::map<ClassDeclaration*, IrInterface*> InterfaceMap;
|
||||
typedef InterfaceMap::iterator InterfaceMapIter;
|
||||
|
||||
typedef std::vector<IrInterface*> InterfaceVector;
|
||||
typedef InterfaceVector::iterator InterfaceVectorIter;
|
||||
|
||||
public:
|
||||
IrStruct(Type*);
|
||||
// vector of LLVM types
|
||||
typedef std::vector<const llvm::Type*> TypeVector;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Anon represents an anonymous struct union block inside an aggregate
|
||||
// during LLVM type construction.
|
||||
struct Anon
|
||||
{
|
||||
bool isunion;
|
||||
Anon* parent;
|
||||
|
||||
TypeVector types;
|
||||
|
||||
Anon(bool IsUnion, Anon* par) : isunion(IsUnion), parent(par) {}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// ctor
|
||||
IrStruct(AggregateDeclaration* agg);
|
||||
|
||||
/// dtor
|
||||
virtual ~IrStruct();
|
||||
|
||||
void addField(VarDeclaration* v);
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// push an anonymous struct/union
|
||||
void pushAnon(bool isunion);
|
||||
|
||||
/// pops an anonymous struct/union
|
||||
void popAnon();
|
||||
|
||||
/// adds field
|
||||
void addVar(VarDeclaration* var);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// build the aggr type
|
||||
const LLType* build();
|
||||
|
||||
/// put the aggr initializers in a vector
|
||||
void buildDefaultConstInit(std::vector<llvm::Constant*>& inits);
|
||||
|
||||
/// ditto - but also builds the constant struct, for convenience
|
||||
LLConstant* buildDefaultConstInit();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the D aggregate
|
||||
AggregateDeclaration* aggrdecl;
|
||||
|
||||
// vector of VarDeclarations in this aggregate
|
||||
VarDeclVector varDecls;
|
||||
|
||||
// vector of VarDeclarations that contribute to the default initializer
|
||||
VarDeclVector defVars;
|
||||
|
||||
// true if the default initializer has been built
|
||||
bool defaultFound;
|
||||
|
||||
// top element
|
||||
Anon* anon;
|
||||
|
||||
// toplevel types in this aggr
|
||||
TypeVector types;
|
||||
|
||||
// current index
|
||||
// always the same as types.size()
|
||||
size_t index;
|
||||
|
||||
// aggregate D type
|
||||
Type* type;
|
||||
llvm::PATypeHolder recty;
|
||||
OffsetMap offsets;
|
||||
VarDeclVector defaultFields;
|
||||
|
||||
// class vtable type
|
||||
llvm::PATypeHolder vtblTy;
|
||||
llvm::PATypeHolder vtblInitTy;
|
||||
|
||||
// initializer type opaque (type of global matches initializer, not formal type)
|
||||
llvm::PATypeHolder initOpaque;
|
||||
llvm::PATypeHolder classInfoOpaque;
|
||||
|
||||
// map/vector of interfaces implemented
|
||||
InterfaceMap interfaceMap;
|
||||
InterfaceVector interfaceVec;
|
||||
const llvm::ArrayType* interfaceInfosTy;
|
||||
|
||||
// interface info array global
|
||||
LLGlobalVariable* interfaceInfos;
|
||||
|
||||
// ...
|
||||
bool defined;
|
||||
bool constinited;
|
||||
|
||||
// vtbl global and initializer
|
||||
LLGlobalVariable* vtbl;
|
||||
#if OPAQUE_VTBLS
|
||||
LLConstant* constVtbl;
|
||||
#else
|
||||
LLConstantStruct* constVtbl;
|
||||
#endif
|
||||
|
||||
// static initializers global and constant
|
||||
LLGlobalVariable* init;
|
||||
LLConstant* constInit;
|
||||
|
||||
// classinfo global and initializer constant
|
||||
LLGlobalVariable* classInfo;
|
||||
LLConstant* constClassInfo;
|
||||
bool hasUnions;
|
||||
DUnion* dunion;
|
||||
bool classDeclared;
|
||||
bool classDefined;
|
||||
bool classInfoDeclared;
|
||||
bool classInfoDefined;
|
||||
|
||||
bool packed; // true for: align(1) struct S { ... }
|
||||
// align(1) struct S { ... }
|
||||
bool packed;
|
||||
|
||||
// dwarf composite global
|
||||
LLGlobalVariable* dwarfComposite;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// represents interface implemented by a class
|
||||
struct IrInterface : IrBase
|
||||
{
|
||||
BaseClass* base;
|
||||
ClassDeclaration* decl;
|
||||
|
||||
llvm::PATypeHolder vtblInitTy;
|
||||
|
||||
LLConstant* vtblInit;
|
||||
LLGlobalVariable* vtbl;
|
||||
|
||||
const LLStructType* infoTy;
|
||||
LLConstant* infoInit;
|
||||
LLConstant* info;
|
||||
|
||||
size_t index;
|
||||
|
||||
IrInterface(BaseClass* b);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,9 +21,6 @@ IrType::IrType(const IrType& s)
|
|||
{
|
||||
assert(list.insert(this).second);
|
||||
type = s.type;
|
||||
#if OPAQUE_VTBLS
|
||||
vtblType = s.type;
|
||||
#endif
|
||||
}
|
||||
|
||||
IrType::~IrType()
|
||||
|
@ -34,7 +31,4 @@ IrType::~IrType()
|
|||
void IrType::reset()
|
||||
{
|
||||
type = NULL;
|
||||
#if OPAQUE_VTBLS
|
||||
vtblType = NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ struct IrType
|
|||
void reset();
|
||||
|
||||
llvm::PATypeHolder* type;
|
||||
llvm::PATypeHolder* vtblType;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "llvm/DerivedTypes.h"
|
||||
#include "gen/llvm.h"
|
||||
#include "declaration.h"
|
||||
#include "ir/irvar.h"
|
||||
|
||||
|
@ -38,8 +38,8 @@ IrLocal::IrLocal(VarDeclaration* v) : IrVar(v)
|
|||
|
||||
IrField::IrField(VarDeclaration* v) : IrVar(v)
|
||||
{
|
||||
index = -1;
|
||||
indexOffset = 0;
|
||||
index = 0;
|
||||
unionOffset = 0;
|
||||
constInit = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,9 @@ struct IrField : IrVar
|
|||
{
|
||||
IrField(VarDeclaration* v);
|
||||
|
||||
int index;
|
||||
size_t indexOffset;
|
||||
unsigned index;
|
||||
unsigned unionOffset;
|
||||
|
||||
llvm::Constant* constInit;
|
||||
};
|
||||
|
||||
|
|
684
llvmdc.kdevelop
684
llvmdc.kdevelop
|
@ -1,684 +0,0 @@
|
|||
<?xml version = '1.0'?>
|
||||
<kdevelop>
|
||||
<general>
|
||||
<author>Tomas Lindquist Olsen</author>
|
||||
<email>tomas.l.olsen@gmail.com</email>
|
||||
<version>0.1</version>
|
||||
<projectmanagement>KDevCustomProject</projectmanagement>
|
||||
<primarylanguage>C++</primarylanguage>
|
||||
<keywords>
|
||||
<keyword>C++</keyword>
|
||||
<keyword>Code</keyword>
|
||||
</keywords>
|
||||
<ignoreparts/>
|
||||
<projectname>llvmdc</projectname>
|
||||
<projectdirectory>.</projectdirectory>
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description/>
|
||||
<defaultencoding/>
|
||||
<versioncontrol>kdevsubversion</versioncontrol>
|
||||
</general>
|
||||
<kdevautoproject>
|
||||
<general/>
|
||||
<run/>
|
||||
<configurations>
|
||||
<optimized>
|
||||
<builddir>optimized</builddir>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevg77options</f77compiler>
|
||||
<cxxflags>-O2 -g0</cxxflags>
|
||||
</optimized>
|
||||
<debug>
|
||||
<configargs>--enable-debug=full</configargs>
|
||||
<builddir>debug</builddir>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevg77options</f77compiler>
|
||||
<cxxflags>-O0 -g3</cxxflags>
|
||||
</debug>
|
||||
</configurations>
|
||||
</kdevautoproject>
|
||||
<kdevdoctreeview>
|
||||
<ignoretocs>
|
||||
<toc>ada</toc>
|
||||
<toc>ada_bugs_gcc</toc>
|
||||
<toc>bash</toc>
|
||||
<toc>bash_bugs</toc>
|
||||
<toc>clanlib</toc>
|
||||
<toc>w3c-dom-level2-html</toc>
|
||||
<toc>fortran_bugs_gcc</toc>
|
||||
<toc>gnome1</toc>
|
||||
<toc>gnustep</toc>
|
||||
<toc>gtk</toc>
|
||||
<toc>gtk_bugs</toc>
|
||||
<toc>haskell</toc>
|
||||
<toc>haskell_bugs_ghc</toc>
|
||||
<toc>java_bugs_gcc</toc>
|
||||
<toc>java_bugs_sun</toc>
|
||||
<toc>kde2book</toc>
|
||||
<toc>opengl</toc>
|
||||
<toc>pascal_bugs_fp</toc>
|
||||
<toc>php</toc>
|
||||
<toc>php_bugs</toc>
|
||||
<toc>perl</toc>
|
||||
<toc>perl_bugs</toc>
|
||||
<toc>python</toc>
|
||||
<toc>python_bugs</toc>
|
||||
<toc>qt-kdev3</toc>
|
||||
<toc>ruby</toc>
|
||||
<toc>ruby_bugs</toc>
|
||||
<toc>sdl</toc>
|
||||
<toc>w3c-svg</toc>
|
||||
<toc>sw</toc>
|
||||
<toc>w3c-uaag10</toc>
|
||||
<toc>wxwidgets_bugs</toc>
|
||||
</ignoretocs>
|
||||
<ignoreqt_xml>
|
||||
<toc>Guide to the Qt Translation Tools</toc>
|
||||
<toc>Qt Assistant Manual</toc>
|
||||
<toc>Qt Designer Manual</toc>
|
||||
<toc>Qt Reference Documentation</toc>
|
||||
<toc>qmake User Guide</toc>
|
||||
</ignoreqt_xml>
|
||||
<ignoredoxygen>
|
||||
<toc>KDE Libraries (Doxygen)</toc>
|
||||
</ignoredoxygen>
|
||||
</kdevdoctreeview>
|
||||
<kdevfilecreate>
|
||||
<filetypes/>
|
||||
<useglobaltypes>
|
||||
<type ext="cpp" />
|
||||
<type ext="h" />
|
||||
</useglobaltypes>
|
||||
</kdevfilecreate>
|
||||
<kdevfileview>
|
||||
<groups>
|
||||
<group pattern="*.h" name="Header files" />
|
||||
<group pattern="*.cpp" name="Source files" />
|
||||
<hidenonprojectfiles>true</hidenonprojectfiles>
|
||||
<hidenonlocation>false</hidenonlocation>
|
||||
</groups>
|
||||
<tree>
|
||||
<hidepatterns>*.bc</hidepatterns>
|
||||
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||
<showvcsfields>false</showvcsfields>
|
||||
</tree>
|
||||
</kdevfileview>
|
||||
<kdevdocumentation>
|
||||
<projectdoc>
|
||||
<docsystem>Doxygen Documentation Collection</docsystem>
|
||||
<docurl>llvmdc.tag</docurl>
|
||||
</projectdoc>
|
||||
</kdevdocumentation>
|
||||
<substmap>
|
||||
<APPNAME>llvmdc</APPNAME>
|
||||
<APPNAMELC>llvmdc</APPNAMELC>
|
||||
<APPNAMESC>Llvmdc</APPNAMESC>
|
||||
<APPNAMEUC>LLVMDC</APPNAMEUC>
|
||||
<AUTHOR>Tomas Lindquist Olsen</AUTHOR>
|
||||
<EMAIL>tomas.l.olsen@gmail.com</EMAIL>
|
||||
<LICENSE>GPL</LICENSE>
|
||||
<LICENSEFILE>COPYING</LICENSEFILE>
|
||||
<VERSION>0.1</VERSION>
|
||||
<YEAR>2007</YEAR>
|
||||
<dest>/home/tomas/projects/llvmdc</dest>
|
||||
</substmap>
|
||||
<kdevcppsupport>
|
||||
<qt>
|
||||
<used>false</used>
|
||||
<version>3</version>
|
||||
<includestyle>3</includestyle>
|
||||
<root>/opt/qt</root>
|
||||
<designerintegration>EmbeddedKDevDesigner</designerintegration>
|
||||
<qmake>/opt/qt/bin/qmake</qmake>
|
||||
<designer>/opt/qt/bin/designer</designer>
|
||||
<designerpluginpaths/>
|
||||
</qt>
|
||||
<codecompletion>
|
||||
<automaticCodeCompletion>false</automaticCodeCompletion>
|
||||
<automaticArgumentsHint>true</automaticArgumentsHint>
|
||||
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
||||
<codeCompletionDelay>250</codeCompletionDelay>
|
||||
<argumentsHintDelay>400</argumentsHintDelay>
|
||||
<headerCompletionDelay>250</headerCompletionDelay>
|
||||
<showOnlyAccessibleItems>false</showOnlyAccessibleItems>
|
||||
<completionBoxItemOrder>0</completionBoxItemOrder>
|
||||
<howEvaluationContextMenu>true</howEvaluationContextMenu>
|
||||
<showCommentWithArgumentHint>true</showCommentWithArgumentHint>
|
||||
<statusBarTypeEvaluation>false</statusBarTypeEvaluation>
|
||||
<namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
|
||||
<processPrimaryTypes>true</processPrimaryTypes>
|
||||
<processFunctionArguments>false</processFunctionArguments>
|
||||
<preProcessAllHeaders>true</preProcessAllHeaders>
|
||||
<parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
|
||||
<resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
|
||||
<alwaysParseInBackground>true</alwaysParseInBackground>
|
||||
<usePermanentCaching>true</usePermanentCaching>
|
||||
<alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
|
||||
<includePaths>.;</includePaths>
|
||||
</codecompletion>
|
||||
<creategettersetter>
|
||||
<prefixGet/>
|
||||
<prefixSet>set</prefixSet>
|
||||
<prefixVariable>m_,_</prefixVariable>
|
||||
<parameterName>theValue</parameterName>
|
||||
<inlineGet>true</inlineGet>
|
||||
<inlineSet>true</inlineSet>
|
||||
</creategettersetter>
|
||||
<splitheadersource>
|
||||
<enabled>false</enabled>
|
||||
<synchronize>true</synchronize>
|
||||
<orientation>Vertical</orientation>
|
||||
</splitheadersource>
|
||||
<references/>
|
||||
</kdevcppsupport>
|
||||
<kdevcustomproject>
|
||||
<run>
|
||||
<directoryradio>executable</directoryradio>
|
||||
<mainprogram>/home/tomas/kdevprojects/llvmdc</mainprogram>
|
||||
<programargs/>
|
||||
<globaldebugarguments/>
|
||||
<globalcwd>/home/tomas/kdevprojects/llvmdc</globalcwd>
|
||||
<useglobalprogram>false</useglobalprogram>
|
||||
<terminal>false</terminal>
|
||||
<autocompile>false</autocompile>
|
||||
<autoinstall>false</autoinstall>
|
||||
<autokdesu>false</autokdesu>
|
||||
<envvars/>
|
||||
</run>
|
||||
<filetypes>
|
||||
<filetype>*.h</filetype>
|
||||
<filetype>*.c</filetype>
|
||||
<filetype>*.cpp</filetype>
|
||||
<filetype>build.sh</filetype>
|
||||
</filetypes>
|
||||
<blacklist>
|
||||
<path>demos</path>
|
||||
<path>demos/ray.cpp</path>
|
||||
<path>dmdorig</path>
|
||||
<path>dmdorig/dmd</path>
|
||||
<path>dmdorig/dmd/access.c</path>
|
||||
<path>dmdorig/dmd/aggregate.h</path>
|
||||
<path>dmdorig/dmd/array.c</path>
|
||||
<path>dmdorig/dmd/arraytypes.h</path>
|
||||
<path>dmdorig/dmd/attrib.c</path>
|
||||
<path>dmdorig/dmd/attrib.h</path>
|
||||
<path>dmdorig/dmd/bit.c</path>
|
||||
<path>dmdorig/dmd/cast.c</path>
|
||||
<path>dmdorig/dmd/class.c</path>
|
||||
<path>dmdorig/dmd/complex_t.h</path>
|
||||
<path>dmdorig/dmd/cond.c</path>
|
||||
<path>dmdorig/dmd/cond.h</path>
|
||||
<path>dmdorig/dmd/constfold.c</path>
|
||||
<path>dmdorig/dmd/dchar.c</path>
|
||||
<path>dmdorig/dmd/dchar.h</path>
|
||||
<path>dmdorig/dmd/declaration.c</path>
|
||||
<path>dmdorig/dmd/declaration.h</path>
|
||||
<path>dmdorig/dmd/delegatize.c</path>
|
||||
<path>dmdorig/dmd/doc.c</path>
|
||||
<path>dmdorig/dmd/doc.h</path>
|
||||
<path>dmdorig/dmd/dsymbol.c</path>
|
||||
<path>dmdorig/dmd/dsymbol.h</path>
|
||||
<path>dmdorig/dmd/dump.c</path>
|
||||
<path>dmdorig/dmd/entity.c</path>
|
||||
<path>dmdorig/dmd/enum.c</path>
|
||||
<path>dmdorig/dmd/enum.h</path>
|
||||
<path>dmdorig/dmd/expression.c</path>
|
||||
<path>dmdorig/dmd/expression.h</path>
|
||||
<path>dmdorig/dmd/func.c</path>
|
||||
<path>dmdorig/dmd/gnuc.c</path>
|
||||
<path>dmdorig/dmd/gnuc.h</path>
|
||||
<path>dmdorig/dmd/hdrgen.c</path>
|
||||
<path>dmdorig/dmd/hdrgen.h</path>
|
||||
<path>dmdorig/dmd/html.c</path>
|
||||
<path>dmdorig/dmd/html.h</path>
|
||||
<path>dmdorig/dmd/identifier.c</path>
|
||||
<path>dmdorig/dmd/identifier.h</path>
|
||||
<path>dmdorig/dmd/idgen.c</path>
|
||||
<path>dmdorig/dmd/impcnvgen.c</path>
|
||||
<path>dmdorig/dmd/import.c</path>
|
||||
<path>dmdorig/dmd/import.h</path>
|
||||
<path>dmdorig/dmd/inifile.c</path>
|
||||
<path>dmdorig/dmd/init.c</path>
|
||||
<path>dmdorig/dmd/init.h</path>
|
||||
<path>dmdorig/dmd/inline.c</path>
|
||||
<path>dmdorig/dmd/interpret.c</path>
|
||||
<path>dmdorig/dmd/lexer.c</path>
|
||||
<path>dmdorig/dmd/lexer.h</path>
|
||||
<path>dmdorig/dmd/link.c</path>
|
||||
<path>dmdorig/dmd/lstring.c</path>
|
||||
<path>dmdorig/dmd/lstring.h</path>
|
||||
<path>dmdorig/dmd/macro.c</path>
|
||||
<path>dmdorig/dmd/macro.h</path>
|
||||
<path>dmdorig/dmd/mangle.c</path>
|
||||
<path>dmdorig/dmd/mars.c</path>
|
||||
<path>dmdorig/dmd/mars.h</path>
|
||||
<path>dmdorig/dmd/mem.c</path>
|
||||
<path>dmdorig/dmd/mem.h</path>
|
||||
<path>dmdorig/dmd/module.c</path>
|
||||
<path>dmdorig/dmd/module.h</path>
|
||||
<path>dmdorig/dmd/mtype.c</path>
|
||||
<path>dmdorig/dmd/mtype.h</path>
|
||||
<path>dmdorig/dmd/opover.c</path>
|
||||
<path>dmdorig/dmd/optimize.c</path>
|
||||
<path>dmdorig/dmd/parse.c</path>
|
||||
<path>dmdorig/dmd/parse.h</path>
|
||||
<path>dmdorig/dmd/port.h</path>
|
||||
<path>dmdorig/dmd/root.c</path>
|
||||
<path>dmdorig/dmd/root.h</path>
|
||||
<path>dmdorig/dmd/scope.c</path>
|
||||
<path>dmdorig/dmd/scope.h</path>
|
||||
<path>dmdorig/dmd/statement.c</path>
|
||||
<path>dmdorig/dmd/statement.h</path>
|
||||
<path>dmdorig/dmd/staticassert.c</path>
|
||||
<path>dmdorig/dmd/staticassert.h</path>
|
||||
<path>dmdorig/dmd/stringtable.c</path>
|
||||
<path>dmdorig/dmd/stringtable.h</path>
|
||||
<path>dmdorig/dmd/struct.c</path>
|
||||
<path>dmdorig/dmd/template.c</path>
|
||||
<path>dmdorig/dmd/template.h</path>
|
||||
<path>dmdorig/dmd/tocsym.c</path>
|
||||
<path>dmdorig/dmd/todt.c</path>
|
||||
<path>dmdorig/dmd/toir.c</path>
|
||||
<path>dmdorig/dmd/toir.h</path>
|
||||
<path>dmdorig/dmd/toobj.c</path>
|
||||
<path>dmdorig/dmd/total.h</path>
|
||||
<path>dmdorig/dmd/typinf.c</path>
|
||||
<path>dmdorig/dmd/unialpha.c</path>
|
||||
<path>dmdorig/dmd/utf.c</path>
|
||||
<path>dmdorig/dmd/utf.h</path>
|
||||
<path>dmdorig/dmd/version.c</path>
|
||||
<path>dmdorig/dmd/version.h</path>
|
||||
<path>dmdorig/phobos</path>
|
||||
<path>dmdorig/phobos/errno.c</path>
|
||||
<path>dmdorig/phobos/etc</path>
|
||||
<path>dmdorig/phobos/etc/c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/adler32.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/compress.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/crc32.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/crc32.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/deflate.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/deflate.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/example.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/gzio.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/infback.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inffast.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inffast.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inffixed.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inflate.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inflate.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inftrees.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/inftrees.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/minigzip.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/trees.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/trees.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/uncompr.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/zconf.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/zconf.in.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/zlib.h</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/zutil.c</path>
|
||||
<path>dmdorig/phobos/etc/c/zlib/zutil.h</path>
|
||||
<path>dmdorig/phobos/internal</path>
|
||||
<path>dmdorig/phobos/internal/complex.c</path>
|
||||
<path>dmdorig/phobos/internal/critical.c</path>
|
||||
<path>dmdorig/phobos/internal/deh.c</path>
|
||||
<path>dmdorig/phobos/internal/mars.h</path>
|
||||
<path>dmdorig/phobos/internal/monitor.c</path>
|
||||
<path>lphobos</path>
|
||||
<path>lphobos/build.sh</path>
|
||||
<path>suite</path>
|
||||
<path>suite/dwarfdebug</path>
|
||||
<path>suite/dwarfdebug/dwarf1</path>
|
||||
<path>suite/dwarfdebug/dwarf1/build.sh</path>
|
||||
<path>suite/dwarfdebug/dwarf2</path>
|
||||
<path>suite/dwarfdebug/dwarf2/build.sh</path>
|
||||
<path>tango</path>
|
||||
<path>tango/lib</path>
|
||||
<path>tango/lib/common</path>
|
||||
<path>tango/lib/common/tango</path>
|
||||
<path>tango/lib/common/tango/stdc</path>
|
||||
<path>tango/lib/common/tango/stdc/wrap.c</path>
|
||||
<path>tango/lib/compiler</path>
|
||||
<path>tango/lib/compiler/llvmdc</path>
|
||||
<path>tango/lib/compiler/llvmdc/critical.c</path>
|
||||
<path>tango/lib/compiler/llvmdc/mars.h</path>
|
||||
<path>tango/lib/compiler/llvmdc/monitor.c</path>
|
||||
<path>tests</path>
|
||||
<path>tests/dstress</path>
|
||||
<path>tests/dstress/benchmark</path>
|
||||
<path>tests/dstress/benchmark/ackermann</path>
|
||||
<path>tests/dstress/benchmark/ackermann/ackermann_c.c</path>
|
||||
<path>tests/dstress/benchmark/cowell-shah</path>
|
||||
<path>tests/dstress/benchmark/cowell-shah/benchmark.c</path>
|
||||
<path>tests/dstress/benchmark/known_gcc_problems</path>
|
||||
<path>tests/dstress/benchmark/known_gcc_problems/common_subexpressions_01_c.c</path>
|
||||
<path>tests/dstress/benchmark/oopack</path>
|
||||
<path>tests/dstress/benchmark/oopack/oopack_v1p8_cpp.cpp</path>
|
||||
<path>tests/dstress/crashRun.c</path>
|
||||
<path>tests/dstress/dstress.c</path>
|
||||
<path>tests/dstress/extract__.c</path>
|
||||
<path>tests/dstress/ifeq__.c</path>
|
||||
<path>tests/dstress/return__.c</path>
|
||||
<path>e2ir.c</path>
|
||||
<path>tango-llvmdc</path>
|
||||
<path>tango-llvmdc/lib</path>
|
||||
<path>tango-llvmdc/lib/common</path>
|
||||
<path>tango-llvmdc/lib/common/tango</path>
|
||||
<path>tango-llvmdc/lib/common/tango/stdc</path>
|
||||
<path>tango-llvmdc/lib/common/tango/stdc/wrap.c</path>
|
||||
<path>tango-llvmdc/lib/compiler</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/complex.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/critical.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/deh.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/mars.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/monitor.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/gen_config1.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/gen_math.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/gen_unix.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/makestruct.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/critical.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/deh.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/aix_float.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_fdset.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_math.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_stdio.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_time.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/mars.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/memory_dyld.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/memory_freebsd.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/monitor.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc/critical.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc/mars.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc/monitor.c</path>
|
||||
<path>tango-llvmdc/patches</path>
|
||||
<path>tango-llvmdc/patches/proposals</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/dmd</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/dmd/monitor.c</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc/monitor.c</path>
|
||||
<path>runtime/build.sh</path>
|
||||
<path>runtime/internal</path>
|
||||
<path>runtime/internal/critical.c</path>
|
||||
<path>runtime/internal/mars.h</path>
|
||||
<path>runtime/internal/monitor.c</path>
|
||||
<path>build</path>
|
||||
<path>build/CMakeFiles</path>
|
||||
<path>build/CMakeFiles/CompilerIdC</path>
|
||||
<path>build/CMakeFiles/CompilerIdC/CMakeCCompilerId.c</path>
|
||||
<path>build/CMakeFiles/CompilerIdCXX</path>
|
||||
<path>build/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp</path>
|
||||
<path>build/dmd</path>
|
||||
<path>build/dmd/id.c</path>
|
||||
<path>build/dmd/id.h</path>
|
||||
<path>build/dmd/impcnvtab.c</path>
|
||||
<path>dmd2.020</path>
|
||||
<path>dmd2.020/access.c</path>
|
||||
<path>dmd2.020/aggregate.h</path>
|
||||
<path>dmd2.020/array.c</path>
|
||||
<path>dmd2.020/arrayop.c</path>
|
||||
<path>dmd2.020/arraytypes.h</path>
|
||||
<path>dmd2.020/attrib.c</path>
|
||||
<path>dmd2.020/attrib.h</path>
|
||||
<path>dmd2.020/bit.c</path>
|
||||
<path>dmd2.020/builtin.c</path>
|
||||
<path>dmd2.020/cast.c</path>
|
||||
<path>dmd2.020/class.c</path>
|
||||
<path>dmd2.020/clone.c</path>
|
||||
<path>dmd2.020/complex_t.h</path>
|
||||
<path>dmd2.020/cond.c</path>
|
||||
<path>dmd2.020/cond.h</path>
|
||||
<path>dmd2.020/constfold.c</path>
|
||||
<path>dmd2.020/dchar.c</path>
|
||||
<path>dmd2.020/dchar.h</path>
|
||||
<path>dmd2.020/declaration.c</path>
|
||||
<path>dmd2.020/declaration.h</path>
|
||||
<path>dmd2.020/delegatize.c</path>
|
||||
<path>dmd2.020/doc.c</path>
|
||||
<path>dmd2.020/doc.h</path>
|
||||
<path>dmd2.020/dsymbol.c</path>
|
||||
<path>dmd2.020/dsymbol.h</path>
|
||||
<path>dmd2.020/dump.c</path>
|
||||
<path>dmd2.020/e2ir.c</path>
|
||||
<path>dmd2.020/entity.c</path>
|
||||
<path>dmd2.020/enum.c</path>
|
||||
<path>dmd2.020/enum.h</path>
|
||||
<path>dmd2.020/expression.c</path>
|
||||
<path>dmd2.020/expression.h</path>
|
||||
<path>dmd2.020/func.c</path>
|
||||
<path>dmd2.020/gnuc.c</path>
|
||||
<path>dmd2.020/gnuc.h</path>
|
||||
<path>dmd2.020/hdrgen.c</path>
|
||||
<path>dmd2.020/hdrgen.h</path>
|
||||
<path>dmd2.020/html.c</path>
|
||||
<path>dmd2.020/html.h</path>
|
||||
<path>dmd2.020/identifier.c</path>
|
||||
<path>dmd2.020/identifier.h</path>
|
||||
<path>dmd2.020/idgen.c</path>
|
||||
<path>dmd2.020/impcnvgen.c</path>
|
||||
<path>dmd2.020/import.c</path>
|
||||
<path>dmd2.020/import.h</path>
|
||||
<path>dmd2.020/inifile.c</path>
|
||||
<path>dmd2.020/init.c</path>
|
||||
<path>dmd2.020/init.h</path>
|
||||
<path>dmd2.020/inline.c</path>
|
||||
<path>dmd2.020/interpret.c</path>
|
||||
<path>dmd2.020/lexer.c</path>
|
||||
<path>dmd2.020/lexer.h</path>
|
||||
<path>dmd2.020/lib.h</path>
|
||||
<path>dmd2.020/libelf.c</path>
|
||||
<path>dmd2.020/link.c</path>
|
||||
<path>dmd2.020/lstring.c</path>
|
||||
<path>dmd2.020/lstring.h</path>
|
||||
<path>dmd2.020/macro.c</path>
|
||||
<path>dmd2.020/macro.h</path>
|
||||
<path>dmd2.020/man.c</path>
|
||||
<path>dmd2.020/mangle.c</path>
|
||||
<path>dmd2.020/mars.c</path>
|
||||
<path>dmd2.020/mars.h</path>
|
||||
<path>dmd2.020/md5.c</path>
|
||||
<path>dmd2.020/md5.h</path>
|
||||
<path>dmd2.020/mem.c</path>
|
||||
<path>dmd2.020/mem.h</path>
|
||||
<path>dmd2.020/module.c</path>
|
||||
<path>dmd2.020/module.h</path>
|
||||
<path>dmd2.020/mtype.c</path>
|
||||
<path>dmd2.020/mtype.h</path>
|
||||
<path>dmd2.020/opover.c</path>
|
||||
<path>dmd2.020/optimize.c</path>
|
||||
<path>dmd2.020/parse.c</path>
|
||||
<path>dmd2.020/parse.h</path>
|
||||
<path>dmd2.020/port.h</path>
|
||||
<path>dmd2.020/root.c</path>
|
||||
<path>dmd2.020/root.h</path>
|
||||
<path>dmd2.020/scope.c</path>
|
||||
<path>dmd2.020/scope.h</path>
|
||||
<path>dmd2.020/statement.c</path>
|
||||
<path>dmd2.020/statement.h</path>
|
||||
<path>dmd2.020/staticassert.c</path>
|
||||
<path>dmd2.020/staticassert.h</path>
|
||||
<path>dmd2.020/stringtable.c</path>
|
||||
<path>dmd2.020/stringtable.h</path>
|
||||
<path>dmd2.020/struct.c</path>
|
||||
<path>dmd2.020/template.c</path>
|
||||
<path>dmd2.020/template.h</path>
|
||||
<path>dmd2.020/tocsym.c</path>
|
||||
<path>dmd2.020/todt.c</path>
|
||||
<path>dmd2.020/toir.c</path>
|
||||
<path>dmd2.020/toir.h</path>
|
||||
<path>dmd2.020/toobj.c</path>
|
||||
<path>dmd2.020/total.h</path>
|
||||
<path>dmd2.020/traits.c</path>
|
||||
<path>dmd2.020/typinf.c</path>
|
||||
<path>dmd2.020/unialpha.c</path>
|
||||
<path>dmd2.020/utf.c</path>
|
||||
<path>dmd2.020/utf.h</path>
|
||||
<path>dmd2.020/version.c</path>
|
||||
<path>dmd2.020/version.h</path>
|
||||
<path>dmd36</path>
|
||||
<path>dmd36/access.c</path>
|
||||
<path>dmd36/aggregate.h</path>
|
||||
<path>dmd36/array.c</path>
|
||||
<path>dmd36/arrayop.c</path>
|
||||
<path>dmd36/arraytypes.h</path>
|
||||
<path>dmd36/attrib.c</path>
|
||||
<path>dmd36/attrib.h</path>
|
||||
<path>dmd36/bit.c</path>
|
||||
<path>dmd36/cast.c</path>
|
||||
<path>dmd36/class.c</path>
|
||||
<path>dmd36/clone.c</path>
|
||||
<path>dmd36/complex_t.h</path>
|
||||
<path>dmd36/cond.c</path>
|
||||
<path>dmd36/cond.h</path>
|
||||
<path>dmd36/constfold.c</path>
|
||||
<path>dmd36/dchar.c</path>
|
||||
<path>dmd36/dchar.h</path>
|
||||
<path>dmd36/declaration.c</path>
|
||||
<path>dmd36/declaration.h</path>
|
||||
<path>dmd36/delegatize.c</path>
|
||||
<path>dmd36/doc.c</path>
|
||||
<path>dmd36/doc.h</path>
|
||||
<path>dmd36/dsymbol.c</path>
|
||||
<path>dmd36/dsymbol.h</path>
|
||||
<path>dmd36/dump.c</path>
|
||||
<path>dmd36/e2ir.c</path>
|
||||
<path>dmd36/entity.c</path>
|
||||
<path>dmd36/enum.c</path>
|
||||
<path>dmd36/enum.h</path>
|
||||
<path>dmd36/expression.c</path>
|
||||
<path>dmd36/expression.h</path>
|
||||
<path>dmd36/func.c</path>
|
||||
<path>dmd36/gnuc.c</path>
|
||||
<path>dmd36/gnuc.h</path>
|
||||
<path>dmd36/hdrgen.c</path>
|
||||
<path>dmd36/hdrgen.h</path>
|
||||
<path>dmd36/html.c</path>
|
||||
<path>dmd36/html.h</path>
|
||||
<path>dmd36/identifier.c</path>
|
||||
<path>dmd36/identifier.h</path>
|
||||
<path>dmd36/idgen.c</path>
|
||||
<path>dmd36/impcnvgen.c</path>
|
||||
<path>dmd36/import.c</path>
|
||||
<path>dmd36/import.h</path>
|
||||
<path>dmd36/inifile.c</path>
|
||||
<path>dmd36/init.c</path>
|
||||
<path>dmd36/init.h</path>
|
||||
<path>dmd36/inline.c</path>
|
||||
<path>dmd36/interpret.c</path>
|
||||
<path>dmd36/lexer.c</path>
|
||||
<path>dmd36/lexer.h</path>
|
||||
<path>dmd36/lib.h</path>
|
||||
<path>dmd36/libelf.c</path>
|
||||
<path>dmd36/link.c</path>
|
||||
<path>dmd36/lstring.c</path>
|
||||
<path>dmd36/lstring.h</path>
|
||||
<path>dmd36/macro.c</path>
|
||||
<path>dmd36/macro.h</path>
|
||||
<path>dmd36/man.c</path>
|
||||
<path>dmd36/mangle.c</path>
|
||||
<path>dmd36/mars.c</path>
|
||||
<path>dmd36/mars.h</path>
|
||||
<path>dmd36/md5.c</path>
|
||||
<path>dmd36/md5.h</path>
|
||||
<path>dmd36/mem.c</path>
|
||||
<path>dmd36/mem.h</path>
|
||||
<path>dmd36/module.c</path>
|
||||
<path>dmd36/module.h</path>
|
||||
<path>dmd36/mtype.c</path>
|
||||
<path>dmd36/mtype.h</path>
|
||||
<path>dmd36/opover.c</path>
|
||||
<path>dmd36/optimize.c</path>
|
||||
<path>dmd36/parse.c</path>
|
||||
<path>dmd36/parse.h</path>
|
||||
<path>dmd36/port.h</path>
|
||||
<path>dmd36/root.c</path>
|
||||
<path>dmd36/root.h</path>
|
||||
<path>dmd36/scope.c</path>
|
||||
<path>dmd36/scope.h</path>
|
||||
<path>dmd36/statement.c</path>
|
||||
<path>dmd36/statement.h</path>
|
||||
<path>dmd36/staticassert.c</path>
|
||||
<path>dmd36/staticassert.h</path>
|
||||
<path>dmd36/stringtable.c</path>
|
||||
<path>dmd36/stringtable.h</path>
|
||||
<path>dmd36/struct.c</path>
|
||||
<path>dmd36/template.c</path>
|
||||
<path>dmd36/template.h</path>
|
||||
<path>dmd36/tocsym.c</path>
|
||||
<path>dmd36/todt.c</path>
|
||||
<path>dmd36/toir.c</path>
|
||||
<path>dmd36/toir.h</path>
|
||||
<path>dmd36/toobj.c</path>
|
||||
<path>dmd36/total.h</path>
|
||||
<path>dmd36/typinf.c</path>
|
||||
<path>dmd36/unialpha.c</path>
|
||||
<path>dmd36/utf.c</path>
|
||||
<path>dmd36/utf.h</path>
|
||||
<path>dmd36/version.c</path>
|
||||
<path>dmd36/version.h</path>
|
||||
</blacklist>
|
||||
<build>
|
||||
<buildtool>make</buildtool>
|
||||
<builddir/>
|
||||
</build>
|
||||
<other>
|
||||
<prio>0</prio>
|
||||
<otherbin/>
|
||||
<defaulttarget/>
|
||||
<otheroptions/>
|
||||
<selectedenvironment>default</selectedenvironment>
|
||||
<environments>
|
||||
<default/>
|
||||
</environments>
|
||||
</other>
|
||||
<make>
|
||||
<abortonerror>false</abortonerror>
|
||||
<numberofjobs>0</numberofjobs>
|
||||
<prio>0</prio>
|
||||
<dontact>false</dontact>
|
||||
<makebin/>
|
||||
<defaulttarget/>
|
||||
<makeoptions/>
|
||||
<selectedenvironment>default</selectedenvironment>
|
||||
<environments>
|
||||
<default/>
|
||||
</environments>
|
||||
</make>
|
||||
<general>
|
||||
<activedir>tangotests</activedir>
|
||||
</general>
|
||||
</kdevcustomproject>
|
||||
<cppsupportpart>
|
||||
<filetemplates>
|
||||
<interfacesuffix>.h</interfacesuffix>
|
||||
<implementationsuffix>.cpp</implementationsuffix>
|
||||
</filetemplates>
|
||||
</cppsupportpart>
|
||||
<kdevdebugger>
|
||||
<general>
|
||||
<gdbpath/>
|
||||
<dbgshell/>
|
||||
<configGdbScript/>
|
||||
<runShellScript/>
|
||||
<runGdbScript/>
|
||||
<breakonloadinglibs>true</breakonloadinglibs>
|
||||
<separatetty>false</separatetty>
|
||||
<floatingtoolbar>false</floatingtoolbar>
|
||||
<raiseGDBOnStart>false</raiseGDBOnStart>
|
||||
</general>
|
||||
<display>
|
||||
<staticmembers>false</staticmembers>
|
||||
<demanglenames>true</demanglenames>
|
||||
<outputradix>10</outputradix>
|
||||
</display>
|
||||
</kdevdebugger>
|
||||
</kdevelop>
|
|
@ -1,239 +0,0 @@
|
|||
# KDevelop Custom Project File List
|
||||
dmd
|
||||
dmd/access.c
|
||||
dmd/aggregate.h
|
||||
dmd/array.c
|
||||
dmd/arrayop.c
|
||||
dmd/arraytypes.h
|
||||
dmd/attrib.c
|
||||
dmd/attrib.h
|
||||
dmd/cast.c
|
||||
dmd/class.c
|
||||
dmd/clone.c
|
||||
dmd/complex_t.h
|
||||
dmd/cond.c
|
||||
dmd/cond.h
|
||||
dmd/constfold.c
|
||||
dmd/dchar.c
|
||||
dmd/dchar.h
|
||||
dmd/declaration.c
|
||||
dmd/declaration.h
|
||||
dmd/delegatize.c
|
||||
dmd/doc.c
|
||||
dmd/doc.h
|
||||
dmd/dsymbol.c
|
||||
dmd/dsymbol.h
|
||||
dmd/dump.c
|
||||
dmd/entity.c
|
||||
dmd/enum.c
|
||||
dmd/enum.h
|
||||
dmd/expression.c
|
||||
dmd/expression.h
|
||||
dmd/func.c
|
||||
dmd/gnuc.c
|
||||
dmd/gnuc.h
|
||||
dmd/hdrgen.c
|
||||
dmd/hdrgen.h
|
||||
dmd/html.c
|
||||
dmd/html.h
|
||||
dmd/identifier.c
|
||||
dmd/identifier.h
|
||||
dmd/idgen.c
|
||||
dmd/impcnvgen.c
|
||||
dmd/import.c
|
||||
dmd/import.h
|
||||
dmd/inifile.c
|
||||
dmd/init.c
|
||||
dmd/init.h
|
||||
dmd/inline.c
|
||||
dmd/interpret.c
|
||||
dmd/lexer.c
|
||||
dmd/lexer.h
|
||||
dmd/lstring.c
|
||||
dmd/lstring.h
|
||||
dmd/macro.c
|
||||
dmd/macro.h
|
||||
dmd/mangle.c
|
||||
dmd/mars.c
|
||||
dmd/mars.h
|
||||
dmd/mem.c
|
||||
dmd/mem.h
|
||||
dmd/module.c
|
||||
dmd/module.h
|
||||
dmd/mtype.c
|
||||
dmd/mtype.h
|
||||
dmd/opover.c
|
||||
dmd/optimize.c
|
||||
dmd/parse.c
|
||||
dmd/parse.h
|
||||
dmd/port.h
|
||||
dmd/root.c
|
||||
dmd/root.h
|
||||
dmd/scope.c
|
||||
dmd/scope.h
|
||||
dmd/statement.c
|
||||
dmd/statement.h
|
||||
dmd/staticassert.c
|
||||
dmd/staticassert.h
|
||||
dmd/stringtable.c
|
||||
dmd/stringtable.h
|
||||
dmd/struct.c
|
||||
dmd/template.c
|
||||
dmd/template.h
|
||||
dmd/total.h
|
||||
dmd/unialpha.c
|
||||
dmd/utf.c
|
||||
dmd/utf.h
|
||||
dmd/version.c
|
||||
dmd/version.h
|
||||
dmd2
|
||||
dmd2/access.c
|
||||
dmd2/aggregate.h
|
||||
dmd2/array.c
|
||||
dmd2/arrayop.c
|
||||
dmd2/arraytypes.h
|
||||
dmd2/attrib.c
|
||||
dmd2/attrib.h
|
||||
dmd2/builtin.c
|
||||
dmd2/cast.c
|
||||
dmd2/class.c
|
||||
dmd2/clone.c
|
||||
dmd2/complex_t.h
|
||||
dmd2/cond.c
|
||||
dmd2/cond.h
|
||||
dmd2/constfold.c
|
||||
dmd2/dchar.c
|
||||
dmd2/dchar.h
|
||||
dmd2/declaration.c
|
||||
dmd2/declaration.h
|
||||
dmd2/delegatize.c
|
||||
dmd2/doc.c
|
||||
dmd2/doc.h
|
||||
dmd2/dsymbol.c
|
||||
dmd2/dsymbol.h
|
||||
dmd2/dump.c
|
||||
dmd2/entity.c
|
||||
dmd2/enum.c
|
||||
dmd2/enum.h
|
||||
dmd2/expression.c
|
||||
dmd2/expression.h
|
||||
dmd2/func.c
|
||||
dmd2/gnuc.c
|
||||
dmd2/gnuc.h
|
||||
dmd2/hdrgen.c
|
||||
dmd2/hdrgen.h
|
||||
dmd2/html.c
|
||||
dmd2/html.h
|
||||
dmd2/id.c
|
||||
dmd2/id.h
|
||||
dmd2/identifier.c
|
||||
dmd2/identifier.h
|
||||
dmd2/idgen.c
|
||||
dmd2/impcnvgen.c
|
||||
dmd2/impcnvtab.c
|
||||
dmd2/import.c
|
||||
dmd2/import.h
|
||||
dmd2/inifile.c
|
||||
dmd2/init.c
|
||||
dmd2/init.h
|
||||
dmd2/inline.c
|
||||
dmd2/interpret.c
|
||||
dmd2/lexer.c
|
||||
dmd2/lexer.h
|
||||
dmd2/lstring.c
|
||||
dmd2/lstring.h
|
||||
dmd2/macro.c
|
||||
dmd2/macro.h
|
||||
dmd2/man.c
|
||||
dmd2/mangle.c
|
||||
dmd2/mars.c
|
||||
dmd2/mars.h
|
||||
dmd2/mem.c
|
||||
dmd2/mem.h
|
||||
dmd2/module.c
|
||||
dmd2/module.h
|
||||
dmd2/mtype.c
|
||||
dmd2/mtype.h
|
||||
dmd2/opover.c
|
||||
dmd2/optimize.c
|
||||
dmd2/parse.c
|
||||
dmd2/parse.h
|
||||
dmd2/port.h
|
||||
dmd2/root.c
|
||||
dmd2/root.h
|
||||
dmd2/scope.c
|
||||
dmd2/scope.h
|
||||
dmd2/statement.c
|
||||
dmd2/statement.h
|
||||
dmd2/staticassert.c
|
||||
dmd2/staticassert.h
|
||||
dmd2/stringtable.c
|
||||
dmd2/stringtable.h
|
||||
dmd2/struct.c
|
||||
dmd2/template.c
|
||||
dmd2/template.h
|
||||
dmd2/total.h
|
||||
dmd2/traits.c
|
||||
dmd2/unialpha.c
|
||||
dmd2/utf.c
|
||||
dmd2/utf.h
|
||||
dmd2/version.c
|
||||
dmd2/version.h
|
||||
gen
|
||||
gen/aa.cpp
|
||||
gen/aa.h
|
||||
gen/arrays.cpp
|
||||
gen/arrays.h
|
||||
gen/asmstmt.cpp
|
||||
gen/binops.cpp
|
||||
gen/classes.cpp
|
||||
gen/classes.h
|
||||
gen/complex.cpp
|
||||
gen/complex.h
|
||||
gen/dvalue.cpp
|
||||
gen/dvalue.h
|
||||
gen/dwarftypes.cpp
|
||||
gen/enums.h
|
||||
gen/functions.cpp
|
||||
gen/functions.h
|
||||
gen/irstate.cpp
|
||||
gen/irstate.h
|
||||
gen/linker.cpp
|
||||
gen/linker.h
|
||||
gen/llvm.h
|
||||
gen/llvmhelpers.cpp
|
||||
gen/llvmhelpers.h
|
||||
gen/logger.cpp
|
||||
gen/logger.h
|
||||
gen/optimizer.cpp
|
||||
gen/runtime.cpp
|
||||
gen/runtime.h
|
||||
gen/statements.cpp
|
||||
gen/structs.cpp
|
||||
gen/structs.h
|
||||
gen/tocall.cpp
|
||||
gen/tocsym.cpp
|
||||
gen/todebug.cpp
|
||||
gen/todebug.h
|
||||
gen/todt.cpp
|
||||
gen/toir.cpp
|
||||
gen/tollvm.cpp
|
||||
gen/tollvm.h
|
||||
gen/toobj.cpp
|
||||
gen/typeinf.h
|
||||
gen/typinf.cpp
|
||||
ir
|
||||
ir/ir.h
|
||||
ir/irforw.h
|
||||
ir/irfunction.cpp
|
||||
ir/irfunction.h
|
||||
ir/irmodule.cpp
|
||||
ir/irmodule.h
|
||||
ir/irstruct.cpp
|
||||
ir/irstruct.h
|
||||
ir/irsymbol.cpp
|
||||
ir/irsymbol.h
|
||||
ir/irtype.cpp
|
||||
ir/irtype.h
|
||||
ir/irvar.cpp
|
||||
ir/irvar.h
|
|
@ -12,14 +12,14 @@ class C : I
|
|||
int i = 42;
|
||||
override void func()
|
||||
{
|
||||
printf("hello %d\n", i);
|
||||
printf("hello %d from %p\n", i, this);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
scope c = new C;
|
||||
auto c = new C;
|
||||
{c.func();}
|
||||
{
|
||||
I i = c;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue