summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGVTables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index a74905fd70f..f9f25e7e57a 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -808,7 +808,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration");
CGM.setGVProperties(VTable, RD);
- CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get());
+ CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get());
return VTable;
}
@@ -1039,7 +1039,32 @@ bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
return true;
}
-void CodeGenModule::EmitVTableTypeMetadata(llvm::GlobalVariable *VTable,
+llvm::GlobalObject::VCallVisibility
+CodeGenModule::GetVCallVisibilityLevel(const CXXRecordDecl *RD) {
+ LinkageInfo LV = RD->getLinkageAndVisibility();
+ llvm::GlobalObject::VCallVisibility TypeVis;
+ if (!isExternallyVisible(LV.getLinkage()))
+ TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
+ else if (HasHiddenLTOVisibility(RD))
+ TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
+ else
+ TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
+
+ for (auto B : RD->bases())
+ if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
+ TypeVis = std::min(TypeVis,
+ GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl()));
+
+ for (auto B : RD->vbases())
+ if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
+ TypeVis = std::min(TypeVis,
+ GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl()));
+
+ return TypeVis;
+}
+
+void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
+ llvm::GlobalVariable *VTable,
const VTableLayout &VTLayout) {
if (!getCodeGenOpts().LTOUnit)
return;
@@ -1099,4 +1124,10 @@ void CodeGenModule::EmitVTableTypeMetadata(llvm::GlobalVariable *VTable,
VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
}
}
+
+ if (getCodeGenOpts().VirtualFunctionElimination) {
+ llvm::GlobalObject::VCallVisibility TypeVis = GetVCallVisibilityLevel(RD);
+ if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
+ VTable->addVCallVisibilityMetadata(TypeVis);
+ }
}
OpenPOWER on IntegriCloud