mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00: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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241010 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b370959788
commit
a6367d9136
@ -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.
|
* Returns the number of dependent libraries in the object module.
|
||||||
*
|
*
|
||||||
|
* Deprecated. Now returns an empty list.
|
||||||
|
*
|
||||||
* \since LTO_API_VERSION=8
|
* \since LTO_API_VERSION=8
|
||||||
*/
|
*/
|
||||||
extern unsigned int
|
extern unsigned int
|
||||||
@ -291,6 +293,8 @@ lto_module_get_num_deplibs(lto_module_t mod);
|
|||||||
/**
|
/**
|
||||||
* Returns the ith dependent library in the module.
|
* Returns the ith dependent library in the module.
|
||||||
*
|
*
|
||||||
|
* Deprecated. Now always returns null.
|
||||||
|
*
|
||||||
* \since LTO_API_VERSION=8
|
* \since LTO_API_VERSION=8
|
||||||
*/
|
*/
|
||||||
extern const char*
|
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.
|
* 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
|
* \since LTO_API_VERSION=8
|
||||||
*/
|
*/
|
||||||
extern unsigned int
|
extern unsigned int
|
||||||
@ -309,6 +316,9 @@ lto_module_get_num_linkeropts(lto_module_t mod);
|
|||||||
/**
|
/**
|
||||||
* Returns the ith linker option in the module.
|
* 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
|
* \since LTO_API_VERSION=8
|
||||||
*/
|
*/
|
||||||
extern const char*
|
extern const char*
|
||||||
|
@ -90,10 +90,6 @@ public:
|
|||||||
~TargetLoweringObjectFileMachO() override {}
|
~TargetLoweringObjectFileMachO() override {}
|
||||||
TargetLoweringObjectFileMachO();
|
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.
|
/// Emit the module flags that specify the garbage collection information.
|
||||||
void emitModuleFlags(MCStreamer &Streamer,
|
void emitModuleFlags(MCStreamer &Streamer,
|
||||||
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||||
@ -150,10 +146,6 @@ public:
|
|||||||
MCSection *getSectionForJumpTable(const Function &F, Mangler &Mang,
|
MCSection *getSectionForJumpTable(const Function &F, Mangler &Mang,
|
||||||
const TargetMachine &TM) const override;
|
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
|
/// Emit Obj-C garbage collection and linker options. Only linker option
|
||||||
/// emission is implemented for COFF.
|
/// emission is implemented for COFF.
|
||||||
void emitModuleFlags(MCStreamer &Streamer,
|
void emitModuleFlags(MCStreamer &Streamer,
|
||||||
@ -164,6 +156,9 @@ public:
|
|||||||
const MCSymbol *KeySym) const override;
|
const MCSymbol *KeySym) const override;
|
||||||
MCSection *getStaticDtorSection(unsigned Priority,
|
MCSection *getStaticDtorSection(unsigned Priority,
|
||||||
const MCSymbol *KeySym) const override;
|
const MCSymbol *KeySym) const override;
|
||||||
|
|
||||||
|
void emitLinkerFlagsForGlobal(raw_ostream &OS, const GlobalValue *GV,
|
||||||
|
const Mangler &Mang) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@ -47,12 +47,11 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<LLVMContext> OwnedContext;
|
std::unique_ptr<LLVMContext> OwnedContext;
|
||||||
|
|
||||||
|
std::string LinkerOpts;
|
||||||
|
|
||||||
std::unique_ptr<object::IRObjectFile> IRFile;
|
std::unique_ptr<object::IRObjectFile> IRFile;
|
||||||
std::unique_ptr<TargetMachine> _target;
|
std::unique_ptr<TargetMachine> _target;
|
||||||
StringSet<> _linkeropt_strings;
|
std::vector<NameAndAttributes> _symbols;
|
||||||
std::vector<const char *> _deplibs;
|
|
||||||
std::vector<const char *> _linkeropts;
|
|
||||||
std::vector<NameAndAttributes> _symbols;
|
|
||||||
|
|
||||||
// _defines and _undefines only needed to disambiguate tentative definitions
|
// _defines and _undefines only needed to disambiguate tentative definitions
|
||||||
StringSet<> _defines;
|
StringSet<> _defines;
|
||||||
@ -149,28 +148,8 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of dependent libraries
|
const char *getLinkerOpts() {
|
||||||
uint32_t getDependentLibraryCount() {
|
return LinkerOpts.c_str();
|
||||||
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 std::vector<const char*> &getAsmUndefinedRefs() {
|
const std::vector<const char*> &getAsmUndefinedRefs() {
|
||||||
|
@ -64,12 +64,6 @@ public:
|
|||||||
const TargetMachine &TM,
|
const TargetMachine &TM,
|
||||||
const MCSymbol *Sym) const;
|
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.
|
/// Emit the module flags that the platform cares about.
|
||||||
virtual void emitModuleFlags(MCStreamer &Streamer,
|
virtual void emitModuleFlags(MCStreamer &Streamer,
|
||||||
ArrayRef<Module::ModuleFlagEntry> Flags,
|
ArrayRef<Module::ModuleFlagEntry> Flags,
|
||||||
@ -188,6 +182,9 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void emitLinkerFlagsForGlobal(raw_ostream &OS, const GlobalValue *GV,
|
||||||
|
const Mangler &Mang) const {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual MCSection *SelectSectionForGlobal(const GlobalValue *GV,
|
virtual MCSection *SelectSectionForGlobal(const GlobalValue *GV,
|
||||||
SectionKind Kind, Mangler &Mang,
|
SectionKind Kind, Mangler &Mang,
|
||||||
|
@ -440,16 +440,6 @@ TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO()
|
|||||||
SupportIndirectSymViaGOTPCRel = true;
|
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.
|
/// emitModuleFlags - Perform code emission for module flags.
|
||||||
void TargetLoweringObjectFileMachO::
|
void TargetLoweringObjectFileMachO::
|
||||||
emitModuleFlags(MCStreamer &Streamer,
|
emitModuleFlags(MCStreamer &Streamer,
|
||||||
@ -990,14 +980,6 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
|
|||||||
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
|
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::
|
void TargetLoweringObjectFileCOFF::
|
||||||
emitModuleFlags(MCStreamer &Streamer,
|
emitModuleFlags(MCStreamer &Streamer,
|
||||||
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||||
@ -1045,3 +1027,36 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
|
|||||||
return getContext().getAssociativeCOFFSection(
|
return getContext().getAssociativeCOFFSection(
|
||||||
cast<MCSectionCOFF>(StaticDtorSection), KeySym);
|
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/Constants.h"
|
||||||
#include "llvm/IR/DiagnosticPrinter.h"
|
#include "llvm/IR/DiagnosticPrinter.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
|
#include "llvm/IR/Mangler.h"
|
||||||
#include "llvm/IR/Metadata.h"
|
#include "llvm/IR/Metadata.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
@ -642,6 +643,8 @@ bool LTOModule::parseSymbols(std::string &errMsg) {
|
|||||||
|
|
||||||
/// parseMetadata - Parse metadata from the module
|
/// parseMetadata - Parse metadata from the module
|
||||||
void LTOModule::parseMetadata() {
|
void LTOModule::parseMetadata() {
|
||||||
|
raw_string_ostream OS(LinkerOpts);
|
||||||
|
|
||||||
// Linker Options
|
// Linker Options
|
||||||
if (Metadata *Val = getModule().getModuleFlag("Linker Options")) {
|
if (Metadata *Val = getModule().getModuleFlag("Linker Options")) {
|
||||||
MDNode *LinkerOptions = cast<MDNode>(Val);
|
MDNode *LinkerOptions = cast<MDNode>(Val);
|
||||||
@ -649,20 +652,19 @@ void LTOModule::parseMetadata() {
|
|||||||
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
|
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
|
||||||
for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
|
for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
|
||||||
MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
|
MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
|
||||||
// FIXME: Make StringSet::insert match Self-Associative Container
|
OS << " " << MDOption->getString();
|
||||||
// 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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
Mangler Mang;
|
||||||
|
for (const NameAndAttributes &Sym : _symbols) {
|
||||||
|
if (!Sym.symbol)
|
||||||
|
continue;
|
||||||
|
_target->getObjFileLowering()->emitLinkerFlagsForGlobal(OS, Sym.symbol,
|
||||||
|
Mang);
|
||||||
|
}
|
||||||
|
|
||||||
// Add other interesting metadata here.
|
// Add other interesting metadata here.
|
||||||
}
|
}
|
||||||
|
@ -581,34 +581,6 @@ MCSymbol *X86AsmPrinter::GetCPISymbol(unsigned CPID) const {
|
|||||||
return AsmPrinter::GetCPISymbol(CPID);
|
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) {
|
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||||
const Triple &TT = TM.getTargetTriple();
|
const Triple &TT = TM.getTargetTriple();
|
||||||
|
|
||||||
@ -692,38 +664,25 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (TT.isOSBinFormatCOFF()) {
|
if (TT.isOSBinFormatCOFF()) {
|
||||||
// Necessary for dllexport support
|
const TargetLoweringObjectFileCOFF &TLOFCOFF =
|
||||||
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 =
|
|
||||||
static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
|
static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
|
||||||
|
|
||||||
OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection());
|
std::string Flags;
|
||||||
|
raw_string_ostream FlagsOS(Flags);
|
||||||
|
|
||||||
for (auto & Symbol : DLLExportedGlobals)
|
for (const auto &Function : M)
|
||||||
GenerateExportDirective(Symbol, /*IsData=*/true);
|
TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Function, *Mang);
|
||||||
for (auto & Symbol : DLLExportedFns)
|
for (const auto &Global : M.globals())
|
||||||
GenerateExportDirective(Symbol, /*IsData=*/false);
|
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();
|
SM.serializeToStackMapSection();
|
||||||
|
@ -30,8 +30,6 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
|
|||||||
StackMaps SM;
|
StackMaps SM;
|
||||||
FaultMaps FM;
|
FaultMaps FM;
|
||||||
|
|
||||||
void GenerateExportDirective(const MCSymbol *Sym, bool IsData);
|
|
||||||
|
|
||||||
// This utility class tracks the length of a stackmap instruction's 'shadow'.
|
// This utility class tracks the length of a stackmap instruction's 'shadow'.
|
||||||
// It is used by the X86AsmPrinter to ensure that the stackmap shadow
|
// It is used by the X86AsmPrinter to ensure that the stackmap shadow
|
||||||
// invariants (i.e. no other stackmaps, patchpoints, or control flow within
|
// 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 ()*)
|
@blob_alias = dllexport alias bitcast ([6 x i8]* @blob to i32 ()*)
|
||||||
|
|
||||||
; CHECK: .section .drectve
|
; CHECK: .section .drectve
|
||||||
; WIN32: " /EXPORT:Var1,DATA"
|
; WIN32: /EXPORT:f1
|
||||||
; WIN32: " /EXPORT:Var2,DATA"
|
; WIN32-SAME: /EXPORT:f2
|
||||||
; WIN32: " /EXPORT:Var3,DATA"
|
; WIN32-SAME: /EXPORT:lnk1
|
||||||
; WIN32: " /EXPORT:WeakVar1,DATA"
|
; WIN32-SAME: /EXPORT:lnk2
|
||||||
; WIN32: " /EXPORT:WeakVar2,DATA"
|
; WIN32-SAME: /EXPORT:weak1
|
||||||
; WIN32: " /EXPORT:f1"
|
; WIN32-SAME: /EXPORT:Var1,DATA
|
||||||
; WIN32: " /EXPORT:f2"
|
; WIN32-SAME: /EXPORT:Var2,DATA
|
||||||
; WIN32: " /EXPORT:lnk1"
|
; WIN32-SAME: /EXPORT:Var3,DATA
|
||||||
; WIN32: " /EXPORT:lnk2"
|
; WIN32-SAME: /EXPORT:WeakVar1,DATA
|
||||||
; WIN32: " /EXPORT:weak1"
|
; WIN32-SAME: /EXPORT:WeakVar2,DATA
|
||||||
; WIN32: " /EXPORT:alias"
|
; WIN32-SAME: /EXPORT:alias
|
||||||
; WIN32: " /EXPORT:alias2"
|
; WIN32-SAME: /EXPORT:alias2
|
||||||
; WIN32: " /EXPORT:alias3"
|
; WIN32-SAME: /EXPORT:alias3
|
||||||
; WIN32: " /EXPORT:weak_alias"
|
; WIN32-SAME: /EXPORT:weak_alias
|
||||||
; WIN32: " /EXPORT:blob_alias"
|
; WIN32-SAME: /EXPORT:blob_alias
|
||||||
; MINGW: " -export:Var1,data"
|
; MINGW: -export:f1
|
||||||
; MINGW: " -export:Var2,data"
|
; MINGW-SAME: -export:f2
|
||||||
; MINGW: " -export:Var3,data"
|
; MINGW-SAME: -export:lnk1
|
||||||
; MINGW: " -export:WeakVar1,data"
|
; MINGW-SAME: -export:lnk2
|
||||||
; MINGW: " -export:WeakVar2,data"
|
; MINGW-SAME: -export:weak1
|
||||||
; MINGW: " -export:f1"
|
; MINGW-SAME: -export:Var1,data
|
||||||
; MINGW: " -export:f2"
|
; MINGW-SAME: -export:Var2,data
|
||||||
; MINGW: " -export:lnk1"
|
; MINGW-SAME: -export:Var3,data
|
||||||
; MINGW: " -export:lnk2"
|
; MINGW-SAME: -export:WeakVar1,data
|
||||||
; MINGW: " -export:weak1"
|
; MINGW-SAME: -export:WeakVar2,data
|
||||||
; MINGW: " -export:alias"
|
; MINGW-SAME: -export:alias
|
||||||
; MINGW: " -export:alias2"
|
; MINGW-SAME: -export:alias2
|
||||||
; MINGW: " -export:alias3"
|
; MINGW-SAME: -export:alias3
|
||||||
; MINGW: " -export:weak_alias"
|
; MINGW-SAME: -export:weak_alias
|
||||||
; MINGW: " -export:blob_alias"
|
; MINGW-SAME: -export:blob_alias"
|
||||||
|
@ -89,40 +89,41 @@ define weak_odr dllexport void @weak1() {
|
|||||||
@weak_alias = weak_odr dllexport alias void()* @f1
|
@weak_alias = weak_odr dllexport alias void()* @f1
|
||||||
|
|
||||||
; CHECK: .section .drectve
|
; 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-NOT: not_exported
|
||||||
; CHECK-CL: " /EXPORT:_stdfun@0"
|
; CHECK-CL: /EXPORT:_f1
|
||||||
; CHECK-CL: " /EXPORT:@fastfun@0"
|
; CHECK-CL-SAME: /EXPORT:_f2
|
||||||
; CHECK-CL: " /EXPORT:_thisfun"
|
; CHECK-CL-SAME: /EXPORT:_stdfun@0
|
||||||
; CHECK-CL: " /EXPORT:_lnk1"
|
; CHECK-CL-SAME: /EXPORT:@fastfun@0
|
||||||
; CHECK-CL: " /EXPORT:_lnk2"
|
; CHECK-CL-SAME: /EXPORT:_thisfun
|
||||||
; CHECK-CL: " /EXPORT:_weak1"
|
; CHECK-CL-SAME: /EXPORT:_lnk1
|
||||||
; CHECK-CL: " /EXPORT:_alias"
|
; CHECK-CL-SAME: /EXPORT:_lnk2
|
||||||
; CHECK-CL: " /EXPORT:_alias2"
|
; CHECK-CL-SAME: /EXPORT:_weak1
|
||||||
; CHECK-CL: " /EXPORT:_alias3"
|
; CHECK-CL-SAME: /EXPORT:_Var1,DATA
|
||||||
; CHECK-CL: " /EXPORT:_weak_alias"
|
; CHECK-CL-SAME: /EXPORT:_Var2,DATA
|
||||||
; CHECK-GCC: " -export:Var1,data"
|
; CHECK-CL-SAME: /EXPORT:_Var3,DATA
|
||||||
; CHECK-GCC: " -export:Var2,data"
|
; CHECK-CL-SAME: /EXPORT:_WeakVar1,DATA
|
||||||
; CHECK-GCC: " -export:Var3,data"
|
; CHECK-CL-SAME: /EXPORT:_WeakVar2,DATA
|
||||||
; CHECK-GCC: " -export:WeakVar1,data"
|
; CHECK-CL-SAME: /EXPORT:_alias
|
||||||
; CHECK-GCC: " -export:WeakVar2,data"
|
; CHECK-CL-SAME: /EXPORT:_alias2
|
||||||
; CHECK-GCC: " -export:f1"
|
; CHECK-CL-SAME: /EXPORT:_alias3
|
||||||
; CHECK-GCC: " -export:f2"
|
; CHECK-CL-SAME: /EXPORT:_weak_alias"
|
||||||
; CHECK-CL-NOT: not_exported
|
; CHECK-CL-NOT: not_exported
|
||||||
; CHECK-GCC: " -export:stdfun@0"
|
; CHECK-GCC-NOT: not_exported
|
||||||
; CHECK-GCC: " -export:@fastfun@0"
|
; CHECK-GCC: -export:f1
|
||||||
; CHECK-GCC: " -export:thisfun"
|
; CHECK-GCC-SAME: -export:f2
|
||||||
; CHECK-GCC: " -export:lnk1"
|
; CHECK-GCC-SAME: -export:stdfun@0
|
||||||
; CHECK-GCC: " -export:lnk2"
|
; CHECK-GCC-SAME: -export:@fastfun@0
|
||||||
; CHECK-GCC: " -export:weak1"
|
; CHECK-GCC-SAME: -export:thisfun
|
||||||
; CHECK-GCC: " -export:alias"
|
; CHECK-GCC-SAME: -export:lnk1
|
||||||
; CHECK-GCC: " -export:alias2"
|
; CHECK-GCC-SAME: -export:lnk2
|
||||||
; CHECK-GCC: " -export:alias3"
|
; CHECK-GCC-SAME: -export:weak1
|
||||||
; CHECK-GCC: " -export:weak_alias"
|
; 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) {
|
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) {
|
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) {
|
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) {
|
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,
|
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
|
||||||
|
Loading…
Reference in New Issue
Block a user