From ae9231ca2a8125ce75fff3ff2539126610aa2eeb Mon Sep 17 00:00:00 2001 From: Ben Dunbobbin Date: Mon, 2 Nov 2020 23:24:04 +0000 Subject: Reland - [Clang] Add the ability to map DLL storage class to visibility 415f7ee883 had LIT test failures on any build where the clang executable was not called "clang". I have adjusted the LIT CHECKs to remove the binary name to fix this. Original commit message: For PlayStation we offer source code compatibility with Microsoft's dllimport/export annotations; however, our file format is based on ELF. To support this we translate from DLL storage class to ELF visibility at the end of codegen in Clang. Other toolchains have used similar strategies (e.g. see the documentation for this ARM toolchain: https://developer.arm.com/documentation/dui0530/i/migrating-from-rvct-v3-1-to-rvct-v4-0/changes-to-symbol-visibility-between-rvct-v3-1-and-rvct-v4-0) This patch adds the ability to perform this translation. Options are provided to support customizing the mapping behaviour. Differential Revision: https://reviews.llvm.org/D89970 --- clang/lib/CodeGen/CodeGenModule.cpp | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 66a3c57b9112..9512b350d9fd 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -401,6 +401,41 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags, } } +static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO, + llvm::Module &M) { + if (!LO.VisibilityFromDLLStorageClass) + return; + + llvm::GlobalValue::VisibilityTypes DLLExportVisibility = + CodeGenModule::GetLLVMVisibility(LO.getDLLExportVisibility()); + llvm::GlobalValue::VisibilityTypes NoDLLStorageClassVisibility = + CodeGenModule::GetLLVMVisibility(LO.getNoDLLStorageClassVisibility()); + llvm::GlobalValue::VisibilityTypes ExternDeclDLLImportVisibility = + CodeGenModule::GetLLVMVisibility(LO.getExternDeclDLLImportVisibility()); + llvm::GlobalValue::VisibilityTypes ExternDeclNoDLLStorageClassVisibility = + CodeGenModule::GetLLVMVisibility( + LO.getExternDeclNoDLLStorageClassVisibility()); + + for (llvm::GlobalValue &GV : M.global_values()) { + if (GV.hasAppendingLinkage() || GV.hasLocalLinkage()) + return; + + if (GV.isDeclarationForLinker()) { + GV.setVisibility(GV.getDLLStorageClass() == + llvm::GlobalValue::DLLImportStorageClass + ? ExternDeclDLLImportVisibility + : ExternDeclNoDLLStorageClassVisibility); + } else { + GV.setVisibility(GV.getDLLStorageClass() == + llvm::GlobalValue::DLLExportStorageClass + ? DLLExportVisibility + : NoDLLStorageClassVisibility); + } + + GV.setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + } +} + void CodeGenModule::Release() { EmitDeferred(); EmitVTablesOpportunistically(); @@ -688,6 +723,12 @@ void CodeGenModule::Release() { getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames); EmitBackendOptionsMetadata(getCodeGenOpts()); + + // Set visibility from DLL export class + // We do this at the end of LLVM IR generation; after any operation + // that might affect the DLL storage class or the visibility, and + // before anything that might act on these. + setVisibilityFromDLLStorageClass(LangOpts, getModule()); } void CodeGenModule::EmitOpenCLMetadata() { -- cgit v1.2.3