mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
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:
parent
e4f424bf63
commit
f38a7972a5
9 changed files with 133 additions and 120 deletions
|
@ -911,17 +911,12 @@ void DtoResolveVariable(VarDeclaration *vd) {
|
|||
// with a different type later, swap it out and replace any existing
|
||||
// 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 =
|
||||
getOrCreateGlobal(vd->loc, gIR->module, DtoMemType(vd->type), isLLConst,
|
||||
linkage, nullptr, irMangle, vd->isThreadlocal());
|
||||
declareGlobal(vd->loc, gIR->module, DtoMemType(vd->type), irMangle,
|
||||
isLLConst, vd->isThreadlocal());
|
||||
if (vd->llvmInternal == LLVMextern_weak)
|
||||
gvar->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
|
||||
|
||||
auto varIr = getIrGlobal(vd);
|
||||
varIr->value = gvar;
|
||||
|
||||
|
@ -1751,19 +1746,20 @@ llvm::Constant *buildStringLiteralConstant(StringExp *se, bool zeroTerm) {
|
|||
return LLConstantArray::get(at, vals);
|
||||
}
|
||||
|
||||
llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module,
|
||||
llvm::Type *type, bool isConstant,
|
||||
llvm::GlobalValue::LinkageTypes linkage,
|
||||
llvm::Constant *init,
|
||||
llvm::StringRef name,
|
||||
bool isThreadLocal) {
|
||||
llvm::GlobalVariable *existing = module.getGlobalVariable(name, true);
|
||||
llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
|
||||
llvm::Type *type,
|
||||
llvm::StringRef mangledName,
|
||||
bool isConstant, bool isThreadLocal) {
|
||||
llvm::GlobalVariable *existing =
|
||||
module.getGlobalVariable(mangledName, /*AllowInternal=*/true);
|
||||
if (existing) {
|
||||
if (existing->getType()->getElementType() != type) {
|
||||
if (existing->getType()->getElementType() != type ||
|
||||
existing->isConstant() != isConstant ||
|
||||
existing->isThreadLocal() != isThreadLocal) {
|
||||
error(loc,
|
||||
"Global variable type does not match previous declaration with "
|
||||
"same mangled name: `%s`",
|
||||
name.str().c_str());
|
||||
mangledName.str().c_str());
|
||||
fatal();
|
||||
}
|
||||
return existing;
|
||||
|
@ -1772,14 +1768,36 @@ llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module,
|
|||
// Use a command line option for the thread model.
|
||||
// On PPC there is only local-exec available - in this case just ignore the
|
||||
// command line.
|
||||
const llvm::GlobalVariable::ThreadLocalMode tlsModel =
|
||||
const auto tlsModel =
|
||||
isThreadLocal
|
||||
? (global.params.targetTriple->getArch() == llvm::Triple::ppc
|
||||
? llvm::GlobalVariable::LocalExecTLSModel
|
||||
: clThreadModel.getValue())
|
||||
: 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) {
|
||||
|
|
|
@ -245,19 +245,30 @@ stringLiteralCacheForType(Type *charType);
|
|||
|
||||
llvm::Constant *buildStringLiteralConstant(StringExp *se, bool zeroTerm);
|
||||
|
||||
/// Tries to create an LLVM global with the given properties. If a variable with
|
||||
/// the same mangled name already exists, checks if the types match and returns
|
||||
/// it instead.
|
||||
/// Tries to declare an LLVM global. If a variable with the same mangled name
|
||||
/// already exists, checks if the types match and returns it instead.
|
||||
///
|
||||
/// Necessary to support multiple declarations with the same mangled name, as
|
||||
/// can be the case due to pragma(mangle).
|
||||
llvm::GlobalVariable *getOrCreateGlobal(const Loc &loc, llvm::Module &module,
|
||||
llvm::Type *type, bool isConstant,
|
||||
llvm::GlobalValue::LinkageTypes linkage,
|
||||
llvm::Constant *init,
|
||||
llvm::StringRef name,
|
||||
llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
|
||||
llvm::Type *type,
|
||||
llvm::StringRef mangledName,
|
||||
bool isConstant,
|
||||
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);
|
||||
|
||||
void Declaration_codegen(Dsymbol *decl);
|
||||
|
|
|
@ -169,18 +169,15 @@ LLFunction *build_module_reference_and_ctor(const char *moduleMangle,
|
|||
|
||||
// create the ModuleReference node for this module
|
||||
const auto thismrefIRMangle = getIRMangledModuleRefSymbolName(moduleMangle);
|
||||
Loc loc;
|
||||
LLGlobalVariable *thismref = getOrCreateGlobal(
|
||||
loc, gIR->module, modulerefTy, false, LLGlobalValue::InternalLinkage,
|
||||
thismrefinit, thismrefIRMangle);
|
||||
LLGlobalVariable *thismref =
|
||||
defineGlobal(Loc(), gIR->module, thismrefIRMangle, thismrefinit,
|
||||
LLGlobalValue::InternalLinkage, false);
|
||||
// make sure _Dmodule_ref is declared
|
||||
const auto mrefIRMangle = getIRMangledVarName("_Dmodule_ref", LINKc);
|
||||
LLConstant *mref = gIR->module.getNamedGlobal(mrefIRMangle);
|
||||
LLType *modulerefPtrTy = getPtrToType(modulerefTy);
|
||||
if (!mref) {
|
||||
mref = new LLGlobalVariable(gIR->module, modulerefPtrTy, false,
|
||||
LLGlobalValue::ExternalLinkage, nullptr,
|
||||
mrefIRMangle);
|
||||
mref = declareGlobal(Loc(), gIR->module, modulerefPtrTy, mrefIRMangle, false);
|
||||
}
|
||||
mref = DtoBitCast(mref, getPtrToType(modulerefPtrTy));
|
||||
|
||||
|
@ -218,9 +215,9 @@ llvm::Function *buildGetTLSAnchor() {
|
|||
// Create a dummmy TLS global private to this module.
|
||||
const auto one =
|
||||
llvm::ConstantInt::get(llvm::Type::getInt8Ty(gIR->context()), 1);
|
||||
const auto anchor = getOrCreateGlobal(
|
||||
Loc(), gIR->module, one->getType(), false,
|
||||
llvm::GlobalValue::LinkOnceODRLinkage, one, "ldc.tls_anchor", true);
|
||||
const auto anchor = defineGlobal(Loc(), gIR->module, "ldc.tls_anchor", one,
|
||||
llvm::GlobalValue::LinkOnceODRLinkage, false,
|
||||
/*isThreadLocal=*/true);
|
||||
anchor->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
anchor->setAlignment(16);
|
||||
|
||||
|
@ -358,11 +355,11 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
|
|||
|
||||
const auto thismrefIRMangle =
|
||||
getIRMangledModuleRefSymbolName(moduleMangle.c_str());
|
||||
auto thismref = new llvm::GlobalVariable(
|
||||
gIR->module, moduleInfoPtrTy,
|
||||
false, // FIXME: mRelocModel != llvm::Reloc::PIC_
|
||||
auto thismref = defineGlobal(Loc(), gIR->module, thismrefIRMangle,
|
||||
DtoBitCast(thisModuleInfo, moduleInfoPtrTy),
|
||||
llvm::GlobalValue::LinkOnceODRLinkage,
|
||||
DtoBitCast(thisModuleInfo, moduleInfoPtrTy), thismrefIRMangle);
|
||||
false // FIXME: mRelocModel != llvm::Reloc::PIC_
|
||||
);
|
||||
thismref->setSection(sectionName);
|
||||
gIR->usedArray.push_back(thismref);
|
||||
|
||||
|
@ -382,22 +379,19 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
|
|||
const auto magicEndSymbolName = (style == RegistryStyle::sectionDarwin)
|
||||
? "\1section$end$__DATA$.minfo"
|
||||
: "__stop___minfo";
|
||||
auto minfoBeg = new llvm::GlobalVariable(gIR->module, moduleInfoPtrTy, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
nullptr, magicBeginSymbolName);
|
||||
auto minfoEnd = new llvm::GlobalVariable(gIR->module, moduleInfoPtrTy, false,
|
||||
llvm::GlobalValue::ExternalLinkage,
|
||||
nullptr, magicEndSymbolName);
|
||||
auto minfoBeg = declareGlobal(Loc(), gIR->module, moduleInfoPtrTy,
|
||||
magicBeginSymbolName, false);
|
||||
auto minfoEnd = declareGlobal(Loc(), gIR->module, moduleInfoPtrTy,
|
||||
magicEndSymbolName, false);
|
||||
minfoBeg->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
minfoEnd->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
|
||||
// Build the ctor to invoke _d_dso_registry.
|
||||
|
||||
// This is the DSO slot for use by the druntime implementation.
|
||||
auto dsoSlot =
|
||||
new llvm::GlobalVariable(gIR->module, getVoidPtrType(), false,
|
||||
llvm::GlobalValue::LinkOnceODRLinkage,
|
||||
getNullPtr(getVoidPtrType()), "ldc.dso_slot");
|
||||
auto dsoSlot = defineGlobal(Loc(), gIR->module, "ldc.dso_slot",
|
||||
getNullPtr(getVoidPtrType()),
|
||||
llvm::GlobalValue::LinkOnceODRLinkage, false);
|
||||
dsoSlot->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
|
||||
// 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
|
||||
// directly using e.g. "g++ dcode.o cppcode.o", though.
|
||||
|
||||
auto dsoInitialized = new llvm::GlobalVariable(
|
||||
gIR->module, llvm::Type::getInt8Ty(gIR->context()), false,
|
||||
llvm::GlobalValue::LinkOnceODRLinkage,
|
||||
auto dsoInitialized = defineGlobal(
|
||||
Loc(), gIR->module, "ldc.dso_initialized",
|
||||
llvm::ConstantInt::get(llvm::Type::getInt8Ty(gIR->context()), 0),
|
||||
"ldc.dso_initialized");
|
||||
llvm::GlobalValue::LinkOnceODRLinkage, false);
|
||||
dsoInitialized->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
|
||||
// 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::get(type);
|
||||
m->d_cover_valid = new llvm::GlobalVariable(
|
||||
gIR->module, type, true, LLGlobalValue::InternalLinkage,
|
||||
gIR->module, type, /*isConstant=*/true, LLGlobalValue::InternalLinkage,
|
||||
zeroinitializer, "_d_cover_valid");
|
||||
LLConstant *idxs[] = {DtoConstUint(0), DtoConstUint(0)};
|
||||
d_cover_valid_slice =
|
||||
|
|
|
@ -165,9 +165,8 @@ llvm::StructType *getTypeDescriptorType(IRState &irs,
|
|||
llvm::GlobalVariable *getTypeDescriptor(IRState &irs, ClassDeclaration *cd) {
|
||||
if (cd->isCPPclass()) {
|
||||
const char *name = Target::cppTypeInfoMangle(cd);
|
||||
return getOrCreateGlobal(
|
||||
cd->loc, irs.module, getVoidPtrType(), /*isConstant=*/true,
|
||||
LLGlobalValue::ExternalLinkage, /*init=*/nullptr, name);
|
||||
return declareGlobal(cd->loc, irs.module, getVoidPtrType(), name,
|
||||
/*isConstant=*/true);
|
||||
}
|
||||
|
||||
auto classInfoPtr = getIrAggr(cd, true)->getClassInfoSymbol();
|
||||
|
@ -188,10 +187,9 @@ llvm::GlobalVariable *getTypeDescriptor(IRState &irs, ClassDeclaration *cd) {
|
|||
llvm::ConstantDataArray::getString(gIR->context(), TypeNameString)};
|
||||
llvm::StructType *TypeDescriptorType =
|
||||
getTypeDescriptorType(irs, classInfoPtr, TypeNameString);
|
||||
Var = new llvm::GlobalVariable(
|
||||
gIR->module, TypeDescriptorType, /*Constant=*/false,
|
||||
LLGlobalVariable::InternalLinkage, // getLinkageForRTTI(Type),
|
||||
llvm::ConstantStruct::get(TypeDescriptorType, Fields), TypeDescName);
|
||||
Var = defineGlobal(cd->loc, gIR->module, TypeDescName,
|
||||
llvm::ConstantStruct::get(TypeDescriptorType, Fields),
|
||||
LLGlobalVariable::InternalLinkage, false);
|
||||
return Var;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,18 +161,22 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
|
|||
|
||||
LLGlobalVariable *ci;
|
||||
if (p.cd->isCPPclass()) {
|
||||
const char *name = Target::cppTypeInfoMangle(p.cd);
|
||||
auto cpp_ti = getOrCreateGlobal(
|
||||
p.cd->loc, irs.module, getVoidPtrType(), /*isConstant=*/true,
|
||||
LLGlobalValue::ExternalLinkage, /*init=*/nullptr, name);
|
||||
// Wrap std::type_info pointers inside a __cpp_type_info_ptr class
|
||||
// instance so that the personality routine may differentiate C++ catch
|
||||
// clauses from D ones.
|
||||
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
|
||||
// the personality routine may differentiate C++ catch clauses from D ones.
|
||||
OutBuffer mangleBuf;
|
||||
mangleBuf.writestring("_D");
|
||||
mangleToBuffer(p.cd, &mangleBuf);
|
||||
mangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr");
|
||||
const auto wrapperMangle = getIRMangledVarName(mangleBuf.peekString(), LINKd);
|
||||
ci = irs.module.getGlobalVariable(wrapperMangle);
|
||||
if (!ci) {
|
||||
const char *name = Target::cppTypeInfoMangle(p.cd);
|
||||
auto cpp_ti =
|
||||
declareGlobal(p.cd->loc, irs.module, getVoidPtrType(), name,
|
||||
/*isConstant=*/true);
|
||||
|
||||
const auto cppTypeInfoPtrType = getCppTypeInfoPtrType();
|
||||
RTTIBuilder b(cppTypeInfoPtrType);
|
||||
|
@ -183,9 +187,10 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
|
|||
->getMemoryLLType());
|
||||
auto wrapperInit = b.get_constant(wrapperType);
|
||||
|
||||
ci = getOrCreateGlobal(
|
||||
p.cd->loc, irs.module, wrapperType, /*isConstant=*/true,
|
||||
LLGlobalValue::LinkOnceODRLinkage, wrapperInit, wrapperMangle);
|
||||
ci = defineGlobal(p.cd->loc, irs.module, wrapperMangle, wrapperInit,
|
||||
LLGlobalValue::LinkOnceODRLinkage,
|
||||
/*isConstant=*/true);
|
||||
}
|
||||
} else {
|
||||
ci = getIrAggr(p.cd)->getClassInfoSymbol();
|
||||
}
|
||||
|
|
|
@ -624,18 +624,11 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
|
|||
}
|
||||
|
||||
const auto irMangle = getIRMangledVarName(mangled, LINKd);
|
||||
LLGlobalVariable *gvar = gIR->module.getGlobalVariable(irMangle);
|
||||
if (gvar) {
|
||||
assert(gvar->getType()->getContainedType(0)->isStructTy());
|
||||
} else {
|
||||
LLType *type = DtoType(decl->type)->getPointerElementType();
|
||||
// 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);
|
||||
}
|
||||
// Declare 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.
|
||||
auto gvar = declareGlobal(decl->loc, gIR->module, type, irMangle, false);
|
||||
|
||||
IrGlobal *irg = getIrGlobal(decl, true);
|
||||
irg->value = gvar;
|
||||
|
|
|
@ -49,9 +49,8 @@ LLConstant *&IrAggr::getInitSymbol() {
|
|||
// create the initZ symbol
|
||||
const auto irMangle = getIRMangledInitSymbolName(aggrdecl);
|
||||
|
||||
auto initGlobal =
|
||||
getOrCreateGlobal(aggrdecl->loc, gIR->module, getLLStructType(), true,
|
||||
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
|
||||
auto initGlobal = declareGlobal(aggrdecl->loc, gIR->module, getLLStructType(),
|
||||
irMangle, /*isConstant=*/true);
|
||||
initGlobal->setAlignment(DtoAlignment(type));
|
||||
|
||||
init = initGlobal;
|
||||
|
|
|
@ -51,9 +51,8 @@ LLGlobalVariable *IrAggr::getVtblSymbol() {
|
|||
|
||||
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType();
|
||||
|
||||
vtbl =
|
||||
getOrCreateGlobal(aggrdecl->loc, gIR->module, vtblTy, true,
|
||||
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
|
||||
vtbl = declareGlobal(aggrdecl->loc, gIR->module, vtblTy, irMangle,
|
||||
/*isConstant=*/true);
|
||||
|
||||
return vtbl;
|
||||
}
|
||||
|
@ -77,9 +76,8 @@ LLGlobalVariable *IrAggr::getClassInfoSymbol() {
|
|||
assert(tc && "invalid ClassInfo type");
|
||||
|
||||
// classinfos cannot be constants since they're used as locks for synchronized
|
||||
classInfo = getOrCreateGlobal(
|
||||
aggrdecl->loc, gIR->module, tc->getMemoryLLType(), false,
|
||||
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
|
||||
classInfo = declareGlobal(aggrdecl->loc, gIR->module, tc->getMemoryLLType(),
|
||||
irMangle, false);
|
||||
|
||||
// Generate some metadata on this ClassInfo if it's for a class.
|
||||
ClassDeclaration *classdecl = aggrdecl->isClassDeclaration();
|
||||
|
@ -139,11 +137,8 @@ LLGlobalVariable *IrAggr::getInterfaceArraySymbol() {
|
|||
|
||||
LLArrayType *array_type = llvm::ArrayType::get(InterfaceTy, n);
|
||||
|
||||
// We keep the global as external for now and only consider template linkage
|
||||
// if we emit the initializer later.
|
||||
classInterfacesArray =
|
||||
getOrCreateGlobal(cd->loc, gIR->module, array_type, true,
|
||||
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
|
||||
classInterfacesArray = declareGlobal(cd->loc, gIR->module, array_type,
|
||||
irMangle, /*isConstant=*/true);
|
||||
|
||||
return classInterfacesArray;
|
||||
}
|
||||
|
@ -457,8 +452,8 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
|
||||
const auto lwc = DtoLinkage(cd);
|
||||
LLGlobalVariable *GV =
|
||||
getOrCreateGlobal(cd->loc, gIR->module, vtbl_constant->getType(), true,
|
||||
lwc.first, vtbl_constant, irMangle);
|
||||
defineGlobal(cd->loc, gIR->module, irMangle, vtbl_constant,
|
||||
lwc.first, /*isConstant=*/true);
|
||||
setLinkage(lwc, GV);
|
||||
|
||||
// insert into the vtbl map
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "module.h"
|
||||
#include "gen/llvm.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/mangling.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irdsymbol.h"
|
||||
|
@ -25,9 +26,9 @@ llvm::GlobalVariable *IrModule::moduleInfoSymbol() {
|
|||
|
||||
const auto irMangle = getIRMangledModuleInfoSymbolName(M);
|
||||
|
||||
moduleInfoVar = new llvm::GlobalVariable(
|
||||
gIR->module, llvm::StructType::create(gIR->context()), false,
|
||||
llvm::GlobalValue::ExternalLinkage, nullptr, irMangle);
|
||||
moduleInfoVar =
|
||||
declareGlobal(Loc(), gIR->module,
|
||||
llvm::StructType::create(gIR->context()), irMangle, false);
|
||||
return moduleInfoVar;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue