mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 22:50:53 +03:00
Make IrDsymbol to be a typesafe union to reduce memory usage
This commit is contained in:
parent
5b15095c81
commit
18f33b1815
27 changed files with 465 additions and 293 deletions
|
@ -52,9 +52,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
|||
DtoType(cd->type);
|
||||
|
||||
// create IrAggr
|
||||
assert(cd->ir.irAggr == NULL);
|
||||
IrAggr* irAggr = new IrAggr(cd);
|
||||
cd->ir.irAggr = irAggr;
|
||||
IrAggr* irAggr = getIrAggr(cd, true);
|
||||
|
||||
// make sure all fields really get their ir field
|
||||
for (VarDeclarations::iterator I = cd->fields.begin(),
|
||||
|
@ -62,12 +60,12 @@ void DtoResolveClass(ClassDeclaration* cd)
|
|||
I != E; ++I)
|
||||
{
|
||||
VarDeclaration* vd = *I;
|
||||
if (vd->ir.irField == NULL) {
|
||||
new IrField(vd);
|
||||
} else {
|
||||
|
||||
if (!isIrFieldCreated(vd))
|
||||
getIrField(vd, true);
|
||||
else
|
||||
IF_LOG Logger::println("class field already exists!!!");
|
||||
}
|
||||
}
|
||||
|
||||
// emit the interfaceInfosZ symbol if necessary
|
||||
if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0)
|
||||
|
@ -98,7 +96,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp)
|
|||
else if (newexp->allocator)
|
||||
{
|
||||
DtoResolveFunction(newexp->allocator);
|
||||
DFuncValue dfn(newexp->allocator, newexp->allocator->ir.irFunc->func);
|
||||
DFuncValue dfn(newexp->allocator, getIrFunc(newexp->allocator)->func);
|
||||
DValue* res = DtoCallFunction(newexp->loc, NULL, &dfn, newexp->newargs);
|
||||
mem = DtoBitCast(res->getRVal(), DtoType(tc), ".newclass_custom");
|
||||
}
|
||||
|
@ -106,7 +104,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp)
|
|||
else
|
||||
{
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_newclass");
|
||||
LLConstant* ci = DtoBitCast(tc->sym->ir.irAggr->getClassInfoSymbol(), DtoType(Type::typeinfoclass->type));
|
||||
LLConstant* ci = DtoBitCast(getIrAggr(tc->sym)->getClassInfoSymbol(), DtoType(Type::typeinfoclass->type));
|
||||
mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
|
||||
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
|
||||
}
|
||||
|
@ -120,7 +118,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp)
|
|||
Logger::println("Resolving outer class");
|
||||
LOG_SCOPE;
|
||||
DValue* thisval = newexp->thisexp->toElem(gIR);
|
||||
size_t idx = tc->sym->vthis->ir.irField->index;
|
||||
size_t idx = getIrField(tc->sym->vthis)->index;
|
||||
LLValue* src = thisval->getRVal();
|
||||
LLValue* dst = DtoGEPi(mem,0,idx,"tmp");
|
||||
IF_LOG Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
|
||||
|
@ -138,7 +136,7 @@ DValue* DtoNewClass(Loc& loc, TypeClass* tc, NewExp* newexp)
|
|||
Logger::println("Calling constructor");
|
||||
assert(newexp->arguments != NULL);
|
||||
DtoResolveFunction(newexp->member);
|
||||
DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem);
|
||||
DFuncValue dfn(newexp->member, getIrFunc(newexp->member)->func, mem);
|
||||
return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments);
|
||||
}
|
||||
|
||||
|
@ -154,7 +152,7 @@ void DtoInitClass(TypeClass* tc, LLValue* dst)
|
|||
|
||||
// Set vtable field. Doing this seperately might be optimized better.
|
||||
LLValue* tmp = DtoGEPi(dst, 0, 0, "vtbl");
|
||||
LLValue* val = DtoBitCast(tc->sym->ir.irAggr->getVtblSymbol(),
|
||||
LLValue* val = DtoBitCast(getIrAggr(tc->sym)->getVtblSymbol(),
|
||||
tmp->getType()->getContainedType(0));
|
||||
DtoStore(val, tmp);
|
||||
|
||||
|
@ -176,7 +174,7 @@ void DtoInitClass(TypeClass* tc, LLValue* dst)
|
|||
LLValue* dstarr = DtoGEPi(dst, 0, firstDataIdx, "tmp");
|
||||
|
||||
// init symbols might not have valid types
|
||||
LLValue* initsym = tc->sym->ir.irAggr->getInitSymbol();
|
||||
LLValue* initsym = getIrAggr(tc->sym)->getInitSymbol();
|
||||
initsym = DtoBitCast(initsym, DtoType(tc));
|
||||
LLValue* srcarr = DtoGEPi(initsym, 0, firstDataIdx, "tmp");
|
||||
|
||||
|
@ -335,7 +333,7 @@ DValue* DtoDynamicCastObject(Loc& loc, DValue* val, Type* _to)
|
|||
TypeClass* to = static_cast<TypeClass*>(_to->toBasetype());
|
||||
DtoResolveClass(to->sym);
|
||||
|
||||
LLValue* cinfo = to->sym->ir.irAggr->getClassInfoSymbol();
|
||||
LLValue* cinfo = getIrAggr(to->sym)->getClassInfoSymbol();
|
||||
// unfortunately this is needed as the implementation of object differs somehow from the declaration
|
||||
// this could happen in user code as well :/
|
||||
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
|
||||
|
@ -396,7 +394,7 @@ DValue* DtoDynamicCastInterface(Loc& loc, DValue* val, Type* _to)
|
|||
// ClassInfo c
|
||||
TypeClass* to = static_cast<TypeClass*>(_to->toBasetype());
|
||||
DtoResolveClass(to->sym);
|
||||
LLValue* cinfo = to->sym->ir.irAggr->getClassInfoSymbol();
|
||||
LLValue* cinfo = getIrAggr(to->sym)->getClassInfoSymbol();
|
||||
// unfortunately this is needed as the implementation of object differs somehow from the declaration
|
||||
// this could happen in user code as well :/
|
||||
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
|
||||
|
@ -423,7 +421,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
|
|||
DtoResolveClass(cd);
|
||||
|
||||
// vd must be a field
|
||||
IrField* field = vd->ir.irField;
|
||||
IrField* field = getIrField(vd);
|
||||
assert(field);
|
||||
|
||||
// get the start pointer
|
||||
|
@ -573,7 +571,7 @@ static LLConstant* build_class_dtor(ClassDeclaration* cd)
|
|||
return getNullPtr(getVoidPtrType());
|
||||
|
||||
DtoResolveFunction(dtor);
|
||||
return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::getInt8Ty(gIR->context())));
|
||||
return llvm::ConstantExpr::getBitCast(getIrFunc(dtor)->func, getPtrToType(LLType::getInt8Ty(gIR->context())));
|
||||
}
|
||||
|
||||
static unsigned build_classinfo_flags(ClassDeclaration* cd)
|
||||
|
@ -643,9 +641,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
|||
assert(cd->type->ty == Tclass);
|
||||
TypeClass* cdty = static_cast<TypeClass*>(cd->type);
|
||||
|
||||
IrAggr* ir = cd->ir.irAggr;
|
||||
assert(ir);
|
||||
|
||||
IrAggr* ir = getIrAggr(cd);
|
||||
ClassDeclaration* cinfo = Type::typeinfoclass;
|
||||
|
||||
if (cinfo->fields.dim != 12)
|
||||
|
|
|
@ -79,8 +79,9 @@ public:
|
|||
DtoTypeInfoOf(decl->type);
|
||||
|
||||
// Define __InterfaceZ.
|
||||
llvm::GlobalVariable *interfaceZ = decl->ir.irAggr->getClassInfoSymbol();
|
||||
interfaceZ->setInitializer(decl->ir.irAggr->getClassInfoInit());
|
||||
IrAggr *ir = getIrAggr(decl);
|
||||
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
|
||||
interfaceZ->setInitializer(ir->getClassInfoInit());
|
||||
interfaceZ->setLinkage(DtoExternalLinkage(decl));
|
||||
}
|
||||
}
|
||||
|
@ -112,8 +113,9 @@ public:
|
|||
}
|
||||
|
||||
// Define the __initZ symbol.
|
||||
llvm::GlobalVariable *initZ = ir.irAggr->getInitSymbol();
|
||||
initZ->setInitializer(ir.irAggr->getDefaultInit());
|
||||
IrAggr *ir = getIrAggr(decl);
|
||||
llvm::GlobalVariable *initZ = ir->getInitSymbol();
|
||||
initZ->setInitializer(ir->getDefaultInit());
|
||||
initZ->setLinkage(DtoExternalLinkage(decl));
|
||||
|
||||
// emit typeinfo
|
||||
|
@ -133,9 +135,8 @@ public:
|
|||
IF_LOG Logger::println("ClassDeclaration::codegen: '%s'", decl->toPrettyChars());
|
||||
LOG_SCOPE
|
||||
|
||||
IrDsymbol &ir = decl->ir;
|
||||
if (ir.defined) return;
|
||||
ir.defined = true;
|
||||
if (decl->ir.defined) return;
|
||||
decl->ir.defined = true;
|
||||
|
||||
if (decl->type->ty == Terror)
|
||||
{ error(decl->loc, "had semantic errors when compiling");
|
||||
|
@ -153,18 +154,19 @@ public:
|
|||
(*I)->accept(this);
|
||||
}
|
||||
|
||||
IrAggr *ir = getIrAggr(decl);
|
||||
llvm::GlobalValue::LinkageTypes const linkage = DtoExternalLinkage(decl);
|
||||
|
||||
llvm::GlobalVariable *initZ = ir.irAggr->getInitSymbol();
|
||||
initZ->setInitializer(ir.irAggr->getDefaultInit());
|
||||
llvm::GlobalVariable *initZ = ir->getInitSymbol();
|
||||
initZ->setInitializer(ir->getDefaultInit());
|
||||
initZ->setLinkage(linkage);
|
||||
|
||||
llvm::GlobalVariable *vtbl = ir.irAggr->getVtblSymbol();
|
||||
vtbl->setInitializer(ir.irAggr->getVtblInit());
|
||||
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
|
||||
vtbl->setInitializer(ir->getVtblInit());
|
||||
vtbl->setLinkage(linkage);
|
||||
|
||||
llvm::GlobalVariable *classZ = ir.irAggr->getClassInfoSymbol();
|
||||
classZ->setInitializer(ir.irAggr->getClassInfoInit());
|
||||
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
|
||||
classZ->setInitializer(ir->getClassInfoInit());
|
||||
classZ->setLinkage(linkage);
|
||||
|
||||
// No need to do TypeInfo here, it is <name>__classZ for classes in D2.
|
||||
|
@ -227,8 +229,8 @@ public:
|
|||
"manifest constant being codegen'd!");
|
||||
#endif
|
||||
|
||||
llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(
|
||||
decl->ir.irGlobal->value);
|
||||
IrGlobal *irGlobal = getIrGlobal(decl);
|
||||
llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(irGlobal->value);
|
||||
assert(gvar && "DtoResolveVariable should have created value");
|
||||
|
||||
const llvm::GlobalValue::LinkageTypes llLinkage = DtoLinkage(decl);
|
||||
|
@ -257,12 +259,12 @@ public:
|
|||
|
||||
gvar->eraseFromParent();
|
||||
gvar = newGvar;
|
||||
decl->ir.irGlobal->value = newGvar;
|
||||
irGlobal->value = newGvar;
|
||||
}
|
||||
|
||||
// Now, set the initializer.
|
||||
assert(!decl->ir.irGlobal->constInit);
|
||||
decl->ir.irGlobal->constInit = initVal;
|
||||
assert(!irGlobal->constInit);
|
||||
irGlobal->constInit = initVal;
|
||||
gvar->setInitializer(initVal);
|
||||
gvar->setLinkage(llLinkage);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//===-- gen/dibuilder.h - Debug information builder -------------*- C++ -*-===//
|
||||
//
|
||||
// LDC – the LLVM D compiler
|
||||
// LDC – the LLVM D compiler
|
||||
//
|
||||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||||
// file for details.
|
||||
|
@ -282,7 +282,7 @@ llvm::DIType ldc::DIBuilder::CreateCompositeType(Type *type)
|
|||
assert(sd);
|
||||
|
||||
// Use the actual type associated with the declaration, ignoring any
|
||||
// const/… wrappers.
|
||||
// const/
wrappers.
|
||||
LLType *T = DtoType(sd->type);
|
||||
IrTypeAggr *ir = sd->type->irtype->isAggr();
|
||||
assert(ir);
|
||||
|
@ -605,7 +605,7 @@ llvm::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd)
|
|||
fd->loc.linnum, // FIXME: scope line
|
||||
0, // Flags
|
||||
false, // isOptimized
|
||||
fd->ir.irFunc->func
|
||||
getIrFunc(fd)->func
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -657,7 +657,7 @@ void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd)
|
|||
Logger::println("D to dwarf funcstart");
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(static_cast<llvm::MDNode *>(fd->ir.irFunc->diSubprogram) != 0);
|
||||
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
|
||||
EmitStopPoint(fd->loc.linnum);
|
||||
}
|
||||
|
||||
|
@ -669,7 +669,7 @@ void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd)
|
|||
Logger::println("D to dwarf funcend");
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(static_cast<llvm::MDNode *>(fd->ir.irFunc->diSubprogram) != 0);
|
||||
assert(static_cast<llvm::MDNode *>(getIrFunc(fd)->diSubprogram) != 0);
|
||||
}
|
||||
|
||||
void ldc::DIBuilder::EmitBlockStart(Loc& loc)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//===-- gen/dibuilder.h - Debug information builder -------------*- C++ -*-===//
|
||||
//
|
||||
// LDC – the LLVM D compiler
|
||||
// LDC – the LLVM D compiler
|
||||
//
|
||||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||||
// file for details.
|
||||
|
|
|
@ -501,7 +501,7 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
|
|||
func = GET_INTRINSIC_DECL(vaend);
|
||||
assert(func);
|
||||
|
||||
fdecl->ir.irFunc->func = func;
|
||||
getIrFunc(fdecl)->func = func;
|
||||
return func;
|
||||
}
|
||||
|
||||
|
@ -767,9 +767,8 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
Type* t = fdecl->type->toBasetype();
|
||||
TypeFunction* f = static_cast<TypeFunction*>(t);
|
||||
|
||||
if (!fdecl->ir.irFunc) {
|
||||
fdecl->ir.irFunc = new IrFunction(fdecl);
|
||||
}
|
||||
// create IrFunction
|
||||
IrFunction *irFunc = getIrFunc(fdecl, true);
|
||||
|
||||
LLFunction* vafunc = 0;
|
||||
if (fdecl->isVaIntrinsic())
|
||||
|
@ -816,7 +815,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
IF_LOG Logger::cout() << "func = " << *func << std::endl;
|
||||
|
||||
// add func to IRFunc
|
||||
fdecl->ir.irFunc->func = func;
|
||||
irFunc->func = func;
|
||||
|
||||
// parameter attributes
|
||||
if (!fdecl->isIntrinsic()) {
|
||||
|
@ -838,7 +837,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
|
||||
if (fdecl->neverInline)
|
||||
{
|
||||
fdecl->ir.irFunc->setNeverInline();
|
||||
irFunc->setNeverInline();
|
||||
}
|
||||
|
||||
if (fdecl->llvmInternal == LLVMglobal_crt_ctor || fdecl->llvmInternal == LLVMglobal_crt_dtor)
|
||||
|
@ -855,13 +854,13 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
|
||||
if (irFty.arg_sret) {
|
||||
iarg->setName(".sret_arg");
|
||||
fdecl->ir.irFunc->retArg = iarg;
|
||||
irFunc->retArg = iarg;
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (irFty.arg_this) {
|
||||
iarg->setName(".this_arg");
|
||||
fdecl->ir.irFunc->thisArg = iarg;
|
||||
irFunc->thisArg = iarg;
|
||||
|
||||
VarDeclaration* v = fdecl->vthis;
|
||||
if (v) {
|
||||
|
@ -869,25 +868,28 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
// later for codegen'ing the function, just as normal
|
||||
// parameters below, because it can be referred to in nested
|
||||
// context types. Will be given storage in DtoDefineFunction.
|
||||
assert(!v->ir.irParam);
|
||||
v->ir.irParam = new IrParameter(v, iarg, irFty.arg_this, true);
|
||||
assert(!isIrParameterCreated(v));
|
||||
IrParameter *irParam = getIrParameter(v, true);
|
||||
irParam->value = iarg;
|
||||
irParam->arg = irFty.arg_this;
|
||||
irParam->isVthis = true;
|
||||
}
|
||||
|
||||
++iarg;
|
||||
}
|
||||
else if (irFty.arg_nest) {
|
||||
iarg->setName(".nest_arg");
|
||||
fdecl->ir.irFunc->nestArg = iarg;
|
||||
assert(fdecl->ir.irFunc->nestArg);
|
||||
irFunc->nestArg = iarg;
|
||||
assert(irFunc->nestArg);
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (irFty.arg_argptr) {
|
||||
iarg->setName("._arguments");
|
||||
fdecl->ir.irFunc->_arguments = iarg;
|
||||
irFunc->_arguments = iarg;
|
||||
++iarg;
|
||||
iarg->setName("._argptr");
|
||||
fdecl->ir.irFunc->_argptr = iarg;
|
||||
irFunc->_argptr = iarg;
|
||||
++iarg;
|
||||
}
|
||||
|
||||
|
@ -902,11 +904,14 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
|
||||
VarDeclaration* argvd = argsym->isVarDeclaration();
|
||||
assert(argvd);
|
||||
assert(!argvd->ir.irLocal);
|
||||
assert(!isIrLocalCreated(argvd));
|
||||
std::string str(argvd->ident->toChars());
|
||||
str.append("_arg");
|
||||
iarg->setName(str);
|
||||
argvd->ir.irParam = new IrParameter(argvd, iarg, irFty.args[paramIndex]);
|
||||
|
||||
IrParameter *irParam = getIrParameter(argvd, true);
|
||||
irParam->value = iarg;
|
||||
irParam->arg = irFty.args[paramIndex];
|
||||
|
||||
k++;
|
||||
}
|
||||
|
@ -1023,24 +1028,23 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
}
|
||||
|
||||
IrFuncTy &irFty = fd->irFty;
|
||||
IrFunction *irFunc = getIrFunc(fd);
|
||||
|
||||
// debug info
|
||||
fd->ir.irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd);
|
||||
irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd);
|
||||
|
||||
Type* t = fd->type->toBasetype();
|
||||
TypeFunction* f = static_cast<TypeFunction*>(t);
|
||||
// assert(f->irtype);
|
||||
|
||||
llvm::Function* func = fd->ir.irFunc->func;
|
||||
llvm::Function* func = irFunc->func;
|
||||
|
||||
// is there a body?
|
||||
if (fd->fbody == NULL)
|
||||
return;
|
||||
|
||||
IF_LOG Logger::println("Doing function body for: %s", fd->toChars());
|
||||
assert(fd->ir.irFunc);
|
||||
IrFunction* irfunction = fd->ir.irFunc;
|
||||
gIR->functions.push_back(irfunction);
|
||||
gIR->functions.push_back(irFunc);
|
||||
|
||||
if (fd->isMain())
|
||||
gIR->emitMain = true;
|
||||
|
@ -1079,7 +1083,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
// create alloca point
|
||||
// this gets erased when the function is complete, so alignment etc does not matter at all
|
||||
llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb);
|
||||
irfunction->allocapoint = allocaPoint;
|
||||
irFunc->allocapoint = allocaPoint;
|
||||
|
||||
// debug info - after all allocas, but before any llvm.dbg.declare etc
|
||||
gIR->DBuilder.EmitFuncStart(fd);
|
||||
|
@ -1096,7 +1100,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
// give the 'this' argument storage and debug info
|
||||
if (irFty.arg_this)
|
||||
{
|
||||
LLValue* thisvar = irfunction->thisArg;
|
||||
LLValue* thisvar = irFunc->thisArg;
|
||||
assert(thisvar);
|
||||
|
||||
LLValue* thismem = thisvar;
|
||||
|
@ -1104,11 +1108,11 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
{
|
||||
thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
|
||||
DtoStore(thisvar, thismem);
|
||||
irfunction->thisArg = thismem;
|
||||
irFunc->thisArg = thismem;
|
||||
}
|
||||
|
||||
assert(fd->vthis->ir.irParam->value == thisvar);
|
||||
fd->vthis->ir.irParam->value = thismem;
|
||||
assert(getIrParameter(fd->vthis)->value == thisvar);
|
||||
getIrParameter(fd->vthis)->value = thismem;
|
||||
|
||||
gIR->DBuilder.EmitLocalVariable(thismem, fd->vthis);
|
||||
}
|
||||
|
@ -1116,10 +1120,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
// give the 'nestArg' storage
|
||||
if (irFty.arg_nest)
|
||||
{
|
||||
LLValue *nestArg = irfunction->nestArg;
|
||||
LLValue *nestArg = irFunc->nestArg;
|
||||
LLValue *val = DtoRawAlloca(nestArg->getType(), 0, "nestedFrame");
|
||||
DtoStore(nestArg, val);
|
||||
irfunction->nestArg = val;
|
||||
irFunc->nestArg = val;
|
||||
}
|
||||
|
||||
// give arguments storage
|
||||
|
@ -1134,7 +1138,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
VarDeclaration* vd = argsym->isVarDeclaration();
|
||||
assert(vd);
|
||||
|
||||
IrParameter* irparam = vd->ir.irParam;
|
||||
IrParameter* irparam = getIrParameter(vd);
|
||||
assert(irparam);
|
||||
|
||||
bool refout = vd->storage_class & (STCref | STCout);
|
||||
|
@ -1163,7 +1167,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
}
|
||||
|
||||
FuncGen fg;
|
||||
irfunction->gen = &fg;
|
||||
irFunc->gen = &fg;
|
||||
|
||||
DtoCreateNestedContext(fd);
|
||||
|
||||
|
@ -1178,19 +1182,19 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
if (f->linkage == LINKd && f->varargs == 1)
|
||||
{
|
||||
// _argptr
|
||||
LLValue* argptrmem = DtoRawAlloca(fd->ir.irFunc->_argptr->getType(), 0, "_argptr_mem");
|
||||
new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
|
||||
fd->ir.irFunc->_argptr = argptrmem;
|
||||
LLValue* argptrmem = DtoRawAlloca(irFunc->_argptr->getType(), 0, "_argptr_mem");
|
||||
new llvm::StoreInst(irFunc->_argptr, argptrmem, gIR->scopebb());
|
||||
irFunc->_argptr = argptrmem;
|
||||
|
||||
// _arguments
|
||||
LLValue* argumentsmem = DtoRawAlloca(fd->ir.irFunc->_arguments->getType(), 0, "_arguments_mem");
|
||||
new llvm::StoreInst(fd->ir.irFunc->_arguments, argumentsmem, gIR->scopebb());
|
||||
fd->ir.irFunc->_arguments = argumentsmem;
|
||||
LLValue* argumentsmem = DtoRawAlloca(irFunc->_arguments->getType(), 0, "_arguments_mem");
|
||||
new llvm::StoreInst(irFunc->_arguments, argumentsmem, gIR->scopebb());
|
||||
irFunc->_arguments = argumentsmem;
|
||||
}
|
||||
|
||||
// output function body
|
||||
Statement_toIR(fd->fbody, gIR);
|
||||
irfunction->gen = 0;
|
||||
irFunc->gen = 0;
|
||||
|
||||
// TODO: clean up this mess
|
||||
|
||||
|
|
|
@ -1032,7 +1032,7 @@ void DtoResolveVariable(VarDeclaration* vd)
|
|||
vd->ir.resolved = true;
|
||||
vd->ir.declared = true;
|
||||
|
||||
vd->ir.irGlobal = new IrGlobal(vd);
|
||||
getIrGlobal(vd, true);
|
||||
|
||||
IF_LOG {
|
||||
if (vd->parent)
|
||||
|
@ -1066,7 +1066,7 @@ void DtoResolveVariable(VarDeclaration* vd)
|
|||
llvm::GlobalVariable* gvar = getOrCreateGlobal(vd->loc, *gIR->module,
|
||||
i1ToI8(DtoType(vd->type)), isLLConst, linkage, 0, llName,
|
||||
vd->isThreadlocal());
|
||||
vd->ir.irGlobal->value = gvar;
|
||||
getIrGlobal(vd)->value = gvar;
|
||||
|
||||
// Set the alignment (it is important not to use type->alignsize because
|
||||
// VarDeclarations can have an align() attribute independent of the type
|
||||
|
@ -1101,7 +1101,7 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
// assert(vd->ir.irLocal && "irLocal is expected to be already set by DtoCreateNestedContext");
|
||||
}
|
||||
|
||||
if(vd->ir.irLocal)
|
||||
if (isIrLocalCreated(vd))
|
||||
{
|
||||
// Nothing to do if it has already been allocated.
|
||||
}
|
||||
|
@ -1114,11 +1114,12 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
*/
|
||||
else if (gIR->func()->retArg && gIR->func()->decl->nrvo_can && gIR->func()->decl->nrvo_var == vd) {
|
||||
assert(!isSpecialRefVar(vd) && "Can this happen?");
|
||||
vd->ir.irLocal = new IrLocal(vd, gIR->func()->retArg);
|
||||
IrLocal *irLocal = getIrLocal(vd, true);
|
||||
irLocal->value = gIR->func()->retArg;
|
||||
}
|
||||
// normal stack variable, allocate storage on the stack if it has not already been done
|
||||
else {
|
||||
vd->ir.irLocal = new IrLocal(vd);
|
||||
IrLocal *irLocal = getIrLocal(vd, true);
|
||||
|
||||
Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type;
|
||||
|
||||
|
@ -1129,7 +1130,7 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
else
|
||||
allocainst = DtoAlloca(type, vd->toChars());
|
||||
|
||||
vd->ir.irLocal->value = allocainst;
|
||||
irLocal->value = allocainst;
|
||||
|
||||
gIR->DBuilder.EmitLocalVariable(allocainst, vd);
|
||||
|
||||
|
@ -1157,12 +1158,12 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
if (isSpecialRefVar(vd))
|
||||
{
|
||||
LLValue* const val = ce->toElem(gIR)->getLVal();
|
||||
DtoStore(val, vd->ir.irLocal->value);
|
||||
DtoStore(val, irLocal->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
DValue* fnval = ce->e1->toElem(gIR);
|
||||
DtoCallFunction(ce->loc, ce->type, fnval, ce->arguments, vd->ir.irLocal->value);
|
||||
DtoCallFunction(ce->loc, ce->type, fnval, ce->arguments, irLocal->value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1171,7 +1172,7 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
}
|
||||
}
|
||||
|
||||
IF_LOG Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
|
||||
IF_LOG Logger::cout() << "llvm value for decl: " << *getIrLocal(vd)->value << '\n';
|
||||
|
||||
if (vd->init)
|
||||
{
|
||||
|
@ -1209,7 +1210,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
|
|||
{
|
||||
DtoVarDeclaration(vd);
|
||||
}
|
||||
return new DVarValue(vd->type, vd, vd->ir.getIrValue());
|
||||
return new DVarValue(vd->type, vd, getIrValue(vd));
|
||||
}
|
||||
// struct declaration
|
||||
else if (StructDeclaration* s = declaration->isStructDeclaration())
|
||||
|
@ -1289,8 +1290,10 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
|
|||
// we don't handle aliases either
|
||||
assert(!var->aliassym);
|
||||
|
||||
IrLocal *irLocal = isIrLocalCreated(var) ? getIrLocal(var) : 0;
|
||||
|
||||
// alloca if necessary
|
||||
if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value))
|
||||
if (!addr && (!irLocal || !irLocal->value))
|
||||
{
|
||||
addr = DtoAlloca(var->type, var->toChars());
|
||||
// add debug info
|
||||
|
@ -1300,22 +1303,22 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
|
|||
// nested variable?
|
||||
// A variable may not be really nested even if nextedrefs is not empty
|
||||
// in case it is referenced by a function inside __traits(compile) or typeof.
|
||||
if (var->nestedrefs.dim && var->ir.irLocal)
|
||||
if (var->nestedrefs.dim && isIrLocalCreated(var))
|
||||
{
|
||||
if(!var->ir.irLocal->value)
|
||||
if (!irLocal->value)
|
||||
{
|
||||
assert(addr);
|
||||
var->ir.irLocal->value = addr;
|
||||
irLocal->value = addr;
|
||||
}
|
||||
else
|
||||
assert(!addr || addr == var->ir.irLocal->value);
|
||||
assert(!addr || addr == irLocal->value);
|
||||
}
|
||||
// normal local variable
|
||||
else
|
||||
{
|
||||
// if this already has storage, it must've been handled already
|
||||
if (var->ir.irLocal && var->ir.irLocal->value) {
|
||||
if (addr && addr != var->ir.irLocal->value) {
|
||||
if (irLocal && irLocal->value) {
|
||||
if (addr && addr != irLocal->value) {
|
||||
// This can happen, for example, in scope(exit) blocks which
|
||||
// are translated to IR multiple times.
|
||||
// That *should* only happen after the first one is completely done
|
||||
|
@ -1323,21 +1326,22 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
|
|||
IF_LOG {
|
||||
Logger::println("Replacing LLVM address of %s", var->toChars());
|
||||
LOG_SCOPE;
|
||||
Logger::cout() << "Old val: " << *var->ir.irLocal->value << '\n';
|
||||
Logger::cout() << "Old val: " << *irLocal->value << '\n';
|
||||
Logger::cout() << "New val: " << *addr << '\n';
|
||||
}
|
||||
var->ir.irLocal->value = addr;
|
||||
irLocal->value = addr;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
assert(!var->ir.isSet());
|
||||
assert(addr);
|
||||
var->ir.irLocal = new IrLocal(var, addr);
|
||||
if (!irLocal)
|
||||
irLocal = getIrLocal(var, true);
|
||||
irLocal->value = addr;
|
||||
}
|
||||
|
||||
// return the alloca
|
||||
return var->ir.irLocal->value;
|
||||
return irLocal->value;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
@ -1473,9 +1477,8 @@ LLConstant* DtoTypeInfoOf(Type* type, bool base)
|
|||
TypeInfoDeclaration* tidecl = type->vtinfo;
|
||||
assert(tidecl);
|
||||
Declaration_codegen(tidecl);
|
||||
assert(tidecl->ir.irGlobal != NULL);
|
||||
assert(tidecl->ir.irGlobal->value != NULL);
|
||||
LLConstant* c = isaConstant(tidecl->ir.irGlobal->value);
|
||||
assert(getIrGlobal(tidecl)->value != NULL);
|
||||
LLConstant* c = isaConstant(getIrGlobal(tidecl)->value);
|
||||
assert(c != NULL);
|
||||
if (base)
|
||||
return llvm::ConstantExpr::getBitCast(c, DtoType(Type::dtypeinfo->type));
|
||||
|
@ -1575,18 +1578,6 @@ bool hasUnalignedFields(Type* t)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrModule * getIrModule(Module * M)
|
||||
{
|
||||
if (M == NULL)
|
||||
M = gIR->func()->decl->getModule();
|
||||
assert(M && "null module");
|
||||
if (!M->ir.irModule)
|
||||
M->ir.irModule = new IrModule(M, M->srcfile->toChars());
|
||||
return M->ir.irModule;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t realignOffset(size_t offset, Type* type)
|
||||
{
|
||||
size_t alignsize = type->alignsize();
|
||||
|
@ -1684,7 +1675,7 @@ void callPostblit(Loc& loc, Expression *exp, LLValue *val)
|
|||
fd->toParent()->error(loc, "is not copyable because it is annotated with @disable");
|
||||
DtoResolveFunction(fd);
|
||||
Expressions args;
|
||||
DFuncValue dfn(fd, fd->ir.irFunc->func, val);
|
||||
DFuncValue dfn(fd, getIrFunc(fd)->func, val);
|
||||
DtoCallFunction(loc, Type::basic[Tvoid], &dfn, &args);
|
||||
}
|
||||
}
|
||||
|
@ -1802,7 +1793,7 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl)
|
|||
{
|
||||
Logger::println("Id::dollar");
|
||||
LLValue* val = 0;
|
||||
if (vd->ir.isSet() && (val = vd->ir.getIrValue()))
|
||||
if (isIrVarCreated(vd) && (val = getIrValue(vd)))
|
||||
{
|
||||
// It must be length of a range
|
||||
return new DVarValue(type, vd, val);
|
||||
|
@ -1816,16 +1807,16 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl)
|
|||
{
|
||||
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
||||
DtoResolveClass(cid->cd);
|
||||
return new DVarValue(type, vd, cid->cd->ir.irAggr->getClassInfoSymbol());
|
||||
return new DVarValue(type, vd, getIrAggr(cid->cd)->getClassInfoSymbol());
|
||||
}
|
||||
// typeinfo
|
||||
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
||||
{
|
||||
Logger::println("TypeInfoDeclaration");
|
||||
DtoResolveTypeInfo(tid);
|
||||
assert(tid->ir.getIrValue());
|
||||
assert(getIrValue(tid));
|
||||
LLType* vartype = DtoType(type);
|
||||
LLValue* m = tid->ir.getIrValue();
|
||||
LLValue* m = getIrValue(tid);
|
||||
if (m->getType() != getPtrToType(vartype))
|
||||
m = gIR->ir->CreateBitCast(m, vartype, "tmp");
|
||||
return new DImValue(type, m);
|
||||
|
@ -1853,16 +1844,16 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl)
|
|||
{
|
||||
Logger::println("lazy parameter");
|
||||
assert(type->ty == Tdelegate);
|
||||
return new DVarValue(type, vd->ir.getIrValue());
|
||||
return new DVarValue(type, getIrValue(vd));
|
||||
}
|
||||
else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) ||
|
||||
llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue()))
|
||||
llvm::isa<llvm::AllocaInst>(getIrValue(vd)))
|
||||
{
|
||||
return new DVarValue(type, vd, vd->ir.getIrValue());
|
||||
return new DVarValue(type, vd, getIrValue(vd));
|
||||
}
|
||||
else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue()))
|
||||
else if (llvm::isa<llvm::Argument>(getIrValue(vd)))
|
||||
{
|
||||
return new DImValue(type, vd->ir.getIrValue());
|
||||
return new DImValue(type, getIrValue(vd));
|
||||
}
|
||||
else llvm_unreachable("Unexpected parameter value.");
|
||||
}
|
||||
|
@ -1875,9 +1866,9 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl)
|
|||
if (isGlobal)
|
||||
DtoResolveVariable(vd);
|
||||
|
||||
assert(vd->ir.isSet() && "Variable not resolved.");
|
||||
assert(isIrVarCreated(vd) && "Variable not resolved.");
|
||||
|
||||
llvm::Value* val = vd->ir.getIrValue();
|
||||
llvm::Value* val = getIrValue(vd);
|
||||
assert(val && "Variable value not set yet.");
|
||||
|
||||
if (isGlobal)
|
||||
|
@ -1910,8 +1901,7 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl)
|
|||
fatal();
|
||||
}
|
||||
DtoResolveFunction(fdecl);
|
||||
assert(fdecl->llvmInternal == LLVMva_arg || fdecl->ir.irFunc);
|
||||
return new DFuncValue(fdecl, fdecl->ir.irFunc ? fdecl->ir.irFunc->func : 0);
|
||||
return new DFuncValue(fdecl, fdecl->llvmInternal != LLVMva_arg ? getIrFunc(fdecl)->func : 0);
|
||||
}
|
||||
|
||||
if (SymbolDeclaration* sdecl = decl->isSymbolDeclaration())
|
||||
|
@ -1924,7 +1914,7 @@ DValue* DtoSymbolAddress(Loc& loc, Type* type, Declaration* decl)
|
|||
assert(ts->sym);
|
||||
DtoResolveStruct(ts->sym);
|
||||
|
||||
LLValue* initsym = ts->sym->ir.irAggr->getInitSymbol();
|
||||
LLValue* initsym = getIrAggr(ts->sym)->getInitSymbol();
|
||||
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
|
||||
return new DVarValue(type, initsym);
|
||||
}
|
||||
|
@ -1959,7 +1949,7 @@ llvm::Constant* DtoConstSymbolAddress(Loc& loc, Declaration* decl)
|
|||
}
|
||||
|
||||
DtoResolveVariable(vd);
|
||||
LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue());
|
||||
LLConstant* llc = llvm::dyn_cast<LLConstant>(getIrValue(vd));
|
||||
assert(llc);
|
||||
return llc;
|
||||
}
|
||||
|
@ -1967,8 +1957,7 @@ llvm::Constant* DtoConstSymbolAddress(Loc& loc, Declaration* decl)
|
|||
else if (FuncDeclaration* fd = decl->isFuncDeclaration())
|
||||
{
|
||||
DtoResolveFunction(fd);
|
||||
IrFunction* irfunc = fd->ir.irFunc;
|
||||
return irfunc->func;
|
||||
return getIrFunc(fd)->func;
|
||||
}
|
||||
|
||||
llvm_unreachable("Taking constant address not implemented.");
|
||||
|
|
|
@ -147,9 +147,6 @@ bool hasUnalignedFields(Type* t);
|
|||
///
|
||||
DValue* DtoInlineAsmExpr(Loc& loc, FuncDeclaration* fd, Expressions* arguments);
|
||||
|
||||
/// Create the IrModule if necessary and returns it.
|
||||
IrModule* getIrModule(Module* M);
|
||||
|
||||
/// Update an offset to make sure it follows both the D and LLVM alignments.
|
||||
/// Returns the offset rounded up to the closest safely aligned offset.
|
||||
size_t realignOffset(size_t offset, Type* type);
|
||||
|
|
|
@ -186,7 +186,7 @@ static llvm::Function* build_module_function(const std::string &name, const std:
|
|||
return NULL;
|
||||
|
||||
if (funcs.size() == 1)
|
||||
return funcs.front()->ir.irFunc->func;
|
||||
return getIrFunc(funcs.front())->func;
|
||||
}
|
||||
|
||||
std::vector<LLType*> argsTy;
|
||||
|
@ -207,7 +207,7 @@ static llvm::Function* build_module_function(const std::string &name, const std:
|
|||
// Call ctor's
|
||||
typedef std::list<FuncDeclaration*>::const_iterator FuncIterator;
|
||||
for (FuncIterator itr = funcs.begin(), end = funcs.end(); itr != end; ++itr) {
|
||||
llvm::Function* f = (*itr)->ir.irFunc->func;
|
||||
llvm::Function* f = getIrFunc(*itr)->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(gABI->callingConv(LINKd));
|
||||
}
|
||||
|
@ -215,8 +215,8 @@ static llvm::Function* build_module_function(const std::string &name, const std:
|
|||
// Increment vgate's
|
||||
typedef std::list<VarDeclaration*>::const_iterator GatesIterator;
|
||||
for (GatesIterator itr = gates.begin(), end = gates.end(); itr != end; ++itr) {
|
||||
assert((*itr)->ir.irGlobal);
|
||||
llvm::Value* val = (*itr)->ir.irGlobal->value;
|
||||
assert(getIrGlobal(*itr));
|
||||
llvm::Value* val = getIrGlobal(*itr)->value;
|
||||
llvm::Value* rval = builder.CreateLoad(val, "vgate");
|
||||
llvm::Value* res = builder.CreateAdd(rval, DtoConstUint(1), "vgate");
|
||||
builder.CreateStore(res, val);
|
||||
|
@ -781,7 +781,7 @@ void Module::genmoduleinfo()
|
|||
continue;
|
||||
}
|
||||
IF_LOG Logger::println("class: %s", cd->toPrettyChars());
|
||||
LLConstant *c = DtoBitCast(cd->ir.irAggr->getClassInfoSymbol(), classinfoTy);
|
||||
LLConstant *c = DtoBitCast(getIrAggr(cd)->getClassInfoSymbol(), classinfoTy);
|
||||
classInits.push_back(c);
|
||||
}
|
||||
// has class array?
|
||||
|
|
|
@ -147,8 +147,7 @@ void DtoDefineNakedFunction(FuncDeclaration* fd)
|
|||
IF_LOG Logger::println("DtoDefineNakedFunction(%s)", fd->mangleExact());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(fd->ir.irFunc);
|
||||
gIR->functions.push_back(fd->ir.irFunc);
|
||||
gIR->functions.push_back(getIrFunc(fd));
|
||||
|
||||
// we need to do special processing on the body, since we only want
|
||||
// to allow actual inline asm blocks to reach the final asm output
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace cl = llvm::cl;
|
|||
|
||||
static void storeVariable(VarDeclaration *vd, LLValue *dst)
|
||||
{
|
||||
LLValue *value = vd->ir.irLocal->value;
|
||||
LLValue *value = getIrLocal(vd)->value;
|
||||
int ty = vd->type->ty;
|
||||
FuncDeclaration *fd = getParentFunc(vd, true);
|
||||
assert(fd && "No parent function for nested variable?");
|
||||
|
@ -69,7 +69,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref
|
|||
// is the nested variable in this scope?
|
||||
if (vdparent == irfunc->decl)
|
||||
{
|
||||
LLValue* val = vd->ir.getIrValue();
|
||||
LLValue* val = getIrValue(vd);
|
||||
return new DVarValue(astype, vd, val);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref
|
|||
LLValue* val = irfunc->thisArg;
|
||||
if (cd->isClassDeclaration())
|
||||
val = DtoLoad(val);
|
||||
ctx = DtoLoad(DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis"));
|
||||
ctx = DtoLoad(DtoGEPi(val, 0, getIrField(cd->vthis)->index, ".vthis"));
|
||||
} else {
|
||||
// Otherwise, this is a simple nested function, load from the context
|
||||
// argument.
|
||||
|
@ -101,7 +101,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref
|
|||
assert(ctx);
|
||||
|
||||
DtoCreateNestedContextType(vdparent->isFuncDeclaration());
|
||||
assert(vd->ir.irLocal);
|
||||
assert(isIrLocalCreated(vd));
|
||||
|
||||
////////////////////////////////////
|
||||
// Extract variable from nested context
|
||||
|
@ -112,7 +112,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref
|
|||
Logger::cout() << "of type: " << *irfunc->frameType << '\n';
|
||||
}
|
||||
|
||||
unsigned vardepth = vd->ir.irLocal->nestedDepth;
|
||||
unsigned vardepth = getIrLocal(vd)->nestedDepth;
|
||||
unsigned funcdepth = irfunc->depth;
|
||||
|
||||
IF_LOG {
|
||||
|
@ -129,17 +129,17 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref
|
|||
} else {
|
||||
// Load frame pointer and index that...
|
||||
if (dwarfValue && global.params.symdebug) {
|
||||
gIR->DBuilder.OpOffset(dwarfAddr, val, vd->ir.irLocal->nestedDepth);
|
||||
gIR->DBuilder.OpOffset(dwarfAddr, val, vardepth);
|
||||
gIR->DBuilder.OpDeref(dwarfAddr);
|
||||
}
|
||||
IF_LOG Logger::println("Lower depth");
|
||||
val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth);
|
||||
val = DtoGEPi(val, 0, vardepth);
|
||||
IF_LOG Logger::cout() << "Frame index: " << *val << '\n';
|
||||
val = DtoAlignedLoad(val, (std::string(".frame.") + vdparent->toChars()).c_str());
|
||||
IF_LOG Logger::cout() << "Frame: " << *val << '\n';
|
||||
}
|
||||
|
||||
int idx = vd->ir.irLocal->nestedIndex;
|
||||
int idx = getIrLocal(vd)->nestedIndex;
|
||||
assert(idx != -1 && "Nested context not yet resolved for variable.");
|
||||
|
||||
if (dwarfValue && global.params.symdebug)
|
||||
|
@ -150,7 +150,7 @@ DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref
|
|||
Logger::cout() << "Addr: " << *val << '\n';
|
||||
Logger::cout() << "of type: " << *val->getType() << '\n';
|
||||
}
|
||||
if (byref || (vd->isParameter() && vd->ir.irParam->arg->byref)) {
|
||||
if (byref || (vd->isParameter() && getIrParameter(vd)->arg->byref)) {
|
||||
val = DtoAlignedLoad(val);
|
||||
//dwarfOpDeref(dwarfAddr);
|
||||
IF_LOG {
|
||||
|
@ -183,7 +183,7 @@ void DtoResolveNestedContext(Loc& loc, AggregateDeclaration *decl, LLValue *valu
|
|||
// our codegen order.
|
||||
DtoResolveDsymbol(decl);
|
||||
|
||||
size_t idx = decl->vthis->ir.irField->index;
|
||||
size_t idx = getIrField(decl->vthis)->index;
|
||||
LLValue* gep = DtoGEPi(value,0,idx,".vthis");
|
||||
DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym)
|
|||
// function (but without any variables in the nested context).
|
||||
return val;
|
||||
}
|
||||
val = DtoLoad(DtoGEPi(val, 0, ad->vthis->ir.irField->index, ".vthis"));
|
||||
val = DtoLoad(DtoGEPi(val, 0, getIrField(ad->vthis)->index, ".vthis"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -242,7 +242,7 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym)
|
|||
|
||||
// if this is for a function that doesn't access variables from
|
||||
// enclosing scopes, it doesn't matter what we pass.
|
||||
if (symfd->ir.irFunc->depth == -1)
|
||||
if (getIrFunc(symfd)->depth == -1)
|
||||
return llvm::UndefValue::get(getVoidPtrType());
|
||||
|
||||
// If sym is a nested function, and its parent context is different
|
||||
|
@ -260,8 +260,8 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym)
|
|||
}
|
||||
IF_LOG Logger::println("Context is from %s", ctxfd->toChars());
|
||||
|
||||
unsigned neededDepth = frameToPass->ir.irFunc->depth;
|
||||
unsigned ctxDepth = ctxfd->ir.irFunc->depth;
|
||||
unsigned neededDepth = getIrFunc(frameToPass)->depth;
|
||||
unsigned ctxDepth = getIrFunc(ctxfd)->depth;
|
||||
|
||||
IF_LOG {
|
||||
Logger::cout() << "Needed depth: " << neededDepth << '\n';
|
||||
|
@ -273,7 +273,7 @@ LLValue* DtoNestedContext(Loc& loc, Dsymbol* sym)
|
|||
// fd needs the same context as we do, so all is well
|
||||
IF_LOG Logger::println("Calling sibling function or directly nested function");
|
||||
} else {
|
||||
val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType));
|
||||
val = DtoBitCast(val, LLPointerType::getUnqual(getIrFunc(ctxfd)->frameType));
|
||||
val = DtoGEPi(val, 0, neededDepth);
|
||||
val = DtoAlignedLoad(val,
|
||||
(std::string(".frame.") + frameToPass->toChars()).c_str());
|
||||
|
@ -293,9 +293,9 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
|
|||
|
||||
DtoDeclareFunction(fd);
|
||||
|
||||
if (fd->ir.irFunc->nestedContextCreated)
|
||||
if (getIrFunc(fd)->nestedContextCreated)
|
||||
return;
|
||||
fd->ir.irFunc->nestedContextCreated = true;
|
||||
getIrFunc(fd)->nestedContextCreated = true;
|
||||
|
||||
// construct nested variables array
|
||||
if (fd->closureVars.dim > 0)
|
||||
|
@ -316,12 +316,12 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
|
|||
// Make sure the parent has already been analyzed.
|
||||
DtoCreateNestedContextType(parfd);
|
||||
|
||||
innerFrameType = parfd->ir.irFunc->frameType;
|
||||
innerFrameType = getIrFunc(parfd)->frameType;
|
||||
if (innerFrameType)
|
||||
depth = parfd->ir.irFunc->depth;
|
||||
depth = getIrFunc(parfd)->depth;
|
||||
}
|
||||
}
|
||||
fd->ir.irFunc->depth = ++depth;
|
||||
getIrFunc(fd)->depth = ++depth;
|
||||
|
||||
IF_LOG Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
|
||||
|
||||
|
@ -352,15 +352,14 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
|
|||
E = fd->closureVars.end();
|
||||
I != E; ++I) {
|
||||
VarDeclaration* vd = *I;
|
||||
if (!vd->ir.irLocal)
|
||||
vd->ir.irLocal = new IrLocal(vd);
|
||||
IrLocal *irLocal = getIrLocal(vd, true);
|
||||
irLocal->nestedIndex = types.size();
|
||||
irLocal->nestedDepth = depth;
|
||||
|
||||
vd->ir.irLocal->nestedIndex = types.size();
|
||||
vd->ir.irLocal->nestedDepth = depth;
|
||||
if (vd->isParameter()) {
|
||||
// Parameters will have storage associated with them (to handle byref etc.),
|
||||
// so handle those cases specially by storing a pointer instead of a value.
|
||||
const IrParameter* irparam = vd->ir.irParam;
|
||||
const IrParameter* irparam = getIrParameter(vd);
|
||||
const bool refout = vd->storage_class & (STCref | STCout);
|
||||
const bool lazy = vd->storage_class & STClazy;
|
||||
const bool byref = irparam->arg->byref;
|
||||
|
@ -389,12 +388,12 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
|
|||
IF_LOG Logger::cout() << "frameType = " << *frameType << '\n';
|
||||
|
||||
// Store type in IrFunction
|
||||
fd->ir.irFunc->frameType = frameType;
|
||||
getIrFunc(fd)->frameType = frameType;
|
||||
} else if (FuncDeclaration* parFunc = getParentFunc(fd, true)) {
|
||||
// Propagate context arg properties if the context arg is passed on unmodified.
|
||||
DtoCreateNestedContextType(parFunc);
|
||||
fd->ir.irFunc->frameType = parFunc->ir.irFunc->frameType;
|
||||
fd->ir.irFunc->depth = parFunc->ir.irFunc->depth;
|
||||
getIrFunc(fd)->frameType = getIrFunc(parFunc)->frameType;
|
||||
getIrFunc(fd)->depth = getIrFunc(parFunc)->depth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +407,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
// construct nested variables array
|
||||
if (fd->closureVars.dim > 0)
|
||||
{
|
||||
IrFunction* irfunction = fd->ir.irFunc;
|
||||
IrFunction* irfunction = getIrFunc(fd);
|
||||
unsigned depth = irfunction->depth;
|
||||
LLStructType *frameType = irfunction->frameType;
|
||||
// Create frame for current function and append to frames list
|
||||
|
@ -432,9 +431,9 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
assert(cd->vthis);
|
||||
Logger::println("Indexing to 'this'");
|
||||
if (cd->isStructDeclaration())
|
||||
src = DtoExtractValue(thisval, cd->vthis->ir.irField->index, ".vthis");
|
||||
src = DtoExtractValue(thisval, getIrField(cd->vthis)->index, ".vthis");
|
||||
else
|
||||
src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis"));
|
||||
src = DtoLoad(DtoGEPi(thisval, 0, getIrField(cd->vthis)->index, ".vthis"));
|
||||
} else {
|
||||
src = DtoLoad(src);
|
||||
}
|
||||
|
@ -465,11 +464,12 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
vd->error("has scoped destruction, cannot build closure");
|
||||
}
|
||||
|
||||
LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
|
||||
IrLocal *irLocal = getIrLocal(vd);
|
||||
LLValue* gep = DtoGEPi(frame, 0, irLocal->nestedIndex, vd->toChars());
|
||||
if (vd->isParameter()) {
|
||||
IF_LOG Logger::println("nested param: %s", vd->toChars());
|
||||
LOG_SCOPE
|
||||
IrParameter* parm = vd->ir.irParam;
|
||||
IrParameter* parm = getIrParameter(vd);
|
||||
|
||||
if (parm->arg->byref)
|
||||
{
|
||||
|
@ -487,13 +487,13 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
}
|
||||
} else {
|
||||
IF_LOG Logger::println("nested var: %s", vd->toChars());
|
||||
assert(!vd->ir.irLocal->value);
|
||||
vd->ir.irLocal->value = gep;
|
||||
assert(!irLocal->value);
|
||||
irLocal->value = gep;
|
||||
}
|
||||
|
||||
if (global.params.symdebug) {
|
||||
LLSmallVector<LLValue*, 2> addr;
|
||||
gIR->DBuilder.OpOffset(addr, frameType, vd->ir.irLocal->nestedIndex);
|
||||
gIR->DBuilder.OpOffset(addr, frameType, irLocal->nestedIndex);
|
||||
gIR->DBuilder.EmitLocalVariable(frame, vd, addr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ RTTIBuilder::RTTIBuilder(AggregateDeclaration* base_class)
|
|||
base = base_class;
|
||||
basetype = static_cast<TypeClass*>(base->type);
|
||||
|
||||
baseir = base->ir.irAggr;
|
||||
baseir = getIrAggr(base);
|
||||
assert(baseir && "no IrStruct for TypeInfo base class");
|
||||
|
||||
if (base->isClassDeclaration()) {
|
||||
|
@ -59,7 +59,7 @@ void RTTIBuilder::push_typeinfo(Type* t)
|
|||
|
||||
void RTTIBuilder::push_classinfo(ClassDeclaration* cd)
|
||||
{
|
||||
inits.push_back(cd->ir.irAggr->getClassInfoSymbol());
|
||||
inits.push_back(getIrAggr(cd)->getClassInfoSymbol());
|
||||
}
|
||||
|
||||
void RTTIBuilder::push_string(const char* str)
|
||||
|
@ -137,7 +137,7 @@ void RTTIBuilder::push_funcptr(FuncDeclaration* fd, Type* castto)
|
|||
if (fd)
|
||||
{
|
||||
DtoResolveFunction(fd);
|
||||
LLConstant* F = fd->ir.irFunc->func;
|
||||
LLConstant* F = getIrFunc(fd)->func;
|
||||
if (castto)
|
||||
F = DtoBitCast(F, DtoType(castto));
|
||||
inits.push_back(F);
|
||||
|
|
|
@ -150,12 +150,12 @@ public:
|
|||
{
|
||||
// sanity check
|
||||
IrFunction* f = irs->func();
|
||||
assert(f->decl->ir.irFunc->retArg);
|
||||
assert(getIrFunc(f->decl)->retArg);
|
||||
|
||||
// FIXME: is there ever a case where a sret return needs to be rewritten for the ABI?
|
||||
|
||||
// get return pointer
|
||||
DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg);
|
||||
DValue* rvar = new DVarValue(f->type->next, getIrFunc(f->decl)->retArg);
|
||||
DValue* e = stmt->exp->toElemDtor(irs);
|
||||
// store return value
|
||||
if (rvar->getLVal() != e->getRVal())
|
||||
|
@ -1205,7 +1205,7 @@ public:
|
|||
if (!stmt->value->isRef() && !stmt->value->isOut()) {
|
||||
// Create a local variable to serve as the value.
|
||||
DtoRawVarDeclaration(stmt->value);
|
||||
valvar = stmt->value->ir.irLocal->value;
|
||||
valvar = getIrLocal(stmt->value)->value;
|
||||
}
|
||||
|
||||
// what to iterate
|
||||
|
@ -1269,7 +1269,7 @@ public:
|
|||
DVarValue dst(stmt->value->type, valvar);
|
||||
DVarValue src(stmt->value->type, gep);
|
||||
DtoAssign(stmt->loc, &dst, &src);
|
||||
stmt->value->ir.irLocal->value = valvar;
|
||||
getIrLocal(stmt->value)->value = valvar;
|
||||
} else {
|
||||
// Use the GEP as the address of the value variable.
|
||||
DtoRawVarDeclaration(stmt->value, gep);
|
||||
|
|
|
@ -53,8 +53,7 @@ void DtoResolveStruct(StructDeclaration* sd, Loc& callerLoc)
|
|||
}
|
||||
|
||||
// create the IrAggr
|
||||
IrAggr* iraggr = new IrAggr(sd);
|
||||
sd->ir.irAggr = iraggr;
|
||||
getIrAggr(sd, true);
|
||||
|
||||
// Set up our field metadata.
|
||||
for (VarDeclarations::iterator I = sd->fields.begin(),
|
||||
|
@ -62,8 +61,8 @@ void DtoResolveStruct(StructDeclaration* sd, Loc& callerLoc)
|
|||
I != E; ++I)
|
||||
{
|
||||
VarDeclaration *vd = *I;
|
||||
assert(!vd->ir.irField);
|
||||
(void)new IrField(vd);
|
||||
assert(!isIrFieldCreated(vd));
|
||||
getIrField(vd, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +98,7 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
|
|||
DtoResolveStruct(sd);
|
||||
|
||||
// vd must be a field
|
||||
IrField* field = vd->ir.irField;
|
||||
IrField* field = getIrField(vd);
|
||||
assert(field);
|
||||
|
||||
// get the start pointer
|
||||
|
|
44
gen/toir.cpp
44
gen/toir.cpp
|
@ -205,7 +205,7 @@ LLConstant* VarExp::toConstElem(IRState* p)
|
|||
assert(sdecltype->ty == Tstruct);
|
||||
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
|
||||
DtoResolveStruct(ts->sym);
|
||||
return ts->sym->ir.irAggr->getDefaultInit();
|
||||
return getIrAggr(ts->sym)->getDefaultInit();
|
||||
}
|
||||
|
||||
if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
|
||||
|
@ -1238,7 +1238,7 @@ LLConstant* CastExp::toConstElem(IRState* p)
|
|||
VarDeclaration *vd = static_cast<VarExp*>(e1)->var->isVarDeclaration();
|
||||
assert(vd);
|
||||
DtoResolveVariable(vd);
|
||||
LLConstant *value = vd->ir.irGlobal ? isaConstant(vd->ir.irGlobal->value) : 0;
|
||||
LLConstant *value = isIrGlobalCreated(vd) ? isaConstant(getIrGlobal(vd)->value) : 0;
|
||||
if (!value)
|
||||
goto Lerr;
|
||||
Type *type = vd->type->toBasetype();
|
||||
|
@ -1405,7 +1405,7 @@ DValue* AddrExp::toElem(IRState* p)
|
|||
FuncDeclaration* fd = fv->func;
|
||||
assert(fd);
|
||||
DtoResolveFunction(fd);
|
||||
return new DFuncValue(fd, fd->ir.irFunc->func);
|
||||
return new DFuncValue(fd, getIrFunc(fd)->func);
|
||||
}
|
||||
else if (v->isIm()) {
|
||||
Logger::println("is immediate");
|
||||
|
@ -1456,7 +1456,7 @@ LLConstant* AddrExp::toConstElem(IRState* p)
|
|||
assert(vd);
|
||||
assert(vd->type->toBasetype()->ty == Tsarray);
|
||||
DtoResolveVariable(vd);
|
||||
assert(vd->ir.irGlobal);
|
||||
assert(isIrGlobalCreated(vd));
|
||||
|
||||
// get index
|
||||
LLConstant* index = iexp->e2->toConstElem(p);
|
||||
|
@ -1464,7 +1464,7 @@ LLConstant* AddrExp::toConstElem(IRState* p)
|
|||
|
||||
// gep
|
||||
LLConstant* idxs[2] = { DtoConstSize_t(0), index };
|
||||
LLConstant *val = isaConstant(vd->ir.irGlobal->value);
|
||||
LLConstant *val = isaConstant(getIrGlobal(vd)->value);
|
||||
val = DtoBitCast(val, DtoType(vd->type->pointerTo()));
|
||||
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(val, idxs, true);
|
||||
|
||||
|
@ -1681,7 +1681,7 @@ DValue* DotVarExp::toElem(IRState* p)
|
|||
}
|
||||
else
|
||||
{
|
||||
funcval = fdecl->ir.irFunc->func;
|
||||
funcval = getIrFunc(fdecl)->func;
|
||||
}
|
||||
assert(funcval);
|
||||
|
||||
|
@ -2170,7 +2170,7 @@ DValue* NewExp::toElem(IRState* p)
|
|||
{
|
||||
// custom allocator
|
||||
DtoResolveFunction(allocator);
|
||||
DFuncValue dfn(allocator, allocator->ir.irFunc->func);
|
||||
DFuncValue dfn(allocator, getIrFunc(allocator)->func);
|
||||
DValue* res = DtoCallFunction(loc, NULL, &dfn, newargs);
|
||||
mem = DtoBitCast(res->getRVal(), DtoType(ntype->pointerTo()), ".newstruct_custom");
|
||||
} else
|
||||
|
@ -2186,7 +2186,7 @@ DValue* NewExp::toElem(IRState* p)
|
|||
else {
|
||||
assert(ts->sym);
|
||||
DtoResolveStruct(ts->sym, loc);
|
||||
DtoAggrCopy(mem, ts->sym->ir.irAggr->getInitSymbol());
|
||||
DtoAggrCopy(mem, getIrAggr(ts->sym)->getInitSymbol());
|
||||
}
|
||||
if (ts->sym->isNested() && ts->sym->vthis)
|
||||
DtoResolveNestedContext(loc, ts->sym, mem);
|
||||
|
@ -2197,7 +2197,7 @@ DValue* NewExp::toElem(IRState* p)
|
|||
Logger::println("Calling constructor");
|
||||
assert(arguments != NULL);
|
||||
DtoResolveFunction(member);
|
||||
DFuncValue dfn(member, member->ir.irFunc->func, mem);
|
||||
DFuncValue dfn(member, getIrFunc(member)->func, mem);
|
||||
DtoCallFunction(loc, ts, &dfn, arguments);
|
||||
}
|
||||
return new DImValue(type, mem);
|
||||
|
@ -2360,7 +2360,7 @@ DValue* AssertExp::toElem(IRState* p)
|
|||
{
|
||||
Logger::print("calling struct invariant");
|
||||
DtoResolveFunction(invdecl);
|
||||
DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal());
|
||||
DFuncValue invfunc(invdecl, getIrFunc(invdecl)->func, cond->getRVal());
|
||||
DtoCallFunction(loc, NULL, &invfunc, NULL);
|
||||
}
|
||||
|
||||
|
@ -2601,7 +2601,7 @@ DValue* DelegateExp::toElem(IRState* p)
|
|||
}
|
||||
}
|
||||
|
||||
castfptr = func->ir.irFunc->func;
|
||||
castfptr = getIrFunc(func)->func;
|
||||
}
|
||||
|
||||
castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
|
||||
|
@ -2850,14 +2850,14 @@ DValue* FuncExp::toElem(IRState* p)
|
|||
// We need to actually codegen the function here, as literals are not added
|
||||
// to the module member list.
|
||||
Declaration_codegen(fd, p);
|
||||
if (!fd->ir.irFunc)
|
||||
if (!isIrFuncCreated(fd))
|
||||
{
|
||||
// See DtoDefineFunction for reasons why codegen was suppressed.
|
||||
// Instead just declare the function.
|
||||
DtoDeclareFunction(fd);
|
||||
assert(!fd->isNested());
|
||||
}
|
||||
assert(fd->ir.irFunc->func);
|
||||
assert(getIrFunc(fd)->func);
|
||||
|
||||
if (fd->isNested()) {
|
||||
LLType* dgty = DtoType(type);
|
||||
|
@ -2881,19 +2881,19 @@ DValue* FuncExp::toElem(IRState* p)
|
|||
cval = getNullPtr(getVoidPtrType());
|
||||
} else {
|
||||
cval = ad->isClassDeclaration() ? DtoLoad(irfn->thisArg) : irfn->thisArg;
|
||||
cval = DtoLoad(DtoGEPi(cval, 0,ad->vthis->ir.irField->index, ".vthis"));
|
||||
cval = DtoLoad(DtoGEPi(cval, 0, getIrField(ad->vthis)->index, ".vthis"));
|
||||
}
|
||||
}
|
||||
else
|
||||
cval = getNullPtr(getVoidPtrType());
|
||||
cval = DtoBitCast(cval, dgty->getContainedType(0));
|
||||
|
||||
LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, dgty->getContainedType(1));
|
||||
LLValue* castfptr = DtoBitCast(getIrFunc(fd)->func, dgty->getContainedType(1));
|
||||
|
||||
return new DImValue(type, DtoAggrPair(cval, castfptr, ".func"));
|
||||
|
||||
} else {
|
||||
return new DFuncValue(type, fd, fd->ir.irFunc->func);
|
||||
return new DFuncValue(type, fd, getIrFunc(fd)->func);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2927,9 +2927,9 @@ LLConstant* FuncExp::toConstElem(IRState* p)
|
|||
// We need to actually codegen the function here, as literals are not added
|
||||
// to the module member list.
|
||||
Declaration_codegen(fd, p);
|
||||
assert(fd->ir.irFunc->func);
|
||||
assert(getIrFunc(fd)->func);
|
||||
|
||||
return fd->ir.irFunc->func;
|
||||
return getIrFunc(fd)->func;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3061,7 +3061,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
|||
assert(ts->sym);
|
||||
DtoResolveStruct(ts->sym);
|
||||
|
||||
LLValue* initsym = ts->sym->ir.irAggr->getInitSymbol();
|
||||
LLValue* initsym = getIrAggr(ts->sym)->getInitSymbol();
|
||||
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
|
||||
return new DVarValue(type, initsym);
|
||||
}
|
||||
|
@ -3200,7 +3200,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
|||
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
|
||||
DtoResolveStruct(ts->sym);
|
||||
|
||||
return ts->sym->ir.irAggr->getDefaultInit();
|
||||
return getIrAggr(ts->sym)->getDefaultInit();
|
||||
}
|
||||
|
||||
// make sure the struct is resolved
|
||||
|
@ -3216,7 +3216,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
|||
}
|
||||
}
|
||||
|
||||
return sd->ir.irAggr->createInitializerConstant(varInits);
|
||||
return getIrAggr(sd)->createInitializerConstant(varInits);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3285,7 +3285,7 @@ llvm::Constant* ClassReferenceExp::toConstElem(IRState *p)
|
|||
assert(i == nexprs);
|
||||
}
|
||||
|
||||
llvm::Constant* constValue = origClass->ir.irAggr->createInitializerConstant(varInits);
|
||||
llvm::Constant* constValue = getIrAggr(origClass)->createInitializerConstant(varInits);
|
||||
|
||||
if (constValue->getType() != value->globalVar->getType()->getContainedType(0))
|
||||
{
|
||||
|
|
|
@ -307,7 +307,7 @@ static void emitTypeMetadata(TypeInfoDeclaration *tid)
|
|||
if (!meta) {
|
||||
// Construct the fields
|
||||
MDNodeField* mdVals[TD_NumFields];
|
||||
mdVals[TD_TypeInfo] = llvm::cast<MDNodeField>(tid->ir.irGlobal->value);
|
||||
mdVals[TD_TypeInfo] = llvm::cast<MDNodeField>(getIrGlobal(tid)->value);
|
||||
mdVals[TD_Type] = llvm::UndefValue::get(DtoType(tid->tinfo));
|
||||
|
||||
// Construct the metadata and insert it into the module.
|
||||
|
@ -342,8 +342,7 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState* p)
|
|||
Logger::println("typeinfo mangle: %s", mangled.c_str());
|
||||
}
|
||||
|
||||
IrGlobal* irg = new IrGlobal(decl);
|
||||
decl->ir.irGlobal = irg;
|
||||
IrGlobal* irg = getIrGlobal(decl, true);
|
||||
irg->value = gIR->module->getGlobalVariable(mangled);
|
||||
if (irg->value) {
|
||||
irg->type = irg->value->getType()->getContainedType(0);
|
||||
|
@ -378,7 +377,7 @@ void TypeInfoDeclaration::llvmDefine()
|
|||
LOG_SCOPE;
|
||||
|
||||
RTTIBuilder b(Type::dtypeinfo);
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -416,7 +415,7 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
|||
}
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -463,7 +462,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
|||
}
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -477,7 +476,7 @@ void TypeInfoPointerDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->nextOf());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -491,7 +490,7 @@ void TypeInfoArrayDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->nextOf());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -513,7 +512,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
|||
b.push(DtoConstSize_t(static_cast<size_t>(tc->dim->toUInteger())));
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -538,7 +537,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
|||
b.push_typeinfo(tc->getImpl()->type);
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -554,7 +553,7 @@ void TypeInfoFunctionDeclaration::llvmDefine()
|
|||
// string deco
|
||||
b.push_string(tinfo->deco);
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -573,7 +572,7 @@ void TypeInfoDelegateDeclaration::llvmDefine()
|
|||
// string deco
|
||||
b.push_string(tinfo->deco);
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -591,7 +590,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
|||
// handle opaque structs
|
||||
if (!sd->members) {
|
||||
RTTIBuilder b(Type::typeinfostruct);
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -603,7 +602,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
|||
}
|
||||
|
||||
DtoResolveStruct(sd);
|
||||
IrAggr* iraggr = sd->ir.irAggr;
|
||||
IrAggr* iraggr = getIrAggr(sd);
|
||||
|
||||
RTTIBuilder b(Type::typeinfostruct);
|
||||
|
||||
|
@ -692,7 +691,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
|||
b.push_size_as_vp(1); // has pointers
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -702,14 +701,13 @@ void TypeInfoClassDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p)
|
|||
// For classes, the TypeInfo is in fact a ClassInfo instance and emitted
|
||||
// as a __ClassZ symbol. For interfaces, the __InterfaceZ symbol is
|
||||
// referenced as "info" member in a (normal) TypeInfo_Interface instance.
|
||||
IrGlobal *irg = new IrGlobal(decl);
|
||||
decl->ir.irGlobal = irg;
|
||||
IrGlobal *irg = getIrGlobal(decl, true);
|
||||
|
||||
assert(decl->tinfo->ty == Tclass);
|
||||
TypeClass *tc = static_cast<TypeClass *>(decl->tinfo);
|
||||
DtoResolveClass(tc->sym);
|
||||
|
||||
irg->value = tc->sym->ir.irAggr->getClassInfoSymbol();
|
||||
irg->value = getIrAggr(tc->sym)->getClassInfoSymbol();
|
||||
irg->type = irg->value->getType()->getContainedType(0);
|
||||
|
||||
if (!tc->sym->isInterfaceDeclaration())
|
||||
|
@ -742,7 +740,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
|||
b.push_classinfo(tc->sym);
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -778,7 +776,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
|||
b.push_array(arrC, dim, Type::dtypeinfo->type, NULL);
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -792,7 +790,7 @@ void TypeInfoConstDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -806,7 +804,7 @@ void TypeInfoInvariantDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -820,7 +818,7 @@ void TypeInfoSharedDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->unSharedOf()->merge());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -834,7 +832,7 @@ void TypeInfoWildDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -851,5 +849,5 @@ void TypeInfoVectorDeclaration::llvmDefine()
|
|||
// TypeInfo base
|
||||
b.push_typeinfo(tv->basetype);
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
b.finalize(getIrGlobal(this));
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "gen/logger.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/iraggr.h"
|
||||
#include "irdsymbol.h"
|
||||
#include "ir/irtypeclass.h"
|
||||
#include "ir/irtypestruct.h"
|
||||
#include <algorithm>
|
||||
|
@ -376,3 +377,22 @@ void IrAggr::addFieldInitializers(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
IrAggr *getIrAggr(AggregateDeclaration *decl, bool create)
|
||||
{
|
||||
if (!isIrAggrCreated(decl) && create)
|
||||
{
|
||||
assert(decl->ir.irAggr == NULL);
|
||||
decl->ir.irAggr = new IrAggr(decl);
|
||||
decl->ir.m_type = IrDsymbol::AggrType;
|
||||
}
|
||||
assert(decl->ir.irAggr != NULL);
|
||||
return decl->ir.irAggr;
|
||||
}
|
||||
|
||||
bool isIrAggrCreated(AggregateDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
assert(t == IrDsymbol::AggrType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::AggrType;
|
||||
}
|
||||
|
|
|
@ -150,4 +150,7 @@ private:
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrAggr *getIrAggr(AggregateDeclaration *decl, bool create = false);
|
||||
bool isIrAggrCreated(AggregateDeclaration *decl);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -185,8 +185,8 @@ LLConstant * IrAggr::getVtblInit()
|
|||
else
|
||||
{
|
||||
DtoResolveFunction(fd);
|
||||
assert(fd->ir.irFunc && "invalid vtbl function");
|
||||
c = fd->ir.irFunc->func;
|
||||
assert(isIrFuncCreated(fd) && "invalid vtbl function");
|
||||
c = getIrFunc(fd)->func;
|
||||
if (cd->isFuncHidden(fd))
|
||||
{ /* fd is hidden from the view of this class.
|
||||
* If fd overlaps with any function in the vtbl[], then
|
||||
|
@ -321,9 +321,9 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
|
|||
"null symbol in interface implementation vtable");
|
||||
|
||||
DtoResolveFunction(fd);
|
||||
assert(fd->ir.irFunc && "invalid vtbl function");
|
||||
assert(isIrFuncCreated(fd) && "invalid vtbl function");
|
||||
|
||||
LLFunction *fn = fd->ir.irFunc->func;
|
||||
LLFunction *fn = getIrFunc(fd)->func;
|
||||
|
||||
// If the base is a cpp interface, 'this' parameter is a pointer to
|
||||
// the interface not the underlying object as expected. Instead of
|
||||
|
@ -445,7 +445,7 @@ LLConstant * IrAggr::getClassInfoInterfaces()
|
|||
|
||||
IF_LOG Logger::println("Adding interface %s", it->base->toPrettyChars());
|
||||
|
||||
IrAggr* irinter = it->base->ir.irAggr;
|
||||
IrAggr* irinter = getIrAggr(it->base);
|
||||
assert(irinter && "interface has null IrStruct");
|
||||
IrTypeClass* itc = stripModifiers(irinter->type)->irtype->isClass();
|
||||
assert(itc && "null interface IrTypeClass");
|
||||
|
|
|
@ -22,7 +22,8 @@ void IrDsymbol::resetAll()
|
|||
(*it)->reset();
|
||||
}
|
||||
|
||||
IrDsymbol::IrDsymbol()
|
||||
IrDsymbol::IrDsymbol() :
|
||||
m_type(NotSet)
|
||||
{
|
||||
list.push_back(this);
|
||||
reset();
|
||||
|
@ -31,12 +32,8 @@ IrDsymbol::IrDsymbol()
|
|||
IrDsymbol::IrDsymbol(const IrDsymbol& s)
|
||||
{
|
||||
list.push_back(this);
|
||||
irModule = s.irModule;
|
||||
irAggr = s.irAggr;
|
||||
irFunc = s.irFunc;
|
||||
irGlobal = s.irGlobal;
|
||||
irLocal = s.irLocal;
|
||||
irField = s.irField;
|
||||
irData = s.irData;
|
||||
m_type = s.m_type;
|
||||
resolved = s.resolved;
|
||||
declared = s.declared;
|
||||
initialized = s.initialized;
|
||||
|
@ -58,24 +55,6 @@ IrDsymbol::~IrDsymbol()
|
|||
|
||||
void IrDsymbol::reset()
|
||||
{
|
||||
irModule = NULL;
|
||||
irAggr = NULL;
|
||||
irFunc = NULL;
|
||||
irGlobal = NULL;
|
||||
irLocal = NULL;
|
||||
irField = NULL;
|
||||
irData = NULL;
|
||||
resolved = declared = initialized = defined = false;
|
||||
}
|
||||
|
||||
bool IrDsymbol::isSet()
|
||||
{
|
||||
return irAggr || irFunc || irGlobal || irLocal || irField;
|
||||
}
|
||||
|
||||
IrVar* IrDsymbol::getIrVar()
|
||||
{
|
||||
assert(irGlobal || irLocal || irField);
|
||||
return irGlobal ? static_cast<IrVar*>(irGlobal) : irLocal ? static_cast<IrVar*>(irLocal) : static_cast<IrVar*>(irField);
|
||||
}
|
||||
|
||||
llvm::Value*& IrDsymbol::getIrValue() { return getIrVar()->value; }
|
||||
|
|
|
@ -25,6 +25,9 @@ struct IrParameter;
|
|||
struct IrField;
|
||||
struct IrVar;
|
||||
class Dsymbol;
|
||||
class AggregateDeclaration;
|
||||
class FuncDeclaration;
|
||||
class VarDeclaration;
|
||||
class Module;
|
||||
|
||||
namespace llvm {
|
||||
|
@ -33,6 +36,18 @@ namespace llvm {
|
|||
|
||||
struct IrDsymbol
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
NotSet,
|
||||
ModuleType,
|
||||
AggrType,
|
||||
FuncType,
|
||||
GlobalType,
|
||||
LocalType,
|
||||
ParamterType,
|
||||
FieldType
|
||||
};
|
||||
|
||||
static std::vector<IrDsymbol*> list;
|
||||
static void resetAll();
|
||||
|
||||
|
@ -44,24 +59,34 @@ struct IrDsymbol
|
|||
|
||||
void reset();
|
||||
|
||||
IrModule* irModule;
|
||||
IrAggr* irAggr;
|
||||
IrFunction* irFunc;
|
||||
IrGlobal* irGlobal;
|
||||
union {
|
||||
IrLocal* irLocal;
|
||||
IrParameter *irParam;
|
||||
};
|
||||
IrField* irField;
|
||||
Type type() const { return m_type; }
|
||||
|
||||
bool resolved;
|
||||
bool declared;
|
||||
bool initialized;
|
||||
bool defined;
|
||||
private:
|
||||
friend IrModule* getIrModule(Module *m);
|
||||
friend IrAggr *getIrAggr(AggregateDeclaration *decl, bool create);
|
||||
friend IrFunction *getIrFunc(FuncDeclaration *decl, bool create);
|
||||
friend IrVar *getIrVar(VarDeclaration *decl);
|
||||
friend IrGlobal *getIrGlobal(VarDeclaration *decl, bool create);
|
||||
friend IrLocal *getIrLocal(VarDeclaration *decl, bool create);
|
||||
friend IrParameter *getIrParameter(VarDeclaration *decl, bool create);
|
||||
friend IrField *getIrField(VarDeclaration *decl, bool create);
|
||||
|
||||
IrVar* getIrVar();
|
||||
llvm::Value*& getIrValue();
|
||||
|
||||
bool isSet();
|
||||
Type m_type;
|
||||
union {
|
||||
void* irData;
|
||||
IrModule* irModule;
|
||||
IrAggr* irAggr;
|
||||
IrFunction* irFunc;
|
||||
IrVar* irVar;
|
||||
IrGlobal* irGlobal;
|
||||
IrLocal* irLocal;
|
||||
IrParameter* irParam;
|
||||
IrField* irField;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "gen/llvm.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irdsymbol.h"
|
||||
#include "ir/irfunction.h"
|
||||
#include <sstream>
|
||||
|
||||
|
@ -96,3 +97,22 @@ void IrFunction::setAlwaysInline()
|
|||
func->addFnAttr(llvm::Attribute::AlwaysInline);
|
||||
#endif
|
||||
}
|
||||
|
||||
IrFunction *getIrFunc(FuncDeclaration *decl, bool create)
|
||||
{
|
||||
if (!isIrFuncCreated(decl) && create)
|
||||
{
|
||||
assert(decl->ir.irFunc == NULL);
|
||||
decl->ir.irFunc = new IrFunction(decl);
|
||||
decl->ir.m_type = IrDsymbol::FuncType;
|
||||
}
|
||||
assert(decl->ir.irFunc != NULL);
|
||||
return decl->ir.irFunc;
|
||||
}
|
||||
|
||||
bool isIrFuncCreated(FuncDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
assert(t == IrDsymbol::FuncType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::FuncType;
|
||||
}
|
||||
|
|
|
@ -125,4 +125,7 @@ struct IrFunction
|
|||
std::stack<llvm::DILexicalBlock> diLexicalBlocks;
|
||||
};
|
||||
|
||||
IrFunction *getIrFunc(FuncDeclaration *decl, bool create = false);
|
||||
bool isIrFuncCreated(FuncDeclaration *decl);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -56,17 +56,17 @@ void IRLandingPadCatchInfo::toIR()
|
|||
// use the same storage for all exceptions that are not accessed in
|
||||
// nested functions
|
||||
if (!catchStmt->var->nestedrefs.dim) {
|
||||
assert(!catchStmt->var->ir.irLocal);
|
||||
catchStmt->var->ir.irLocal = new IrLocal(catchStmt->var);
|
||||
assert(!isIrLocalCreated(catchStmt->var));
|
||||
IrLocal *irLocal = getIrLocal(catchStmt->var, true);
|
||||
LLValue* catch_var = gIR->func()->gen->landingPadInfo.getExceptionStorage();
|
||||
catchStmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchStmt->var->type)));
|
||||
irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchStmt->var->type)));
|
||||
} else {
|
||||
// this will alloca if we haven't already and take care of nested refs
|
||||
DtoDeclarationExp(catchStmt->var);
|
||||
|
||||
// the exception will only be stored in catch_var. copy it over if necessary
|
||||
LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->gen->landingPadInfo.getExceptionStorage()), DtoType(catchStmt->var->type));
|
||||
DtoStore(exc, catchStmt->var->ir.irLocal->value);
|
||||
DtoStore(exc, getIrLocal(catchStmt->var)->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ void IRLandingPad::constructLandingPad(IRLandingPadScope scope)
|
|||
// create next block
|
||||
llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend());
|
||||
// get class info symbol
|
||||
LLValue *classInfo = catchItr->catchType->ir.irAggr->getClassInfoSymbol();
|
||||
LLValue *classInfo = getIrAggr(catchItr->catchType)->getClassInfoSymbol();
|
||||
// add that symbol as landing pad clause
|
||||
landingPad->addClause(llvm::cast<llvm::Constant>(classInfo));
|
||||
// call llvm.eh.typeid.for to get class info index in the exception table
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "module.h"
|
||||
#include "gen/llvm.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irdsymbol.h"
|
||||
#include "ir/irmodule.h"
|
||||
|
||||
IrModule::IrModule(Module* module, const char* srcfilename)
|
||||
|
@ -24,3 +26,17 @@ IrModule::IrModule(Module* module, const char* srcfilename)
|
|||
IrModule::~IrModule()
|
||||
{
|
||||
}
|
||||
|
||||
IrModule *getIrModule(Module *m)
|
||||
{
|
||||
if (m == NULL)
|
||||
m = gIR->func()->decl->getModule();
|
||||
assert(m && "null module");
|
||||
if (m->ir.m_type == IrDsymbol::NotSet)
|
||||
{
|
||||
m->ir.irModule = new IrModule(m, m->srcfile->toChars());
|
||||
m->ir.m_type = IrDsymbol::ModuleType;
|
||||
}
|
||||
assert(m->ir.m_type == IrDsymbol::ModuleType);
|
||||
return m->ir.irModule;
|
||||
}
|
||||
|
|
|
@ -31,4 +31,6 @@ struct IrModule
|
|||
llvm::GlobalVariable* fileName;
|
||||
};
|
||||
|
||||
IrModule *getIrModule(Module *m);
|
||||
|
||||
#endif
|
||||
|
|
110
ir/irvar.cpp
110
ir/irvar.cpp
|
@ -10,6 +10,7 @@
|
|||
#include "gen/llvm.h"
|
||||
#include "declaration.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "ir/irdsymbol.h"
|
||||
#include "ir/irvar.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -18,9 +19,6 @@
|
|||
|
||||
IrField::IrField(VarDeclaration* v) : IrVar(v)
|
||||
{
|
||||
assert(V->ir.irField == NULL && "field for this variable already exists");
|
||||
V->ir.irField = this;
|
||||
|
||||
if (v->aggrIndex)
|
||||
{
|
||||
index = v->aggrIndex;
|
||||
|
@ -46,3 +44,109 @@ llvm::Constant* IrField::getDefaultInit()
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrVar *getIrVar(VarDeclaration *decl)
|
||||
{
|
||||
assert(isIrVarCreated(decl));
|
||||
assert(decl->ir.irVar != NULL);
|
||||
return decl->ir.irVar;
|
||||
}
|
||||
|
||||
llvm::Value *getIrValue(VarDeclaration *decl)
|
||||
{
|
||||
return getIrVar(decl)->value;
|
||||
}
|
||||
|
||||
bool isIrVarCreated(VarDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
bool isIrVar = t == IrDsymbol::GlobalType ||
|
||||
t == IrDsymbol::LocalType ||
|
||||
t == IrDsymbol::ParamterType ||
|
||||
t == IrDsymbol::FieldType;
|
||||
assert(isIrVar || t == IrDsymbol::NotSet);
|
||||
return isIrVar;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrGlobal *getIrGlobal(VarDeclaration *decl, bool create)
|
||||
{
|
||||
if (!isIrGlobalCreated(decl) && create)
|
||||
{
|
||||
assert(decl->ir.irGlobal == NULL);
|
||||
decl->ir.irGlobal = new IrGlobal(decl);
|
||||
decl->ir.m_type = IrDsymbol::GlobalType;
|
||||
}
|
||||
assert(decl->ir.irGlobal != NULL);
|
||||
return decl->ir.irGlobal;
|
||||
}
|
||||
|
||||
bool isIrGlobalCreated(VarDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
assert(t == IrDsymbol::GlobalType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::GlobalType;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrLocal *getIrLocal(VarDeclaration *decl, bool create)
|
||||
{
|
||||
if (!isIrLocalCreated(decl) && create)
|
||||
{
|
||||
assert(decl->ir.irLocal == NULL);
|
||||
decl->ir.irLocal = new IrLocal(decl);
|
||||
decl->ir.m_type = IrDsymbol::LocalType;
|
||||
}
|
||||
assert(decl->ir.irLocal != NULL);
|
||||
return decl->ir.irLocal;
|
||||
}
|
||||
|
||||
bool isIrLocalCreated(VarDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
assert(t == IrDsymbol::LocalType || t == IrDsymbol::ParamterType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::LocalType || t == IrDsymbol::ParamterType;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrParameter *getIrParameter(VarDeclaration *decl, bool create)
|
||||
{
|
||||
if (!isIrParameterCreated(decl) && create)
|
||||
{
|
||||
assert(decl->ir.irParam == NULL);
|
||||
decl->ir.irParam = new IrParameter(decl);
|
||||
decl->ir.m_type = IrDsymbol::ParamterType;
|
||||
}
|
||||
return decl->ir.irParam;
|
||||
}
|
||||
|
||||
bool isIrParameterCreated(VarDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
assert(t == IrDsymbol::ParamterType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::ParamterType;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrField *getIrField(VarDeclaration *decl, bool create)
|
||||
{
|
||||
if (!isIrFieldCreated(decl) && create)
|
||||
{
|
||||
assert(decl->ir.irField == NULL);
|
||||
decl->ir.irField = new IrField(decl);
|
||||
decl->ir.m_type = IrDsymbol::FieldType;
|
||||
}
|
||||
assert(decl->ir.irField != NULL);
|
||||
return decl->ir.irField;
|
||||
}
|
||||
|
||||
bool isIrFieldCreated(VarDeclaration *decl)
|
||||
{
|
||||
int t = decl->ir.type();
|
||||
assert(t == IrDsymbol::FieldType || t == IrDsymbol::NotSet);
|
||||
return t == IrDsymbol::FieldType;
|
||||
}
|
||||
|
|
16
ir/irvar.h
16
ir/irvar.h
|
@ -91,4 +91,20 @@ protected:
|
|||
llvm::Constant* constInit;
|
||||
};
|
||||
|
||||
IrVar *getIrVar(VarDeclaration *decl);
|
||||
llvm::Value *getIrValue(VarDeclaration *decl);
|
||||
bool isIrVarCreated(VarDeclaration *decl);
|
||||
|
||||
IrGlobal *getIrGlobal(VarDeclaration *decl, bool create = false);
|
||||
bool isIrGlobalCreated(VarDeclaration *decl);
|
||||
|
||||
IrLocal *getIrLocal(VarDeclaration *decl, bool create = false);
|
||||
bool isIrLocalCreated(VarDeclaration *decl);
|
||||
|
||||
IrParameter *getIrParameter(VarDeclaration *decl, bool create = false);
|
||||
bool isIrParameterCreated(VarDeclaration *decl);
|
||||
|
||||
IrField *getIrField(VarDeclaration *decl, bool create = false);
|
||||
bool isIrFieldCreated(VarDeclaration *decl);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue