Split up getOrCreateGlobal() in {declare,define}Global()

Making it obvious which of the two operations is performed, reducing
call args and making sure a global isn't defined multiple times via
`defineGlobal()`.

The only [intended] functional change is in gen/trycatchfinally.cpp,
where I inserted a check for an existing __cpp_type_info_ptr global when
emitting a catch for C++ exceptions.
This commit is contained in:
Martin 2018-04-07 19:25:54 +02:00
parent e4f424bf63
commit f38a7972a5
9 changed files with 133 additions and 120 deletions

View file

@ -911,17 +911,12 @@ void DtoResolveVariable(VarDeclaration *vd) {
// with a different type later, swap it out and replace any existing // with a different type later, swap it out and replace any existing
// uses with bitcasts to the previous type. // uses with bitcasts to the previous type.
// We always start out with external linkage; any other type is set
// when actually defining it in VarDeclaration::codegen.
llvm::GlobalValue::LinkageTypes linkage =
llvm::GlobalValue::ExternalLinkage;
if (vd->llvmInternal == LLVMextern_weak) {
linkage = llvm::GlobalValue::ExternalWeakLinkage;
}
llvm::GlobalVariable *gvar = llvm::GlobalVariable *gvar =
getOrCreateGlobal(vd->loc, gIR->module, DtoMemType(vd->type), isLLConst, declareGlobal(vd->loc, gIR->module, DtoMemType(vd->type), irMangle,
linkage, nullptr, irMangle, vd->isThreadlocal()); isLLConst, vd->isThreadlocal());
if (vd->llvmInternal == LLVMextern_weak)
gvar->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
auto varIr = getIrGlobal(vd); auto varIr = getIrGlobal(vd);
varIr->value = gvar; varIr->value = gvar;
@ -1751,19 +1746,20 @@ llvm::Constant *buildStringLiteralConstant(StringExp *se, bool zeroTerm) {
return LLConstantArray::get(at, vals); return LLConstantArray::get(at, vals);
} }
llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module, llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
llvm::Type *type, bool isConstant, llvm::Type *type,
llvm::GlobalValue::LinkageTypes linkage, llvm::StringRef mangledName,
llvm::Constant *init, bool isConstant, bool isThreadLocal) {
llvm::StringRef name, llvm::GlobalVariable *existing =
bool isThreadLocal) { module.getGlobalVariable(mangledName, /*AllowInternal=*/true);
llvm::GlobalVariable *existing = module.getGlobalVariable(name, true);
if (existing) { if (existing) {
if (existing->getType()->getElementType() != type) { if (existing->getType()->getElementType() != type ||
existing->isConstant() != isConstant ||
existing->isThreadLocal() != isThreadLocal) {
error(loc, error(loc,
"Global variable type does not match previous declaration with " "Global variable type does not match previous declaration with "
"same mangled name: `%s`", "same mangled name: `%s`",
name.str().c_str()); mangledName.str().c_str());
fatal(); fatal();
} }
return existing; return existing;
@ -1772,14 +1768,36 @@ llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module,
// Use a command line option for the thread model. // Use a command line option for the thread model.
// On PPC there is only local-exec available - in this case just ignore the // On PPC there is only local-exec available - in this case just ignore the
// command line. // command line.
const llvm::GlobalVariable::ThreadLocalMode tlsModel = const auto tlsModel =
isThreadLocal isThreadLocal
? (global.params.targetTriple->getArch() == llvm::Triple::ppc ? (global.params.targetTriple->getArch() == llvm::Triple::ppc
? llvm::GlobalVariable::LocalExecTLSModel ? llvm::GlobalVariable::LocalExecTLSModel
: clThreadModel.getValue()) : clThreadModel.getValue())
: llvm::GlobalVariable::NotThreadLocal; : llvm::GlobalVariable::NotThreadLocal;
return new llvm::GlobalVariable(module, type, isConstant, linkage, init, name,
nullptr, tlsModel); return new llvm::GlobalVariable(module, type, isConstant,
llvm::GlobalValue::ExternalLinkage, nullptr,
mangledName, nullptr, tlsModel);
}
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
llvm::GlobalValue::LinkageTypes linkage) {
assert(global->isDeclaration() && "Global variable already defined");
assert(init);
global->setInitializer(init);
global->setLinkage(linkage);
}
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,
llvm::StringRef mangledName,
llvm::Constant *init,
llvm::GlobalValue::LinkageTypes linkage,
bool isConstant, bool isThreadLocal) {
assert(init);
auto global = declareGlobal(loc, module, init->getType(), mangledName,
isConstant, isThreadLocal);
defineGlobal(global, init, linkage);
return global;
} }
FuncDeclaration *getParentFunc(Dsymbol *sym) { FuncDeclaration *getParentFunc(Dsymbol *sym) {

View file

@ -245,18 +245,29 @@ stringLiteralCacheForType(Type *charType);
llvm::Constant *buildStringLiteralConstant(StringExp *se, bool zeroTerm); llvm::Constant *buildStringLiteralConstant(StringExp *se, bool zeroTerm);
/// Tries to create an LLVM global with the given properties. If a variable with /// Tries to declare an LLVM global. If a variable with the same mangled name
/// the same mangled name already exists, checks if the types match and returns /// already exists, checks if the types match and returns it instead.
/// it instead.
/// ///
/// Necessary to support multiple declarations with the same mangled name, as /// Necessary to support multiple declarations with the same mangled name, as
/// can be the case due to pragma(mangle). /// can be the case due to pragma(mangle).
llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module, llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
llvm::Type *type, bool isConstant, llvm::Type *type,
llvm::GlobalValue::LinkageTypes linkage, llvm::StringRef mangledName,
llvm::Constant *init, bool isConstant,
llvm::StringRef name, bool isThreadLocal = false);
bool isThreadLocal = false);
/// Defines an existing LLVM global, i.e., sets the initial value and finalizes
/// its linkage.
/// Asserts that a global isn't defined multiple times this way.
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
llvm::GlobalValue::LinkageTypes linkage);
/// Declares (if not already declared) & defines an LLVM global.
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,
llvm::StringRef mangledName,
llvm::Constant *init,
llvm::GlobalValue::LinkageTypes linkage,
bool isConstant, bool isThreadLocal = false);
FuncDeclaration *getParentFunc(Dsymbol *sym); FuncDeclaration *getParentFunc(Dsymbol *sym);

