Skip to content
Merged
6 changes: 0 additions & 6 deletions driver/codegenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,6 @@ void emitLLVMUsedArray(IRState &irs) {
namespace ldc {
CodeGenerator::CodeGenerator(llvm::LLVMContext &context, bool singleObj)
: context_(context), moduleCount_(0), singleObj_(singleObj), ir_(nullptr) {
if (!ClassDeclaration::object) {
error(Loc(), "declaration for class `Object` not found; druntime not "
"configured properly");
fatal();
}

#if LDC_LLVM_VER >= 309
// Set the context to discard value names when not generating textual IR.
if (!global.params.output_ll) {
Expand Down
5 changes: 3 additions & 2 deletions driver/linker-msvc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ void addMscrtLibs(std::vector<std::string> &args,
}

void addLibIfFound(std::vector<std::string> &args, const llvm::Twine &name) {
if (llvm::sys::fs::exists(exe_path::prependLibDir(name)))
args.push_back(name.str());
std::string candidate = exe_path::prependLibDir(name);
if (llvm::sys::fs::exists(candidate))
args.push_back(std::move(candidate));
}

void addSanitizerLibs(std::vector<std::string> &args) {
Expand Down
20 changes: 10 additions & 10 deletions gen/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,13 +674,6 @@ DSliceValue *DtoNewDynArray(Loc &loc, Type *arrayType, DValue *dim,
IF_LOG Logger::println("DtoNewDynArray : %s", arrayType->toChars());
LOG_SCOPE;

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// dim arg
assert(DtoType(dim->type) == DtoSize_t());
LLValue *arrayLen = DtoRVal(dim);

// get runtime function
Type *eltType = arrayType->toBasetype()->nextOf();
bool zeroInit = eltType->isZeroInit();
Expand All @@ -690,6 +683,13 @@ DSliceValue *DtoNewDynArray(Loc &loc, Type *arrayType, DValue *dim,
: "_d_newarrayU";
LLFunction *fn = getRuntimeFunction(loc, gIR->module, fnname);

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// dim arg
assert(DtoType(dim->type) == DtoSize_t());
LLValue *arrayLen = DtoRVal(dim);

// call allocator
LLValue *newArray =
gIR->CreateCallOrInvoke(fn, arrayTypeInfo, arrayLen, ".gc_mem")
Expand All @@ -704,9 +704,6 @@ DSliceValue *DtoNewMulDimDynArray(Loc &loc, Type *arrayType, DValue **dims,
IF_LOG Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
LOG_SCOPE;

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// get value type
Type *vtype = arrayType->toBasetype();
for (size_t i = 0; i < ndims; ++i) {
Expand All @@ -718,6 +715,9 @@ DSliceValue *DtoNewMulDimDynArray(Loc &loc, Type *arrayType, DValue **dims,
vtype->isZeroInit() ? "_d_newarraymTX" : "_d_newarraymiTX";
LLFunction *fn = getRuntimeFunction(loc, gIR->module, fnname);

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// Check if constant
bool allDimsConst = true;
for (size_t i = 0; i < ndims; ++i) {
Expand Down
28 changes: 18 additions & 10 deletions gen/classes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ DValue *DtoNewClass(Loc &loc, TypeClass *tc, NewExp *newexp) {
llvm::Function *fn =
getRuntimeFunction(loc, gIR->module, "_d_allocclass");
LLConstant *ci = DtoBitCast(getIrAggr(tc->sym)->getClassInfoSymbol(),
DtoType(Type::typeinfoclass->type));
DtoType(getClassInfoType()));
mem =
gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
Expand Down Expand Up @@ -347,17 +347,25 @@ DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {

////////////////////////////////////////////////////////////////////////////////

DValue *DtoDynamicCastObject(Loc &loc, DValue *val, Type *_to) {
// call:
// Object _d_dynamic_cast(Object o, ClassInfo c)
static void resolveObjectAndClassInfoClasses() {
// check declarations in object.d
getObjectType();
getClassInfoType();

DtoResolveClass(ClassDeclaration::object);
DtoResolveClass(Type::typeinfoclass);
}

DValue *DtoDynamicCastObject(Loc &loc, DValue *val, Type *_to) {
// call:
// Object _d_dynamic_cast(Object o, ClassInfo c)

llvm::Function *func =
getRuntimeFunction(loc, gIR->module, "_d_dynamic_cast");
LLFunctionType *funcTy = func->getFunctionType();

resolveObjectAndClassInfoClasses();

// Object o
LLValue *obj = DtoRVal(val);
obj = DtoBitCast(obj, funcTy->getParamType(0));
Expand Down Expand Up @@ -389,13 +397,12 @@ DValue *DtoDynamicCastInterface(Loc &loc, DValue *val, Type *_to) {
// call:
// Object _d_interface_cast(void* p, ClassInfo c)

DtoResolveClass(ClassDeclaration::object);
DtoResolveClass(Type::typeinfoclass);

llvm::Function *func =
getRuntimeFunction(loc, gIR->module, "_d_interface_cast");
LLFunctionType *funcTy = func->getFunctionType();

resolveObjectAndClassInfoClasses();

// void* p
LLValue *ptr = DtoRVal(val);
ptr = DtoBitCast(ptr, funcTy->getParamType(0));
Expand Down Expand Up @@ -606,7 +613,8 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
assert(cd->type->ty == Tclass);

IrAggr *ir = getIrAggr(cd);
ClassDeclaration *cinfo = Type::typeinfoclass;
Type *const cinfoType = getClassInfoType(); // check declaration in object.d
ClassDeclaration *const cinfo = Type::typeinfoclass;

if (cinfo->fields.dim != 12) {
error(Loc(), "Unexpected number of fields in `object.ClassInfo`; "
Expand All @@ -615,7 +623,7 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
}

// use the rtti builder
RTTIBuilder b(cinfo);
RTTIBuilder b(cinfoType);

LLConstant *c;

Expand Down Expand Up @@ -656,7 +664,7 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
if (cd->baseClass && !cd->isInterfaceDeclaration()) {
b.push_classinfo(cd->baseClass);
} else {
b.push_null(cinfo->type);
b.push_null(cinfoType);
}

// destructor
Expand Down
2 changes: 1 addition & 1 deletion gen/declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class CodegenVisitor : public Visitor {
setLinkage(decl, initGlobal);

// emit typeinfo
if (global.params.useTypeInfo) {
if (global.params.useTypeInfo && Type::dtypeinfo) {
DtoTypeInfoOf(decl->type, /*base=*/false);
}
}
Expand Down
2 changes: 1 addition & 1 deletion gen/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
if (isLLVMVariadic && f->linkage == LINKd) {
// Add extra `_arguments` parameter for D-style variadic functions.
newIrFty.arg_arguments =
new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
new IrFuncTyArg(getTypeInfoType()->arrayOf(), false);
++nextLLArgIdx;
}

Expand Down
2 changes: 1 addition & 1 deletion gen/llvmhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,7 @@ LLConstant *DtoTypeInfoOf(Type *type, bool base) {
LLConstant *c = isaConstant(getIrGlobal(tidecl)->value);
assert(c != NULL);
if (base) {
return llvm::ConstantExpr::getBitCast(c, DtoType(Type::dtypeinfo->type));
return llvm::ConstantExpr::getBitCast(c, DtoType(getTypeInfoType()));
}
return c;
}
Expand Down
16 changes: 8 additions & 8 deletions gen/moduleinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "gen/logger.h"
#include "gen/mangling.h"
#include "gen/rttibuilder.h"
#include "gen/runtime.h"
#include "ir/irfunction.h"
#include "ir/irmodule.h"
#include "ir/irtype.h"
Expand Down Expand Up @@ -132,7 +133,7 @@ llvm::Function *buildModuleSharedDtor(Module *m) {

/// Builds the (constant) data content for the importedModules[] array.
llvm::Constant *buildImportedModules(Module *m, size_t &count) {
const auto moduleInfoPtrTy = DtoPtrToType(Module::moduleinfo->type);
const auto moduleInfoPtrTy = DtoPtrToType(getModuleInfoType());

std::vector<LLConstant *> importInits;
for (auto mod : m->aimports) {
Expand All @@ -154,7 +155,7 @@ llvm::Constant *buildImportedModules(Module *m, size_t &count) {

/// Builds the (constant) data content for the localClasses[] array.
llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
const auto classinfoTy = Type::typeinfoclass->type->ctype->getLLType();
const auto classinfoTy = DtoType(getClassInfoType());

ClassDeclarations aclasses;
for (auto s : *m->members) {
Expand Down Expand Up @@ -193,16 +194,15 @@ llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
}

llvm::GlobalVariable *genModuleInfo(Module *m) {
if (!Module::moduleinfo) {
m->error("object.d is missing the `ModuleInfo` struct");
fatal();
}
// check declaration in object.d
const auto moduleInfoType = getModuleInfoType();
const auto moduleInfoDecl = Module::moduleinfo;

// The "new-style" ModuleInfo records are variable-length, with the presence
// of the various fields indicated by a certain flag bit. The base struct
// should consist only of the _flags/_index fields (the latter of which is
// unused).
if (Module::moduleinfo->structsize != 4 + 4) {
if (moduleInfoDecl->structsize != 4 + 4) {
m->error("Unexpected size of struct `object.ModuleInfo`; "
"druntime version does not match compiler (see -v)");
fatal();
Expand Down Expand Up @@ -262,7 +262,7 @@ llvm::GlobalVariable *genModuleInfo(Module *m) {
}

// Now, start building the initialiser for the ModuleInfo instance.
RTTIBuilder b(Module::moduleinfo);
RTTIBuilder b(moduleInfoType);

b.push_uint(flags);
b.push_uint(0); // index
Expand Down
10 changes: 6 additions & 4 deletions gen/modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
// functions).
const bool isFirst = !gIR->module.getGlobalVariable("ldc.dso_slot");

llvm::Type *const moduleInfoPtrTy = DtoPtrToType(Module::moduleinfo->type);
llvm::Type *const moduleInfoPtrTy = DtoPtrToType(getModuleInfoType());
const auto sectionName =
style == RegistryStyle::sectionMSVC
? ".minfo"
Expand Down Expand Up @@ -708,9 +708,11 @@ void codegenModule(IRState *irs, Module *m) {
fatal();
}

// Skip emission of all the additional module metadata if requested by the
// user or the betterC switch is on.
if (global.params.useModuleInfo && !m->noModuleInfo) {
// Skip emission of all the additional module metadata if:
// a) the -betterC switch is on,
// b) requested explicitly by the user via pragma(LDC_no_moduleinfo), or if
// c) there's no ModuleInfo declaration.
if (global.params.useModuleInfo && !m->noModuleInfo && Module::moduleinfo) {
// generate ModuleInfo
registerModuleInfo(m);
}
Expand Down
8 changes: 4 additions & 4 deletions gen/passes/GarbageCollect2Stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct Analysis {
CallGraph *CG;
CallGraphNode *CGNode;

Type *getTypeFor(Value *typeinfo) const;
llvm::Type *getTypeFor(Value *typeinfo) const;
};
}

Expand Down Expand Up @@ -105,7 +105,7 @@ enum Type {

class FunctionInfo {
protected:
Type *Ty;
llvm::Type *Ty;

public:
ReturnType::Type ReturnType;
Expand Down Expand Up @@ -559,7 +559,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) {
return Changed;
}

Type *Analysis::getTypeFor(Value *typeinfo) const {
llvm::Type *Analysis::getTypeFor(Value *typeinfo) const {
GlobalVariable *ti_global =
dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
if (!ti_global) {
Expand Down Expand Up @@ -826,7 +826,7 @@ bool isSafeToStackAllocate(BasicBlock::iterator Alloc, Value *V,
// its return value and doesn't unwind (a readonly function can leak bits
// by throwing an exception or not depending on the input value).
if (CS.onlyReadsMemory() && CS.doesNotThrow() &&
I->getType() == Type::getVoidTy(I->getContext())) {
I->getType() == llvm::Type::getVoidTy(I->getContext())) {
break;
}

Expand Down
4 changes: 2 additions & 2 deletions gen/passes/SimplifyDRuntimeCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ struct LLVM_LIBRARY_VISIBILITY ArrayCastLenOpt : public LibCallOptimization {
IRBuilder<> &B) override {
// Verify we have a reasonable prototype for _d_array_cast_len
const FunctionType *FT = Callee->getFunctionType();
const Type *RetTy = FT->getReturnType();
const llvm::Type *RetTy = FT->getReturnType();
if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) ||
FT->getParamType(0) != RetTy || FT->getParamType(1) != RetTy ||
FT->getParamType(2) != RetTy) {
Expand Down Expand Up @@ -263,7 +263,7 @@ struct LLVM_LIBRARY_VISIBILITY ArraySliceCopyOpt : public LibCallOptimization {
IRBuilder<> &B) override {
// Verify we have a reasonable prototype for _d_array_slice_copy
const FunctionType *FT = Callee->getFunctionType();
const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
const llvm::Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
if (Callee->arg_size() != 4 || FT->getReturnType() != B.getVoidTy() ||
FT->getParamType(0) != VoidPtrTy ||
!isa<IntegerType>(FT->getParamType(1)) ||
Expand Down
16 changes: 7 additions & 9 deletions gen/rttibuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@
#include "ir/iraggr.h"
#include "ir/irfunction.h"

RTTIBuilder::RTTIBuilder(AggregateDeclaration *base_class) {
DtoResolveDsymbol(base_class);
RTTIBuilder::RTTIBuilder(Type *baseType) {
const auto ad = isAggregate(baseType);
assert(ad && "not an aggregate type");

base = base_class;
basetype = static_cast<TypeClass *>(base->type);
DtoResolveDsymbol(ad);

baseir = getIrAggr(base);
assert(baseir && "no IrStruct for TypeInfo base class");
if (ad->isClassDeclaration()) {
const auto baseir = getIrAggr(ad);
assert(baseir && "no IrAggr for TypeInfo base class");

prevFieldEnd = 0;

if (base->isClassDeclaration()) {
// just start with adding the vtbl
push(baseir->getVtblSymbol());
// and monitor
Expand Down
12 changes: 2 additions & 10 deletions gen/rttibuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,25 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constant.h"

class AggregateDeclaration;
class ClassDeclaration;
class Dsymbol;
class FuncDeclaration;
struct IrGlobal;
struct IrAggr;
class Type;
class TypeClass;
namespace llvm {
class StructType;
class GlobalVariable;
}

class RTTIBuilder {
AggregateDeclaration *base;
TypeClass *basetype;
IrAggr *baseir;

/// The offset (in bytes) at which the previously pushed field ended.
uint64_t prevFieldEnd;
uint64_t prevFieldEnd = 0;

public:
// 15 is enough for any D2 ClassInfo including 64 bit pointer alignment
// padding
llvm::SmallVector<llvm::Constant *, 15> inits;

explicit RTTIBuilder(AggregateDeclaration *base_class);
explicit RTTIBuilder(Type *baseType);

void push(llvm::Constant *C);
void push_null(Type *T);
Expand Down
Loading