Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/irgenerator/GenVTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ llvm::Constant *IRGenerator::generateTypeInfoName(StructBase *spiceStruct) const
// Set global attributes
global->setConstant(true);
global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
global->setLinkage(getSymbolLinkageType(isPublic));
global->setLinkage(getVTableLinkageType(isPublic));
global->setDSOLocal(isSymbolDSOLocal(isPublic));
attachComdatToSymbol(global, globalName, isPublic);

Expand Down Expand Up @@ -83,7 +83,7 @@ llvm::Constant *IRGenerator::generateTypeInfo(StructBase *spiceStruct) const {
// Set global attributes
global->setConstant(true);
global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
global->setLinkage(getSymbolLinkageType(isPublic));
global->setLinkage(getVTableLinkageType(isPublic));
global->setDSOLocal(isSymbolDSOLocal(isPublic));
global->setAlignment(llvm::MaybeAlign(8));
attachComdatToSymbol(global, mangledName, isPublic);
Expand Down Expand Up @@ -113,7 +113,7 @@ llvm::Constant *IRGenerator::generateVTable(StructBase *spiceStruct) const {
// Set global attributes
global->setConstant(true);
global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
global->setLinkage(getSymbolLinkageType(isPublic));
global->setLinkage(getVTableLinkageType(isPublic));
global->setDSOLocal(isSymbolDSOLocal(isPublic));
global->setAlignment(llvm::MaybeAlign(8));
attachComdatToSymbol(global, mangledName, isPublic);
Expand Down
8 changes: 8 additions & 0 deletions src/irgenerator/IRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,14 @@ llvm::GlobalValue::LinkageTypes IRGenerator::getSymbolLinkageType(bool isPublic)
return isPublic ? llvm::GlobalValue::ExternalLinkage : llvm::GlobalValue::PrivateLinkage;
}

llvm::GlobalValue::LinkageTypes IRGenerator::getVTableLinkageType(bool isPublic) const {
// VTables, type infos and type info names are ODR entities that may legitimately be emitted in more than one
// translation unit (e.g. an interface that is forward-declared in one file and fully defined in another). Giving
// them weak ODR linkage lets the linker coalesce the duplicates. On ELF this pairs with the comdat group below; on
// MachO, which has no comdat support, the weak/coalesced linkage is what prevents a duplicate-symbol error.
return isPublic ? llvm::GlobalValue::WeakODRLinkage : llvm::GlobalValue::PrivateLinkage;
}

void IRGenerator::attachComdatToSymbol(llvm::GlobalVariable *global, const std::string &comdatName, bool isPublic) const {
// MachO does not support comdat annotations
if (isPublic && cliOptions.targetTriple.getObjectFormat() != llvm::Triple::MachO)
Expand Down
1 change: 1 addition & 0 deletions src/irgenerator/IRGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class IRGenerator final : CompilerPass, public ParallelizableASTVisitor {
llvm::Attribute::AttrKind getExtAttrKindForType(const QualType &type) const;
bool isSymbolDSOLocal(bool isPublic) const;
llvm::GlobalValue::LinkageTypes getSymbolLinkageType(bool isPublic) const;
llvm::GlobalValue::LinkageTypes getVTableLinkageType(bool isPublic) const;
void attachComdatToSymbol(llvm::GlobalVariable *global, const std::string &comdatName, bool isPublic) const;

// Generate implicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ $_ZTI3Car = comdat any

$_ZTV3Car = comdat any

@_ZTS3Car = dso_local constant [5 x i8] c"3Car\00", comdat, align 4
@_ZTS3Car = weak_odr dso_local constant [5 x i8] c"3Car\00", comdat, align 4
@_ZTV8TypeInfo = external global ptr
@_ZTI9Driveable = external global ptr
@_ZTI3Car = dso_local constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTV8TypeInfo, i64 2), ptr @_ZTS3Car, ptr @_ZTI9Driveable }, comdat, align 8
@_ZTV3Car = dso_local unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI3Car, ptr @_ZN3Car5driveEi, ptr @_ZN3Car9isDrivingEv] }, comdat, align 8
@_ZTI3Car = weak_odr dso_local constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTV8TypeInfo, i64 2), ptr @_ZTS3Car, ptr @_ZTI9Driveable }, comdat, align 8
@_ZTV3Car = weak_odr dso_local unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI3Car, ptr @_ZN3Car5driveEi, ptr @_ZN3Car9isDrivingEv] }, comdat, align 8
@printf.str.0 = private unnamed_addr constant [15 x i8] c"Is driving: %d\00", align 4

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ $_ZTI3Car = comdat any

$_ZTV3Car = comdat any

@_ZTS3Car = dso_local constant [5 x i8] c"3Car\00", comdat, align 4
@_ZTS3Car = weak_odr dso_local constant [5 x i8] c"3Car\00", comdat, align 4
@_ZTV8TypeInfo = external global ptr
@_ZTI9Driveable = external global ptr
@_ZTI3Car = dso_local constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTV8TypeInfo, i64 2), ptr @_ZTS3Car, ptr @_ZTI9Driveable }, comdat, align 8
@_ZTV3Car = dso_local unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI3Car, ptr @_ZN3Car5driveEi, ptr @_ZN3Car9isDrivingEv] }, comdat, align 8
@_ZTI3Car = weak_odr dso_local constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTV8TypeInfo, i64 2), ptr @_ZTS3Car, ptr @_ZTI9Driveable }, comdat, align 8
@_ZTV3Car = weak_odr dso_local unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI3Car, ptr @_ZN3Car5driveEi, ptr @_ZN3Car9isDrivingEv] }, comdat, align 8
@printf.str.0 = private unnamed_addr constant [15 x i8] c"Is driving: %d\00", align 4

define private void @_ZN3Car4ctorEv(ptr noundef nonnull align 8 dereferenceable(16) %0) {
Expand Down
Loading