View file

@ -169,18 +169,15 @@ LLFunction *build_module_reference_and_ctor(const char *moduleMangle,
// create the ModuleReference node for this module // create the ModuleReference node for this module
const auto thismrefIRMangle = getIRMangledModuleRefSymbolName(moduleMangle); const auto thismrefIRMangle = getIRMangledModuleRefSymbolName(moduleMangle);
Loc loc; LLGlobalVariable *thismref =
LLGlobalVariable *thismref = getOrCreateGlobal( defineGlobal(Loc(), gIR->module, thismrefIRMangle, thismrefinit,
loc, gIR->module, modulerefTy, false, LLGlobalValue::InternalLinkage, LLGlobalValue::InternalLinkage, false);
thismrefinit, thismrefIRMangle);
// make sure _Dmodule_ref is declared // make sure _Dmodule_ref is declared
const auto mrefIRMangle = getIRMangledVarName("_Dmodule_ref", LINKc); const auto mrefIRMangle = getIRMangledVarName("_Dmodule_ref", LINKc);
LLConstant *mref = gIR->module.getNamedGlobal(mrefIRMangle); LLConstant *mref = gIR->module.getNamedGlobal(mrefIRMangle);
LLType *modulerefPtrTy = getPtrToType(modulerefTy); LLType *modulerefPtrTy = getPtrToType(modulerefTy);
if (!mref) { if (!mref) {
mref = new LLGlobalVariable(gIR->module, modulerefPtrTy, false, mref = declareGlobal(Loc(), gIR->module, modulerefPtrTy, mrefIRMangle, false);
LLGlobalValue::ExternalLinkage, nullptr,
mrefIRMangle);
} }
mref = DtoBitCast(mref, getPtrToType(modulerefPtrTy)); mref = DtoBitCast(mref, getPtrToType(modulerefPtrTy));
@ -218,9 +215,9 @@ llvm::Function *buildGetTLSAnchor() {
// Create a dummmy TLS global private to this module. // Create a dummmy TLS global private to this module.
const auto one = const auto one =
llvm::ConstantInt::get(llvm::Type::getInt8Ty(gIR->context()), 1); llvm::ConstantInt::get(llvm::Type::getInt8Ty(gIR->context()), 1);
const auto anchor = getOrCreateGlobal( const auto anchor = defineGlobal(Loc(), gIR->module, "ldc.tls_anchor", one,
Loc(), gIR->module, one->getType(), false, llvm::GlobalValue::LinkOnceODRLinkage, false,
llvm::GlobalValue::LinkOnceODRLinkage, one, "ldc.tls_anchor", true); /*isThreadLocal=*/true);
anchor->setVisibility(llvm::GlobalValue::HiddenVisibility); anchor->setVisibility(llvm::GlobalValue::HiddenVisibility);
anchor->setAlignment(16); anchor->setAlignment(16);
@ -358,11 +355,11 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
const auto thismrefIRMangle = const auto thismrefIRMangle =
getIRMangledModuleRefSymbolName(moduleMangle.c_str()); getIRMangledModuleRefSymbolName(moduleMangle.c_str());
auto thismref = new llvm::GlobalVariable( auto thismref = defineGlobal(Loc(), gIR->module, thismrefIRMangle,
gIR->module, moduleInfoPtrTy, DtoBitCast(thisModuleInfo, moduleInfoPtrTy),
false, // FIXME: mRelocModel != llvm::Reloc::PIC_ llvm::GlobalValue::LinkOnceODRLinkage,
llvm::GlobalValue::LinkOnceODRLinkage, false // FIXME: mRelocModel != llvm::Reloc::PIC_
DtoBitCast(thisModuleInfo, moduleInfoPtrTy), thismrefIRMangle); );
thismref->setSection(sectionName); thismref->setSection(sectionName);
gIR->usedArray.push_back(thismref); gIR->usedArray.push_back(thismref);
@ -382,22 +379,19 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
const auto magicEndSymbolName = (style == RegistryStyle::sectionDarwin) const auto magicEndSymbolName = (style == RegistryStyle::sectionDarwin)
? "\1section$end$__DATA$.minfo" ? "\1section$end$__DATA$.minfo"
: "__stop___minfo"; : "__stop___minfo";
auto minfoBeg = new llvm::GlobalVariable(gIR->module, moduleInfoPtrTy, false, auto minfoBeg = declareGlobal(Loc(), gIR->module, moduleInfoPtrTy,
llvm::GlobalValue::ExternalLinkage, magicBeginSymbolName, false);
nullptr, magicBeginSymbolName); auto minfoEnd = declareGlobal(Loc(), gIR->module, moduleInfoPtrTy,
auto minfoEnd = new llvm::GlobalVariable(gIR->module, moduleInfoPtrTy, false, magicEndSymbolName, false);
llvm::GlobalValue::ExternalLinkage,
nullptr, magicEndSymbolName);
minfoBeg->setVisibility(llvm::GlobalValue::HiddenVisibility); minfoBeg->setVisibility(llvm::GlobalValue::HiddenVisibility);
minfoEnd->setVisibility(llvm::GlobalValue::HiddenVisibility); minfoEnd->setVisibility(llvm::GlobalValue::HiddenVisibility);
// Build the ctor to invoke _d_dso_registry. // Build the ctor to invoke _d_dso_registry.
// This is the DSO slot for use by the druntime implementation. // This is the DSO slot for use by the druntime implementation.
auto dsoSlot = auto dsoSlot = defineGlobal(Loc(), gIR->module, "ldc.dso_slot",
new llvm::GlobalVariable(gIR->module, getVoidPtrType(), false, getNullPtr(getVoidPtrType()),
llvm::GlobalValue::LinkOnceODRLinkage, llvm::GlobalValue::LinkOnceODRLinkage, false);
getNullPtr(getVoidPtrType()), "ldc.dso_slot");
dsoSlot->setVisibility(llvm::GlobalValue::HiddenVisibility); dsoSlot->setVisibility(llvm::GlobalValue::HiddenVisibility);
// Okay, so the theory is easy: We want to have one global constructor and // Okay, so the theory is easy: We want to have one global constructor and
@ -429,11 +423,10 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
// problems. This would mean that it is no longer safe to link D objects // problems. This would mean that it is no longer safe to link D objects
// directly using e.g. "g++ dcode.o cppcode.o", though. // directly using e.g. "g++ dcode.o cppcode.o", though.
auto dsoInitialized = new llvm::GlobalVariable( auto dsoInitialized = defineGlobal(
gIR->module, llvm::Type::getInt8Ty(gIR->context()), false, Loc(), gIR->module, "ldc.dso_initialized",
llvm::GlobalValue::LinkOnceODRLinkage,
llvm::ConstantInt::get(llvm::Type::getInt8Ty(gIR->context()), 0), llvm::ConstantInt::get(llvm::Type::getInt8Ty(gIR->context()), 0),
"ldc.dso_initialized"); llvm::GlobalValue::LinkOnceODRLinkage, false);
dsoInitialized->setVisibility(llvm::GlobalValue::HiddenVisibility); dsoInitialized->setVisibility(llvm::GlobalValue::HiddenVisibility);
// There is no reason for this cast to void*, other than that removing it // There is no reason for this cast to void*, other than that removing it
@ -505,7 +498,7 @@ void addCoverageAnalysis(Module *m) {
llvm::ConstantAggregateZero *zeroinitializer = llvm::ConstantAggregateZero *zeroinitializer =
llvm::ConstantAggregateZero::get(type); llvm::ConstantAggregateZero::get(type);
m->d_cover_valid = new llvm::GlobalVariable( m->d_cover_valid = new llvm::GlobalVariable(
gIR->module, type, true, LLGlobalValue::InternalLinkage, gIR->module, type, /*isConstant=*/true, LLGlobalValue::InternalLinkage,
zeroinitializer, "_d_cover_valid"); zeroinitializer, "_d_cover_valid");
LLConstant *idxs[] = {DtoConstUint(0), DtoConstUint(0)}; LLConstant *idxs[] = {DtoConstUint(0), DtoConstUint(0)};
d_cover_valid_slice = d_cover_valid_slice =

View file

@ -165,9 +165,8 @@ llvm::StructType *getTypeDescriptorType(IRState &irs,
llvm::GlobalVariable *getTypeDescriptor(IRState &irs, ClassDeclaration *cd) { llvm::GlobalVariable *getTypeDescriptor(IRState &irs, ClassDeclaration *cd) {
if (cd->isCPPclass()) { if (cd->isCPPclass()) {
const char *name = Target::cppTypeInfoMangle(cd); const char *name = Target::cppTypeInfoMangle(cd);
return getOrCreateGlobal( return declareGlobal(cd->loc, irs.module, getVoidPtrType(), name,
cd->loc, irs.module, getVoidPtrType(), /*isConstant=*/true, /*isConstant=*/true);
LLGlobalValue::ExternalLinkage, /*init=*/nullptr, name);
} }
auto classInfoPtr = getIrAggr(cd, true)->getClassInfoSymbol(); auto classInfoPtr = getIrAggr(cd, true)->getClassInfoSymbol();
@ -188,10 +187,9 @@ llvm::GlobalVariable *getTypeDescriptor(IRState &irs, ClassDeclaration *cd) {
llvm::ConstantDataArray::getString(gIR->context(), TypeNameString)}; llvm::ConstantDataArray::getString(gIR->context(), TypeNameString)};
llvm::StructType *TypeDescriptorType = llvm::StructType *TypeDescriptorType =
getTypeDescriptorType(irs, classInfoPtr, TypeNameString); getTypeDescriptorType(irs, classInfoPtr, TypeNameString);
Var = new llvm::GlobalVariable( Var = defineGlobal(cd->loc, gIR->module, TypeDescName,
gIR->module, TypeDescriptorType, /*Constant=*/false, llvm::ConstantStruct::get(TypeDescriptorType, Fields),
LLGlobalVariable::InternalLinkage, // getLinkageForRTTI(Type), LLGlobalVariable::InternalLinkage, false);
llvm::ConstantStruct::get(TypeDescriptorType, Fields), TypeDescName);
return Var; return Var;
} }

View file

@ -161,31 +161,36 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
LLGlobalVariable *ci; LLGlobalVariable *ci;
if (p.cd->isCPPclass()) { if (p.cd->isCPPclass()) {
const char *name = Target::cppTypeInfoMangle(p.cd); // Wrap std::type_info pointers inside a __cpp_type_info_ptr class
auto cpp_ti = getOrCreateGlobal( // instance so that the personality routine may differentiate C++ catch
p.cd->loc, irs.module, getVoidPtrType(), /*isConstant=*/true, // clauses from D ones.
LLGlobalValue::ExternalLinkage, /*init=*/nullptr, name); OutBuffer wrapperMangleBuf;
wrapperMangleBuf.writestring("_D");
mangleToBuffer(p.cd, &wrapperMangleBuf);
wrapperMangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr");
const auto wrapperMangle =
getIRMangledVarName(wrapperMangleBuf.peekString(), LINKd);
// Wrap std::type_info pointers inside a __cpp_type_info_ptr class instance so that ci = irs.module.getGlobalVariable(wrapperMangle);
// the personality routine may differentiate C++ catch clauses from D ones. if (!ci) {
OutBuffer mangleBuf; const char *name = Target::cppTypeInfoMangle(p.cd);
mangleBuf.writestring("_D"); auto cpp_ti =
mangleToBuffer(p.cd, &mangleBuf); declareGlobal(p.cd->loc, irs.module, getVoidPtrType(), name,
mangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr"); /*isConstant=*/true);
const auto wrapperMangle = getIRMangledVarName(mangleBuf.peekString(), LINKd);
const auto cppTypeInfoPtrType = getCppTypeInfoPtrType(); const auto cppTypeInfoPtrType = getCppTypeInfoPtrType();
RTTIBuilder b(cppTypeInfoPtrType); RTTIBuilder b(cppTypeInfoPtrType);
b.push(cpp_ti); b.push(cpp_ti);
auto wrapperType = llvm::cast<llvm::StructType>( auto wrapperType = llvm::cast<llvm::StructType>(
static_cast<IrTypeClass *>(cppTypeInfoPtrType->ctype) static_cast<IrTypeClass *>(cppTypeInfoPtrType->ctype)
->getMemoryLLType()); ->getMemoryLLType());
auto wrapperInit = b.get_constant(wrapperType); auto wrapperInit = b.get_constant(wrapperType);
ci = getOrCreateGlobal( ci = defineGlobal(p.cd->loc, irs.module, wrapperMangle, wrapperInit,
p.cd->loc, irs.module, wrapperType, /*isConstant=*/true, LLGlobalValue::LinkOnceODRLinkage,
LLGlobalValue::LinkOnceODRLinkage, wrapperInit, wrapperMangle); /*isConstant=*/true);
}
} else { } else {
ci = getIrAggr(p.cd)->getClassInfoSymbol(); ci = getIrAggr(p.cd)->getClassInfoSymbol();
} }

View file

@ -624,18 +624,11 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
} }
const auto irMangle = getIRMangledVarName(mangled, LINKd); const auto irMangle = getIRMangledVarName(mangled, LINKd);
LLGlobalVariable *gvar = gIR->module.getGlobalVariable(irMangle); LLType *type = DtoType(decl->type)->getPointerElementType();
if (gvar) { // Declare the symbol. We need to keep it mutable as the type is not
assert(gvar->getType()->getContainedType(0)->isStructTy()); // declared as immutable on the D side, and e.g. synchronized() can be used
} else { // on the implicit monitor.
LLType *type = DtoType(decl->type)->getPointerElementType(); auto gvar = declareGlobal(decl->loc, gIR->module, type, irMangle, false);
// Create the symbol. We need to keep it mutable as the type is not declared
// as immutable on the D side, and e.g. synchronized() can be used on the
// implicit monitor.
gvar =
new LLGlobalVariable(gIR->module, type, false,
LLGlobalValue::ExternalLinkage, nullptr, irMangle);
}
IrGlobal *irg = getIrGlobal(decl, true); IrGlobal *irg = getIrGlobal(decl, true);
irg->value = gvar; irg->value = gvar;

View file

@ -49,9 +49,8 @@ LLConstant *&IrAggr::getInitSymbol() {
// create the initZ symbol // create the initZ symbol
const auto irMangle = getIRMangledInitSymbolName(aggrdecl); const auto irMangle = getIRMangledInitSymbolName(aggrdecl);
auto initGlobal = auto initGlobal = declareGlobal(aggrdecl->loc, gIR->module, getLLStructType(),
getOrCreateGlobal(aggrdecl->loc, gIR->module, getLLStructType(), true, irMangle, /*isConstant=*/true);
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
initGlobal->setAlignment(DtoAlignment(type)); initGlobal->setAlignment(DtoAlignment(type));
init = initGlobal; init = initGlobal;

View file

@ -51,9 +51,8 @@ LLGlobalVariable *IrAggr::getVtblSymbol() {
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType(); LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType();
vtbl = vtbl = declareGlobal(aggrdecl->loc, gIR->module, vtblTy, irMangle,
getOrCreateGlobal(aggrdecl->loc, gIR->module, vtblTy, true, /*isConstant=*/true);
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
return vtbl; return vtbl;
} }
@ -77,9 +76,8 @@ LLGlobalVariable *IrAggr::getClassInfoSymbol() {
assert(tc && "invalid ClassInfo type"); assert(tc && "invalid ClassInfo type");
// classinfos cannot be constants since they're used as locks for synchronized // classinfos cannot be constants since they're used as locks for synchronized
classInfo = getOrCreateGlobal( classInfo = declareGlobal(aggrdecl->loc, gIR->module, tc->getMemoryLLType(),
aggrdecl->loc, gIR->module, tc->getMemoryLLType(), false, irMangle, false);
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
// Generate some metadata on this ClassInfo if it's for a class. // Generate some metadata on this ClassInfo if it's for a class.
ClassDeclaration *classdecl = aggrdecl->isClassDeclaration(); ClassDeclaration *classdecl = aggrdecl->isClassDeclaration();
@ -139,11 +137,8 @@ LLGlobalVariable *IrAggr::getInterfaceArraySymbol() {
LLArrayType *array_type = llvm::ArrayType::get(InterfaceTy, n); LLArrayType *array_type = llvm::ArrayType::get(InterfaceTy, n);
// We keep the global as external for now and only consider template linkage classInterfacesArray = declareGlobal(cd->loc, gIR->module, array_type,
// if we emit the initializer later. irMangle, /*isConstant=*/true);
classInterfacesArray =
getOrCreateGlobal(cd->loc, gIR->module, array_type, true,
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
return classInterfacesArray; return classInterfacesArray;
} }
@ -457,8 +452,8 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
const auto lwc = DtoLinkage(cd); const auto lwc = DtoLinkage(cd);
LLGlobalVariable *GV = LLGlobalVariable *GV =
getOrCreateGlobal(cd->loc, gIR->module, vtbl_constant->getType(), true, defineGlobal(cd->loc, gIR->module, irMangle, vtbl_constant,
lwc.first, vtbl_constant, irMangle); lwc.first, /*isConstant=*/true);
setLinkage(lwc, GV); setLinkage(lwc, GV);
// insert into the vtbl map // insert into the vtbl map

View file

@ -11,6 +11,7 @@
#include "module.h" #include "module.h"
#include "gen/llvm.h" #include "gen/llvm.h"
#include "gen/irstate.h" #include "gen/irstate.h"
#include "gen/llvmhelpers.h"
#include "gen/mangling.h" #include "gen/mangling.h"
#include "gen/tollvm.h" #include "gen/tollvm.h"
#include "ir/irdsymbol.h" #include "ir/irdsymbol.h"
@ -25,9 +26,9 @@ llvm::GlobalVariable *IrModule::moduleInfoSymbol() {
const auto irMangle = getIRMangledModuleInfoSymbolName(M); const auto irMangle = getIRMangledModuleInfoSymbolName(M);
moduleInfoVar = new llvm::GlobalVariable( moduleInfoVar =
gIR->module, llvm::StructType::create(gIR->context()), false, declareGlobal(Loc(), gIR->module,
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle); llvm::StructType::create(gIR->context()), irMangle, false);
return moduleInfoVar; return moduleInfoVar;
} }