Fixed calling of _d_array_bounds and _d_switch_error.

This commit is contained in:
Alexey Prokhin 2011-01-02 17:43:02 +03:00
parent 3c4db7bc87
commit a86f414bc1
7 changed files with 87 additions and 21 deletions

View file

@ -45,6 +45,9 @@
#endif
#if IN_LLVM
#include "llvm/Type.h"
#include "llvm/LLVMContext.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/CommandLine.h"
#include <map>
@ -211,6 +214,8 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
#if IN_LLVM
// LDC
llvmForceLogging = false;
moduleInfoVar = NULL;
moduleInfoType = new llvm::PATypeHolder(llvm::OpaqueType::get(llvm::getGlobalContext()));
this->doDocComment = doDocComment;
this->doHdrGen = doHdrGen;
#endif
@ -408,6 +413,9 @@ void Module::deleteObjFile()
Module::~Module()
{
#if IN_LLVM
delete moduleInfoType;
#endif
}
const char *Module::kind()

View file

@ -34,6 +34,8 @@ typedef DValue elem;
namespace llvm {
class LLVMContext;
class Module;
class GlobalVariable;
class PATypeHolder;
}
#else
@ -202,8 +204,11 @@ struct Module : Package
void buildTargetFiles(bool singleObj);
File* buildFilePath(const char* forcename, const char* path, const char* ext);
Module *isModule() { return this; }
llvm::GlobalVariable* moduleInfoSymbol();
bool llvmForceLogging;
llvm::GlobalVariable* moduleInfoVar;
llvm::PATypeHolder* moduleInfoType;
// array ops emitted in this module already
StringTable arrayfuncs;

View file

@ -80,9 +80,16 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
std::vector<LLValue*> args;
#if DMDV2
// module param
LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol();
const LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));
#else
// file param
IrModule* irmod = getIrModule(NULL);
args.push_back(DtoLoad(irmod->fileName));
#endif
// line param
LLConstant* c = DtoConstUint(loc.linnum);

View file

@ -1327,9 +1327,15 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
std::vector<LLValue*> args;
Module* funcmodule = gIR->func()->decl->getModule();
#if DMDV2
// module param
LLValue *moduleInfoSymbol = funcmodule->moduleInfoSymbol();
const LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));
#else
// file param
// we might be generating for an imported template function
Module* funcmodule = gIR->func()->decl->getModule();
const char* cur_file = funcmodule->srcfile->name->toChars();
if (loc.filename && strcmp(loc.filename, cur_file) != 0)
{
@ -1340,6 +1346,7 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
IrModule* irmod = getIrModule(funcmodule);
args.push_back(DtoLoad(irmod->fileName));
}
#endif
// line param
LLConstant* c = DtoConstUint(loc.linnum);

View file

@ -11,11 +11,13 @@
#include "dsymbol.h"
#include "mtype.h"
#include "aggregate.h"
#include "module.h"
#include "gen/runtime.h"
#include "gen/logger.h"
#include "gen/tollvm.h"
#include "gen/irstate.h"
#include "ir/irtype.h"
using namespace llvm::Attribute;
@ -234,19 +236,34 @@ static void LLVM_D_BuildRuntimeModule()
/////////////////////////////////////////////////////////////////////////////////////
// void _d_assert( char[] file, uint line )
// void _d_array_bounds( char[] file, uint line )
// void _d_switch_error( char[] file, uint line )
{
llvm::StringRef fname("_d_assert");
llvm::StringRef fname2("_d_array_bounds");
llvm::StringRef fname3("_d_switch_error");
std::vector<const LLType*> types;
types.push_back(stringTy);
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// D1:
// void _d_array_bounds( char[] file, uint line )
// void _d_switch_error( char[] file, uint line )
// D2:
// void _d_array_bounds(ModuleInfo* m, uint line)
// void _d_switch_error(ModuleInfo* m, uint line)
{
llvm::StringRef fname("_d_array_bounds");
llvm::StringRef fname2("_d_switch_error");
std::vector<const LLType*> types;
#if DMDV2
types.push_back(getPtrToType(DtoType(Module::moduleinfo->type)));
#else
types.push_back(stringTy);
#endif
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
}
// void _d_assert_msg( char[] msg, char[] file, uint line )

View file

@ -1555,9 +1555,16 @@ void SwitchErrorStatement::toIR(IRState* p)
std::vector<LLValue*> args;
#if DMDV2
// module param
LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol();
const LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));
#else
// file param
IrModule* irmod = getIrModule(NULL);
args.push_back(DtoLoad(irmod->fileName));
#endif
// line param
LLConstant* c = DtoConstUint(loc.linnum);

View file

@ -22,6 +22,7 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/LLVMContext.h"
#include "mars.h"
#include "module.h"
@ -535,6 +536,31 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
return ctor;
}
llvm::GlobalVariable* Module::moduleInfoSymbol()
{
// create name
std::string MIname("_D");
MIname.append(mangle());
MIname.append("8__ModuleZ");
if (gIR->dmodule != this) {
const LLType* moduleinfoTy = DtoType(moduleinfo->type);
LLGlobalVariable *var = gIR->module->getGlobalVariable(MIname);
if (!var)
var = new llvm::GlobalVariable(*gIR->module, moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
return var;
}
if (moduleInfoVar)
return moduleInfoVar;
// declare global
// flags will be modified at runtime so can't make it constant
moduleInfoVar = new llvm::GlobalVariable(*gIR->module, moduleInfoType->get(), false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
return moduleInfoVar;
}
// Put out instance of ModuleInfo for this Module
void Module::genmoduleinfo()
@ -592,7 +618,6 @@ void Module::genmoduleinfo()
b.push_string(toPrettyChars());
// importedModules[]
int aimports_dim = aimports.dim;
std::vector<LLConstant*> importInits;
LLConstant* c = 0;
for (size_t i = 0; i < aimports.dim; i++)
@ -742,23 +767,13 @@ void Module::genmoduleinfo()
assert(0);
}*/
// create initializer
// create and set initializer
LLConstant* constMI = b.get_constant();
// create name
std::string MIname("_D");
MIname.append(mangle());
MIname.append("8__ModuleZ");
// declare global
// flags will be modified at runtime so can't make it constant
// it makes no sense that the our own module info already exists!
assert(!gIR->module->getGlobalVariable(MIname));
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module, constMI->getType(), false, llvm::GlobalValue::ExternalLinkage, constMI, MIname);
llvm::cast<llvm::OpaqueType>(moduleInfoType->get())->refineAbstractTypeTo(constMI->getType());
moduleInfoSymbol()->setInitializer(constMI);
// build the modulereference and ctor for registering it
LLFunction* mictor = build_module_reference_and_ctor(gvar);
LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol());
// register this ctor in the magic llvm.global_ctors appending array
const LLFunctionType* magicfty = LLFunctionType::get(LLType::getVoidTy(gIR->context()), std::vector<const LLType*>(), false);