mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
Teach LTOModule to emit linker flags for dllexported symbols, plus interface cleanup.
This change unifies how LTOModule and the backend obtain linker flags for globals: via a new TargetLoweringObjectFile member function named emitLinkerFlagsForGlobal. A new function LTOModule::getLinkerOpts() returns the list of linker flags as a single concatenated string. This change affects the C libLTO API: the function lto_module_get_*deplibs now exposes an empty list, and lto_module_get_*linkeropts exposes a single element which combines the contents of all observed flags. libLTO should never have tried to parse the linker flags; it is the linker's job to do so. Because linkers will need to be able to parse flags in regular object files, it makes little sense for libLTO to have a redundant mechanism for doing so. The new API is compatible with the old one. It is valid for a user to specify multiple linker flags in a single pragma directive like this: #pragma comment(linker, "/defaultlib:foo /defaultlib:bar") The previous implementation would not have exposed either flag via lto_module_get_*deplibs (as the test in TargetLoweringObjectFileCOFF::getDepLibFromLinkerOpt was case sensitive) and would have exposed "/defaultlib:foo /defaultlib:bar" as a single flag via lto_module_get_*linkeropts. This may have been a bug in the implementation, but it does give us a chance to fix the interface. Differential Revision: http://reviews.llvm.org/D10548 llvm-svn: 241010
This commit is contained in:
parent
7226bf4ba4
commit
d3c303721f
@ -282,6 +282,8 @@ lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
|
||||
/**
|
||||
* Returns the number of dependent libraries in the object module.
|
||||
*
|
||||
* Deprecated. Now returns an empty list.
|
||||
*
|
||||
* \since LTO_API_VERSION=8
|
||||
*/
|
||||
extern unsigned int
|
||||
@ -291,6 +293,8 @@ lto_module_get_num_deplibs(lto_module_t mod);
|
||||
/**
|
||||
* Returns the ith dependent library in the module.
|
||||
*
|
||||
* Deprecated. Now always returns null.
|
||||
*
|
||||
* \since LTO_API_VERSION=8
|
||||
*/
|
||||
extern const char*
|
||||
@ -300,6 +304,9 @@ lto_module_get_deplib(lto_module_t mod, unsigned int index);
|
||||
/**
|
||||
* Returns the number of linker options in the object module.
|
||||
*
|
||||
* Each linker option may consist of multiple flags. It is the linker's
|
||||
* responsibility to split the flags using a platform-specific mechanism.
|
||||
*
|
||||
* \since LTO_API_VERSION=8
|
||||
*/
|
||||
extern unsigned int
|
||||
@ -309,6 +316,9 @@ lto_module_get_num_linkeropts(lto_module_t mod);
|
||||
/**
|
||||
* Returns the ith linker option in the module.
|
||||
*
|
||||
* Each linker option may consist of multiple flags. It is the linker's
|
||||
* responsibility to split the flags using a platform-specific mechanism.
|
||||
*
|
||||
* \since LTO_API_VERSION=8
|
||||
*/
|
||||
extern const char*
|
||||
|
@ -90,10 +90,6 @@ public:
|
||||
~TargetLoweringObjectFileMachO() override {}
|
||||
TargetLoweringObjectFileMachO();
|
||||
|
||||
/// Extract the dependent library name from a linker option string. Returns
|
||||
/// StringRef() if the option does not specify a library.
|
||||
StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
|
||||
|
||||
/// Emit the module flags that specify the garbage collection information.
|
||||
void emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
@ -150,10 +146,6 @@ public:
|
||||
MCSection *getSectionForJumpTable(const Function &F, Mangler &Mang,
|
||||
const TargetMachine &TM) const override;
|
||||
|
||||
/// Extract the dependent library name from a linker option string. Returns
|
||||
/// StringRef() if the option does not specify a library.
|
||||
StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
|
||||
|
||||
/// Emit Obj-C garbage collection and linker options. Only linker option
|
||||
/// emission is implemented for COFF.
|
||||
void emitModuleFlags(MCStreamer &Streamer,
|
||||
@ -164,6 +156,9 @@ public:
|
||||
const MCSymbol *KeySym) const override;
|
||||
MCSection *getStaticDtorSection(unsigned Priority,
|
||||
const MCSymbol *KeySym) const override;
|
||||
|
||||
void emitLinkerFlagsForGlobal(raw_ostream &OS, const GlobalValue *GV,
|
||||
const Mangler &Mang) const override;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -47,12 +47,11 @@ private:
|
||||
|
||||
std::unique_ptr<LLVMContext> OwnedContext;
|
||||
|
||||
std::string LinkerOpts;
|
||||
|
||||
std::unique_ptr<object::IRObjectFile> IRFile;
|
||||
std::unique_ptr<TargetMachine> _target;
|
||||
StringSet<> _linkeropt_strings;
|
||||
std::vector<const char *> _deplibs;
|
||||
std::vector<const char *> _linkeropts;
|
||||
std::vector<NameAndAttributes> _symbols;
|
||||
std::vector<NameAndAttributes> _symbols;
|
||||
|
||||
// _defines and _undefines only needed to disambiguate tentative definitions
|
||||
StringSet<> _defines;
|
||||
@ -149,28 +148,8 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Get the number of dependent libraries
|
||||
uint32_t getDependentLibraryCount() {
|
||||
return _deplibs.size();
|
||||
}
|
||||
|
||||
/// Get the dependent library at the specified index.
|
||||
const char *getDependentLibrary(uint32_t index) {
|
||||
if (index < _deplibs.size())
|
||||
return _deplibs[index];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Get the number of linker options
|
||||
uint32_t getLinkerOptCount() {
|
||||
return _linkeropts.size();
|
||||
}
|
||||
|
||||
/// Get the linker option at the specified index.
|
||||
const char *getLinkerOpt(uint32_t index) {
|
||||
if (index < _linkeropts.size())
|
||||
return _linkeropts[index];
|
||||
return nullptr;
|
||||
const char *getLinkerOpts() {
|
||||
return LinkerOpts.c_str();
|
||||
}
|
||||
|
||||
const std::vector<const char*> &getAsmUndefinedRefs() {
|
||||
|
@ -64,12 +64,6 @@ public:
|
||||
const TargetMachine &TM,
|
||||
const MCSymbol *Sym) const;
|
||||
|
||||
/// Extract the dependent library name from a linker option string. Returns
|
||||
/// StringRef() if the option does not specify a library.
|
||||
virtual StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const {
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
/// Emit the module flags that the platform cares about.
|
||||
virtual void emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> Flags,
|
||||
@ -188,6 +182,9 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void emitLinkerFlagsForGlobal(raw_ostream &OS, const GlobalValue *GV,
|
||||
const Mangler &Mang) const {}
|
||||
|
||||
protected:
|
||||
virtual MCSection *SelectSectionForGlobal(const GlobalValue *GV,
|
||||
SectionKind Kind, Mangler &Mang,
|
||||
|
@ -440,16 +440,6 @@ TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO()
|
||||
SupportIndirectSymViaGOTPCRel = true;
|
||||
}
|
||||
|
||||
/// getDepLibFromLinkerOpt - Extract the dependent library name from a linker
|
||||
/// option string. Returns StringRef() if the option does not specify a library.
|
||||
StringRef TargetLoweringObjectFileMachO::
|
||||
getDepLibFromLinkerOpt(StringRef LinkerOption) const {
|
||||
const char *LibCmd = "-l";
|
||||
if (LinkerOption.startswith(LibCmd))
|
||||
return LinkerOption.substr(strlen(LibCmd));
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
/// emitModuleFlags - Perform code emission for module flags.
|
||||
void TargetLoweringObjectFileMachO::
|
||||
emitModuleFlags(MCStreamer &Streamer,
|
||||
@ -990,14 +980,6 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
|
||||
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
|
||||
}
|
||||
|
||||
StringRef TargetLoweringObjectFileCOFF::
|
||||
getDepLibFromLinkerOpt(StringRef LinkerOption) const {
|
||||
const char *LibCmd = "/DEFAULTLIB:";
|
||||
if (LinkerOption.startswith(LibCmd))
|
||||
return LinkerOption.substr(strlen(LibCmd));
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileCOFF::
|
||||
emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
@ -1045,3 +1027,36 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
|
||||
return getContext().getAssociativeCOFFSection(
|
||||
cast<MCSectionCOFF>(StaticDtorSection), KeySym);
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
|
||||
raw_ostream &OS, const GlobalValue *GV, const Mangler &Mang) const {
|
||||
if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
|
||||
return;
|
||||
|
||||
const Triple &TT = getTargetTriple();
|
||||
|
||||
if (TT.isKnownWindowsMSVCEnvironment())
|
||||
OS << " /EXPORT:";
|
||||
else
|
||||
OS << " -export:";
|
||||
|
||||
if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
|
||||
std::string Flag;
|
||||
raw_string_ostream FlagOS(Flag);
|
||||
Mang.getNameWithPrefix(FlagOS, GV, false);
|
||||
FlagOS.flush();
|
||||
if (Flag[0] == DL->getGlobalPrefix())
|
||||
OS << Flag.substr(1);
|
||||
else
|
||||
OS << Flag;
|
||||
} else {
|
||||
Mang.getNameWithPrefix(OS, GV, false);
|
||||
}
|
||||
|
||||
if (!GV->getValueType()->isFunctionTy()) {
|
||||
if (TT.isKnownWindowsMSVCEnvironment())
|
||||
OS << ",DATA";
|
||||
else
|
||||
OS << ",data";
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DiagnosticPrinter.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
@ -642,6 +643,8 @@ bool LTOModule::parseSymbols(std::string &errMsg) {
|
||||
|
||||
/// parseMetadata - Parse metadata from the module
|
||||
void LTOModule::parseMetadata() {
|
||||
raw_string_ostream OS(LinkerOpts);
|
||||
|
||||
// Linker Options
|
||||
if (Metadata *Val = getModule().getModuleFlag("Linker Options")) {
|
||||
MDNode *LinkerOptions = cast<MDNode>(Val);
|
||||
@ -649,20 +652,19 @@ void LTOModule::parseMetadata() {
|
||||
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
|
||||
for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
|
||||
MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
|
||||
// FIXME: Make StringSet::insert match Self-Associative Container
|
||||
// requirements, returning <iter,bool> rather than bool, and use that
|
||||
// here.
|
||||
StringRef Op =
|
||||
_linkeropt_strings.insert(MDOption->getString()).first->first();
|
||||
StringRef DepLibName =
|
||||
_target->getObjFileLowering()->getDepLibFromLinkerOpt(Op);
|
||||
if (!DepLibName.empty())
|
||||
_deplibs.push_back(DepLibName.data());
|
||||
else if (!Op.empty())
|
||||
_linkeropts.push_back(Op.data());
|
||||
OS << " " << MDOption->getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Globals
|
||||
Mangler Mang;
|
||||
for (const NameAndAttributes &Sym : _symbols) {
|
||||
if (!Sym.symbol)
|
||||
continue;
|
||||
_target->getObjFileLowering()->emitLinkerFlagsForGlobal(OS, Sym.symbol,
|
||||
Mang);
|
||||
}
|
||||
|
||||
// Add other interesting metadata here.
|
||||
}
|
||||
|
@ -581,34 +581,6 @@ MCSymbol *X86AsmPrinter::GetCPISymbol(unsigned CPID) const {
|
||||
return AsmPrinter::GetCPISymbol(CPID);
|
||||
}
|
||||
|
||||
void X86AsmPrinter::GenerateExportDirective(const MCSymbol *Sym, bool IsData) {
|
||||
SmallString<128> Directive;
|
||||
raw_svector_ostream OS(Directive);
|
||||
StringRef Name = Sym->getName();
|
||||
const Triple &TT = TM.getTargetTriple();
|
||||
|
||||
if (TT.isKnownWindowsMSVCEnvironment())
|
||||
OS << " /EXPORT:";
|
||||
else
|
||||
OS << " -export:";
|
||||
|
||||
if ((TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) &&
|
||||
(Name[0] == getDataLayout().getGlobalPrefix()))
|
||||
Name = Name.drop_front();
|
||||
|
||||
OS << Name;
|
||||
|
||||
if (IsData) {
|
||||
if (TT.isKnownWindowsMSVCEnvironment())
|
||||
OS << ",DATA";
|
||||
else
|
||||
OS << ",data";
|
||||
}
|
||||
|
||||
OS.flush();
|
||||
OutStreamer->EmitBytes(Directive);
|
||||
}
|
||||
|
||||
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||
const Triple &TT = TM.getTargetTriple();
|
||||
|
||||
@ -692,38 +664,25 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||
}
|
||||
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
// Necessary for dllexport support
|
||||
std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;
|
||||
|
||||
for (const auto &Function : M)
|
||||
if (Function.hasDLLExportStorageClass() && !Function.isDeclaration())
|
||||
DLLExportedFns.push_back(getSymbol(&Function));
|
||||
|
||||
for (const auto &Global : M.globals())
|
||||
if (Global.hasDLLExportStorageClass() && !Global.isDeclaration())
|
||||
DLLExportedGlobals.push_back(getSymbol(&Global));
|
||||
|
||||
for (const auto &Alias : M.aliases()) {
|
||||
if (!Alias.hasDLLExportStorageClass())
|
||||
continue;
|
||||
|
||||
if (Alias.getType()->getElementType()->isFunctionTy())
|
||||
DLLExportedFns.push_back(getSymbol(&Alias));
|
||||
else
|
||||
DLLExportedGlobals.push_back(getSymbol(&Alias));
|
||||
}
|
||||
|
||||
// Output linker support code for dllexported globals on windows.
|
||||
if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
|
||||
const TargetLoweringObjectFileCOFF &TLOFCOFF =
|
||||
const TargetLoweringObjectFileCOFF &TLOFCOFF =
|
||||
static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
|
||||
|
||||
OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection());
|
||||
std::string Flags;
|
||||
raw_string_ostream FlagsOS(Flags);
|
||||
|
||||
for (auto & Symbol : DLLExportedGlobals)
|
||||
GenerateExportDirective(Symbol, /*IsData=*/true);
|
||||
for (auto & Symbol : DLLExportedFns)
|
||||
GenerateExportDirective(Symbol, /*IsData=*/false);
|
||||
for (const auto &Function : M)
|
||||
TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Function, *Mang);
|
||||
for (const auto &Global : M.globals())
|
||||
TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Global, *Mang);
|
||||
for (const auto &Alias : M.aliases())
|
||||
TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Alias, *Mang);
|
||||
|
||||
FlagsOS.flush();
|
||||
|
||||
// Output collected flags.
|
||||
if (!Flags.empty()) {
|
||||
OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection());
|
||||
OutStreamer->EmitBytes(Flags);
|
||||
}
|
||||
|
||||
SM.serializeToStackMapSection();
|
||||
|
@ -30,8 +30,6 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
|
||||
StackMaps SM;
|
||||
FaultMaps FM;
|
||||
|
||||
void GenerateExportDirective(const MCSymbol *Sym, bool IsData);
|
||||
|
||||
// This utility class tracks the length of a stackmap instruction's 'shadow'.
|
||||
// It is used by the X86AsmPrinter to ensure that the stackmap shadow
|
||||
// invariants (i.e. no other stackmaps, patchpoints, or control flow within
|
||||
|
@ -71,33 +71,33 @@ define weak_odr dllexport void @weak1() {
|
||||
@blob_alias = dllexport alias bitcast ([6 x i8]* @blob to i32 ()*)
|
||||
|
||||
; CHECK: .section .drectve
|
||||
; WIN32: " /EXPORT:Var1,DATA"
|
||||
; WIN32: " /EXPORT:Var2,DATA"
|
||||
; WIN32: " /EXPORT:Var3,DATA"
|
||||
; WIN32: " /EXPORT:WeakVar1,DATA"
|
||||
; WIN32: " /EXPORT:WeakVar2,DATA"
|
||||
; WIN32: " /EXPORT:f1"
|
||||
; WIN32: " /EXPORT:f2"
|
||||
; WIN32: " /EXPORT:lnk1"
|
||||
; WIN32: " /EXPORT:lnk2"
|
||||
; WIN32: " /EXPORT:weak1"
|
||||
; WIN32: " /EXPORT:alias"
|
||||
; WIN32: " /EXPORT:alias2"
|
||||
; WIN32: " /EXPORT:alias3"
|
||||
; WIN32: " /EXPORT:weak_alias"
|
||||
; WIN32: " /EXPORT:blob_alias"
|
||||
; MINGW: " -export:Var1,data"
|
||||
; MINGW: " -export:Var2,data"
|
||||
; MINGW: " -export:Var3,data"
|
||||
; MINGW: " -export:WeakVar1,data"
|
||||
; MINGW: " -export:WeakVar2,data"
|
||||
; MINGW: " -export:f1"
|
||||
; MINGW: " -export:f2"
|
||||
; MINGW: " -export:lnk1"
|
||||
; MINGW: " -export:lnk2"
|
||||
; MINGW: " -export:weak1"
|
||||
; MINGW: " -export:alias"
|
||||
; MINGW: " -export:alias2"
|
||||
; MINGW: " -export:alias3"
|
||||
; MINGW: " -export:weak_alias"
|
||||
; MINGW: " -export:blob_alias"
|
||||
; WIN32: /EXPORT:f1
|
||||
; WIN32-SAME: /EXPORT:f2
|
||||
; WIN32-SAME: /EXPORT:lnk1
|
||||
; WIN32-SAME: /EXPORT:lnk2
|
||||
; WIN32-SAME: /EXPORT:weak1
|
||||
; WIN32-SAME: /EXPORT:Var1,DATA
|
||||
; WIN32-SAME: /EXPORT:Var2,DATA
|
||||
; WIN32-SAME: /EXPORT:Var3,DATA
|
||||
; WIN32-SAME: /EXPORT:WeakVar1,DATA
|
||||
; WIN32-SAME: /EXPORT:WeakVar2,DATA
|
||||
; WIN32-SAME: /EXPORT:alias
|
||||
; WIN32-SAME: /EXPORT:alias2
|
||||
; WIN32-SAME: /EXPORT:alias3
|
||||
; WIN32-SAME: /EXPORT:weak_alias
|
||||
; WIN32-SAME: /EXPORT:blob_alias
|
||||
; MINGW: -export:f1
|
||||
; MINGW-SAME: -export:f2
|
||||
; MINGW-SAME: -export:lnk1
|
||||
; MINGW-SAME: -export:lnk2
|
||||
; MINGW-SAME: -export:weak1
|
||||
; MINGW-SAME: -export:Var1,data
|
||||
; MINGW-SAME: -export:Var2,data
|
||||
; MINGW-SAME: -export:Var3,data
|
||||
; MINGW-SAME: -export:WeakVar1,data
|
||||
; MINGW-SAME: -export:WeakVar2,data
|
||||
; MINGW-SAME: -export:alias
|
||||
; MINGW-SAME: -export:alias2
|
||||
; MINGW-SAME: -export:alias3
|
||||
; MINGW-SAME: -export:weak_alias
|
||||
; MINGW-SAME: -export:blob_alias"
|
||||
|
@ -89,40 +89,41 @@ define weak_odr dllexport void @weak1() {
|
||||
@weak_alias = weak_odr dllexport alias void()* @f1
|
||||
|
||||
; CHECK: .section .drectve
|
||||
; CHECK-CL: " /EXPORT:_Var1,DATA"
|
||||
; CHECK-CL: " /EXPORT:_Var2,DATA"
|
||||
; CHECK-CL: " /EXPORT:_Var3,DATA"
|
||||
; CHECK-CL: " /EXPORT:_WeakVar1,DATA"
|
||||
; CHECK-CL: " /EXPORT:_WeakVar2,DATA"
|
||||
; CHECK-CL: " /EXPORT:_f1"
|
||||
; CHECK-CL: " /EXPORT:_f2"
|
||||
; CHECK-CL-NOT: not_exported
|
||||
; CHECK-CL: " /EXPORT:_stdfun@0"
|
||||
; CHECK-CL: " /EXPORT:@fastfun@0"
|
||||
; CHECK-CL: " /EXPORT:_thisfun"
|
||||
; CHECK-CL: " /EXPORT:_lnk1"
|
||||
; CHECK-CL: " /EXPORT:_lnk2"
|
||||
; CHECK-CL: " /EXPORT:_weak1"
|
||||
; CHECK-CL: " /EXPORT:_alias"
|
||||
; CHECK-CL: " /EXPORT:_alias2"
|
||||
; CHECK-CL: " /EXPORT:_alias3"
|
||||
; CHECK-CL: " /EXPORT:_weak_alias"
|
||||
; CHECK-GCC: " -export:Var1,data"
|
||||
; CHECK-GCC: " -export:Var2,data"
|
||||
; CHECK-GCC: " -export:Var3,data"
|
||||
; CHECK-GCC: " -export:WeakVar1,data"
|
||||
; CHECK-GCC: " -export:WeakVar2,data"
|
||||
; CHECK-GCC: " -export:f1"
|
||||
; CHECK-GCC: " -export:f2"
|
||||
; CHECK-CL: /EXPORT:_f1
|
||||
; CHECK-CL-SAME: /EXPORT:_f2
|
||||
; CHECK-CL-SAME: /EXPORT:_stdfun@0
|
||||
; CHECK-CL-SAME: /EXPORT:@fastfun@0
|
||||
; CHECK-CL-SAME: /EXPORT:_thisfun
|
||||
; CHECK-CL-SAME: /EXPORT:_lnk1
|
||||
; CHECK-CL-SAME: /EXPORT:_lnk2
|
||||
; CHECK-CL-SAME: /EXPORT:_weak1
|
||||
; CHECK-CL-SAME: /EXPORT:_Var1,DATA
|
||||
; CHECK-CL-SAME: /EXPORT:_Var2,DATA
|
||||
; CHECK-CL-SAME: /EXPORT:_Var3,DATA
|
||||
; CHECK-CL-SAME: /EXPORT:_WeakVar1,DATA
|
||||
; CHECK-CL-SAME: /EXPORT:_WeakVar2,DATA
|
||||
; CHECK-CL-SAME: /EXPORT:_alias
|
||||
; CHECK-CL-SAME: /EXPORT:_alias2
|
||||
; CHECK-CL-SAME: /EXPORT:_alias3
|
||||
; CHECK-CL-SAME: /EXPORT:_weak_alias"
|
||||
; CHECK-CL-NOT: not_exported
|
||||
; CHECK-GCC: " -export:stdfun@0"
|
||||
; CHECK-GCC: " -export:@fastfun@0"
|
||||
; CHECK-GCC: " -export:thisfun"
|
||||
; CHECK-GCC: " -export:lnk1"
|
||||
; CHECK-GCC: " -export:lnk2"
|
||||
; CHECK-GCC: " -export:weak1"
|
||||
; CHECK-GCC: " -export:alias"
|
||||
; CHECK-GCC: " -export:alias2"
|
||||
; CHECK-GCC: " -export:alias3"
|
||||
; CHECK-GCC: " -export:weak_alias"
|
||||
|
||||
; CHECK-GCC-NOT: not_exported
|
||||
; CHECK-GCC: -export:f1
|
||||
; CHECK-GCC-SAME: -export:f2
|
||||
; CHECK-GCC-SAME: -export:stdfun@0
|
||||
; CHECK-GCC-SAME: -export:@fastfun@0
|
||||
; CHECK-GCC-SAME: -export:thisfun
|
||||
; CHECK-GCC-SAME: -export:lnk1
|
||||
; CHECK-GCC-SAME: -export:lnk2
|
||||
; CHECK-GCC-SAME: -export:weak1
|
||||
; CHECK-GCC-SAME: -export:Var1,data
|
||||
; CHECK-GCC-SAME: -export:Var2,data
|
||||
; CHECK-GCC-SAME: -export:Var3,data
|
||||
; CHECK-GCC-SAME: -export:WeakVar1,data
|
||||
; CHECK-GCC-SAME: -export:WeakVar2,data
|
||||
; CHECK-GCC-SAME: -export:alias
|
||||
; CHECK-GCC-SAME: -export:alias2
|
||||
; CHECK-GCC-SAME: -export:alias3
|
||||
; CHECK-GCC-SAME: -export:weak_alias"
|
||||
; CHECK-GCC-NOT: not_exported
|
||||
|
@ -224,19 +224,21 @@ lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
|
||||
}
|
||||
|
||||
unsigned int lto_module_get_num_deplibs(lto_module_t mod) {
|
||||
return unwrap(mod)->getDependentLibraryCount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) {
|
||||
return unwrap(mod)->getDependentLibrary(index);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int lto_module_get_num_linkeropts(lto_module_t mod) {
|
||||
return unwrap(mod)->getLinkerOptCount();
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) {
|
||||
return unwrap(mod)->getLinkerOpt(index);
|
||||
if (index != 0)
|
||||
return nullptr;
|
||||
return unwrap(mod)->getLinkerOpts();
|
||||
}
|
||||
|
||||
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
|
||||
|
Loading…
Reference in New Issue
Block a user