File: | lib/CodeGen/LLVMTargetMachine.cpp |
Warning: | line 502, column 5 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file implements the LLVMTargetMachine class. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/Analysis/Passes.h" | |||
15 | #include "llvm/CodeGen/AsmPrinter.h" | |||
16 | #include "llvm/CodeGen/BasicTTIImpl.h" | |||
17 | #include "llvm/CodeGen/MachineModuleInfo.h" | |||
18 | #include "llvm/CodeGen/Passes.h" | |||
19 | #include "llvm/CodeGen/TargetPassConfig.h" | |||
20 | #include "llvm/IR/LegacyPassManager.h" | |||
21 | #include "llvm/MC/MCAsmBackend.h" | |||
22 | #include "llvm/MC/MCAsmInfo.h" | |||
23 | #include "llvm/MC/MCCodeEmitter.h" | |||
24 | #include "llvm/MC/MCContext.h" | |||
25 | #include "llvm/MC/MCInstrInfo.h" | |||
26 | #include "llvm/MC/MCStreamer.h" | |||
27 | #include "llvm/MC/MCSubtargetInfo.h" | |||
28 | #include "llvm/Support/CommandLine.h" | |||
29 | #include "llvm/Support/ErrorHandling.h" | |||
30 | #include "llvm/Support/FormattedStream.h" | |||
31 | #include "llvm/Support/TargetRegistry.h" | |||
32 | #include "llvm/Target/TargetLoweringObjectFile.h" | |||
33 | #include "llvm/Target/TargetMachine.h" | |||
34 | #include "llvm/Target/TargetOptions.h" | |||
35 | using namespace llvm; | |||
36 | ||||
37 | static cl::opt<bool> EnableTrapUnreachable("trap-unreachable", | |||
38 | cl::Hidden, cl::ZeroOrMore, cl::init(false), | |||
39 | cl::desc("Enable generating trap for unreachable")); | |||
40 | ||||
41 | void LLVMTargetMachine::initAsmInfo() { | |||
42 | MRI = TheTarget.createMCRegInfo(getTargetTriple().str()); | |||
43 | MII = TheTarget.createMCInstrInfo(); | |||
44 | // FIXME: Having an MCSubtargetInfo on the target machine is a hack due | |||
45 | // to some backends having subtarget feature dependent module level | |||
46 | // code generation. This is similar to the hack in the AsmPrinter for | |||
47 | // module level assembly etc. | |||
48 | STI = TheTarget.createMCSubtargetInfo(getTargetTriple().str(), getTargetCPU(), | |||
49 | getTargetFeatureString()); | |||
50 | ||||
51 | MCAsmInfo *TmpAsmInfo = | |||
52 | TheTarget.createMCAsmInfo(*MRI, getTargetTriple().str()); | |||
53 | // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, | |||
54 | // and if the old one gets included then MCAsmInfo will be NULL and | |||
55 | // we'll crash later. | |||
56 | // Provide the user with a useful error message about what's wrong. | |||
57 | assert(TmpAsmInfo && "MCAsmInfo not initialized. "(static_cast <bool> (TmpAsmInfo && "MCAsmInfo not initialized. " "Make sure you include the correct TargetSelect.h" "and that InitializeAllTargetMCs() is being invoked!" ) ? void (0) : __assert_fail ("TmpAsmInfo && \"MCAsmInfo not initialized. \" \"Make sure you include the correct TargetSelect.h\" \"and that InitializeAllTargetMCs() is being invoked!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/lib/CodeGen/LLVMTargetMachine.cpp" , 59, __extension__ __PRETTY_FUNCTION__)) | |||
58 | "Make sure you include the correct TargetSelect.h"(static_cast <bool> (TmpAsmInfo && "MCAsmInfo not initialized. " "Make sure you include the correct TargetSelect.h" "and that InitializeAllTargetMCs() is being invoked!" ) ? void (0) : __assert_fail ("TmpAsmInfo && \"MCAsmInfo not initialized. \" \"Make sure you include the correct TargetSelect.h\" \"and that InitializeAllTargetMCs() is being invoked!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/lib/CodeGen/LLVMTargetMachine.cpp" , 59, __extension__ __PRETTY_FUNCTION__)) | |||
59 | "and that InitializeAllTargetMCs() is being invoked!")(static_cast <bool> (TmpAsmInfo && "MCAsmInfo not initialized. " "Make sure you include the correct TargetSelect.h" "and that InitializeAllTargetMCs() is being invoked!" ) ? void (0) : __assert_fail ("TmpAsmInfo && \"MCAsmInfo not initialized. \" \"Make sure you include the correct TargetSelect.h\" \"and that InitializeAllTargetMCs() is being invoked!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/lib/CodeGen/LLVMTargetMachine.cpp" , 59, __extension__ __PRETTY_FUNCTION__)); | |||
60 | ||||
61 | if (Options.DisableIntegratedAS) | |||
62 | TmpAsmInfo->setUseIntegratedAssembler(false); | |||
63 | ||||
64 | TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments); | |||
65 | ||||
66 | TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections); | |||
67 | ||||
68 | TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations); | |||
69 | ||||
70 | if (Options.ExceptionModel != ExceptionHandling::None) | |||
71 | TmpAsmInfo->setExceptionsType(Options.ExceptionModel); | |||
72 | ||||
73 | AsmInfo = TmpAsmInfo; | |||
74 | } | |||
75 | ||||
76 | LLVMTargetMachine::LLVMTargetMachine(const Target &T, | |||
77 | StringRef DataLayoutString, | |||
78 | const Triple &TT, StringRef CPU, | |||
79 | StringRef FS, const TargetOptions &Options, | |||
80 | Reloc::Model RM, CodeModel::Model CM, | |||
81 | CodeGenOpt::Level OL) | |||
82 | : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) { | |||
83 | this->RM = RM; | |||
84 | this->CMModel = CM; | |||
85 | this->OptLevel = OL; | |||
86 | ||||
87 | if (EnableTrapUnreachable) | |||
88 | this->Options.TrapUnreachable = true; | |||
89 | } | |||
90 | ||||
91 | TargetTransformInfo | |||
92 | LLVMTargetMachine::getTargetTransformInfo(const Function &F) { | |||
93 | return TargetTransformInfo(BasicTTIImpl(this, F)); | |||
94 | } | |||
95 | ||||
96 | /// addPassesToX helper drives creation and initialization of TargetPassConfig. | |||
97 | static MCContext * | |||
98 | addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, | |||
99 | bool DisableVerify, bool &WillCompleteCodeGenPipeline, | |||
100 | raw_pwrite_stream &Out, MachineModuleInfo *MMI) { | |||
101 | // Targets may override createPassConfig to provide a target-specific | |||
102 | // subclass. | |||
103 | TargetPassConfig *PassConfig = TM->createPassConfig(PM); | |||
104 | // Set PassConfig options provided by TargetMachine. | |||
105 | PassConfig->setDisableVerify(DisableVerify); | |||
106 | WillCompleteCodeGenPipeline = PassConfig->willCompleteCodeGenPipeline(); | |||
107 | PM.add(PassConfig); | |||
108 | if (!MMI) | |||
109 | MMI = new MachineModuleInfo(TM); | |||
110 | PM.add(MMI); | |||
111 | ||||
112 | if (PassConfig->addISelPasses()) | |||
113 | return nullptr; | |||
114 | PassConfig->addMachinePasses(); | |||
115 | PassConfig->setInitialized(); | |||
116 | if (!WillCompleteCodeGenPipeline) | |||
117 | PM.add(createPrintMIRPass(Out)); | |||
118 | ||||
119 | return &MMI->getContext(); | |||
120 | } | |||
121 | ||||
122 | bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, | |||
123 | raw_pwrite_stream &Out, CodeGenFileType FileType, | |||
124 | MCContext &Context) { | |||
125 | if (Options.MCOptions.MCSaveTempLabels) | |||
126 | Context.setAllowTemporaryLabels(false); | |||
127 | ||||
128 | const MCSubtargetInfo &STI = *getMCSubtargetInfo(); | |||
129 | const MCAsmInfo &MAI = *getMCAsmInfo(); | |||
130 | const MCRegisterInfo &MRI = *getMCRegisterInfo(); | |||
131 | const MCInstrInfo &MII = *getMCInstrInfo(); | |||
132 | ||||
133 | std::unique_ptr<MCStreamer> AsmStreamer; | |||
134 | ||||
135 | switch (FileType) { | |||
136 | case CGFT_AssemblyFile: { | |||
137 | MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter( | |||
138 | getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI); | |||
139 | ||||
140 | // Create a code emitter if asked to show the encoding. | |||
141 | MCCodeEmitter *MCE = nullptr; | |||
142 | if (Options.MCOptions.ShowMCEncoding) | |||
143 | MCE = getTarget().createMCCodeEmitter(MII, MRI, Context); | |||
144 | ||||
145 | MCAsmBackend *MAB = | |||
146 | getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); | |||
147 | auto FOut = llvm::make_unique<formatted_raw_ostream>(Out); | |||
148 | MCStreamer *S = getTarget().createAsmStreamer( | |||
149 | Context, std::move(FOut), Options.MCOptions.AsmVerbose, | |||
150 | Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, | |||
151 | Options.MCOptions.ShowMCInst); | |||
152 | AsmStreamer.reset(S); | |||
153 | break; | |||
154 | } | |||
155 | case CGFT_ObjectFile: { | |||
156 | // Create the code emitter for the target if it exists. If not, .o file | |||
157 | // emission fails. | |||
158 | MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context); | |||
159 | MCAsmBackend *MAB = | |||
160 | getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); | |||
161 | if (!MCE || !MAB) | |||
162 | return true; | |||
163 | ||||
164 | // Don't waste memory on names of temp labels. | |||
165 | Context.setUseNamesOnTempLabels(false); | |||
166 | ||||
167 | Triple T(getTargetTriple().str()); | |||
168 | AsmStreamer.reset(getTarget().createMCObjectStreamer( | |||
169 | T, Context, std::unique_ptr<MCAsmBackend>(MAB), Out, | |||
170 | std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, | |||
171 | Options.MCOptions.MCIncrementalLinkerCompatible, | |||
172 | /*DWARFMustBeAtTheEnd*/ true)); | |||
173 | break; | |||
174 | } | |||
175 | case CGFT_Null: | |||
176 | // The Null output is intended for use for performance analysis and testing, | |||
177 | // not real users. | |||
178 | AsmStreamer.reset(getTarget().createNullStreamer(Context)); | |||
179 | break; | |||
180 | } | |||
181 | ||||
182 | // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. | |||
183 | FunctionPass *Printer = | |||
184 | getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); | |||
185 | if (!Printer) | |||
186 | return true; | |||
187 | ||||
188 | PM.add(Printer); | |||
189 | return false; | |||
190 | } | |||
191 | ||||
192 | bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, | |||
193 | raw_pwrite_stream &Out, | |||
194 | CodeGenFileType FileType, | |||
195 | bool DisableVerify, | |||
196 | MachineModuleInfo *MMI) { | |||
197 | // Add common CodeGen passes. | |||
198 | bool WillCompleteCodeGenPipeline = true; | |||
199 | MCContext *Context = addPassesToGenerateCode( | |||
200 | this, PM, DisableVerify, WillCompleteCodeGenPipeline, Out, MMI); | |||
201 | if (!Context) | |||
| ||||
202 | return true; | |||
203 | ||||
204 | if (WillCompleteCodeGenPipeline && addAsmPrinter(PM, Out, FileType, *Context)) | |||
205 | return true; | |||
206 | ||||
207 | PM.add(createFreeMachineFunctionPass()); | |||
208 | return false; | |||
209 | } | |||
210 | ||||
211 | /// addPassesToEmitMC - Add passes to the specified pass manager to get | |||
212 | /// machine code emitted with the MCJIT. This method returns true if machine | |||
213 | /// code is not supported. It fills the MCContext Ctx pointer which can be | |||
214 | /// used to build custom MCStreamer. | |||
215 | /// | |||
216 | bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, | |||
217 | raw_pwrite_stream &Out, | |||
218 | bool DisableVerify) { | |||
219 | // Add common CodeGen passes. | |||
220 | bool WillCompleteCodeGenPipeline = true; | |||
221 | Ctx = addPassesToGenerateCode(this, PM, DisableVerify, | |||
222 | WillCompleteCodeGenPipeline, Out, | |||
223 | /*MachineModuleInfo*/ nullptr); | |||
224 | if (!Ctx) | |||
225 | return true; | |||
226 | assert(WillCompleteCodeGenPipeline && "CodeGen pipeline has been altered")(static_cast <bool> (WillCompleteCodeGenPipeline && "CodeGen pipeline has been altered") ? void (0) : __assert_fail ("WillCompleteCodeGenPipeline && \"CodeGen pipeline has been altered\"" , "/build/llvm-toolchain-snapshot-7~svn329677/lib/CodeGen/LLVMTargetMachine.cpp" , 226, __extension__ __PRETTY_FUNCTION__)); | |||
227 | ||||
228 | if (Options.MCOptions.MCSaveTempLabels) | |||
229 | Ctx->setAllowTemporaryLabels(false); | |||
230 | ||||
231 | // Create the code emitter for the target if it exists. If not, .o file | |||
232 | // emission fails. | |||
233 | const MCSubtargetInfo &STI = *getMCSubtargetInfo(); | |||
234 | const MCRegisterInfo &MRI = *getMCRegisterInfo(); | |||
235 | MCCodeEmitter *MCE = | |||
236 | getTarget().createMCCodeEmitter(*getMCInstrInfo(), MRI, *Ctx); | |||
237 | MCAsmBackend *MAB = | |||
238 | getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); | |||
239 | if (!MCE || !MAB) | |||
240 | return true; | |||
241 | ||||
242 | const Triple &T = getTargetTriple(); | |||
243 | std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer( | |||
244 | T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), Out, | |||
245 | std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, | |||
246 | Options.MCOptions.MCIncrementalLinkerCompatible, | |||
247 | /*DWARFMustBeAtTheEnd*/ true)); | |||
248 | ||||
249 | // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. | |||
250 | FunctionPass *Printer = | |||
251 | getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); | |||
252 | if (!Printer) | |||
253 | return true; | |||
254 | ||||
255 | PM.add(Printer); | |||
256 | PM.add(createFreeMachineFunctionPass()); | |||
257 | ||||
258 | return false; // success! | |||
259 | } |
1 | //===- Support/TargetRegistry.h - Target Registration -----------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file exposes the TargetRegistry interface, which tools can use to access | |||
11 | // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.) | |||
12 | // which have been registered. | |||
13 | // | |||
14 | // Target specific class implementations should register themselves using the | |||
15 | // appropriate TargetRegistry interfaces. | |||
16 | // | |||
17 | //===----------------------------------------------------------------------===// | |||
18 | ||||
19 | #ifndef LLVM_SUPPORT_TARGETREGISTRY_H | |||
20 | #define LLVM_SUPPORT_TARGETREGISTRY_H | |||
21 | ||||
22 | #include "llvm-c/DisassemblerTypes.h" | |||
23 | #include "llvm/ADT/Optional.h" | |||
24 | #include "llvm/ADT/StringRef.h" | |||
25 | #include "llvm/ADT/Triple.h" | |||
26 | #include "llvm/ADT/iterator_range.h" | |||
27 | #include "llvm/Support/CodeGen.h" | |||
28 | #include "llvm/Support/ErrorHandling.h" | |||
29 | #include "llvm/Support/FormattedStream.h" | |||
30 | #include <algorithm> | |||
31 | #include <cassert> | |||
32 | #include <cstddef> | |||
33 | #include <iterator> | |||
34 | #include <memory> | |||
35 | #include <string> | |||
36 | ||||
37 | namespace llvm { | |||
38 | ||||
39 | class AsmPrinter; | |||
40 | class MCAsmBackend; | |||
41 | class MCAsmInfo; | |||
42 | class MCAsmParser; | |||
43 | class MCCodeEmitter; | |||
44 | class MCContext; | |||
45 | class MCDisassembler; | |||
46 | class MCInstPrinter; | |||
47 | class MCInstrAnalysis; | |||
48 | class MCInstrInfo; | |||
49 | class MCRegisterInfo; | |||
50 | class MCRelocationInfo; | |||
51 | class MCStreamer; | |||
52 | class MCSubtargetInfo; | |||
53 | class MCSymbolizer; | |||
54 | class MCTargetAsmParser; | |||
55 | class MCTargetOptions; | |||
56 | class MCTargetStreamer; | |||
57 | class raw_ostream; | |||
58 | class raw_pwrite_stream; | |||
59 | class TargetMachine; | |||
60 | class TargetOptions; | |||
61 | ||||
62 | MCStreamer *createNullStreamer(MCContext &Ctx); | |||
63 | MCStreamer *createAsmStreamer(MCContext &Ctx, | |||
64 | std::unique_ptr<formatted_raw_ostream> OS, | |||
65 | bool isVerboseAsm, bool useDwarfDirectory, | |||
66 | MCInstPrinter *InstPrint, MCCodeEmitter *CE, | |||
67 | MCAsmBackend *TAB, bool ShowInst); | |||
68 | ||||
69 | /// Takes ownership of \p TAB and \p CE. | |||
70 | MCStreamer *createELFStreamer(MCContext &Ctx, | |||
71 | std::unique_ptr<MCAsmBackend> &&TAB, | |||
72 | raw_pwrite_stream &OS, | |||
73 | std::unique_ptr<MCCodeEmitter> &&CE, | |||
74 | bool RelaxAll); | |||
75 | MCStreamer *createMachOStreamer(MCContext &Ctx, | |||
76 | std::unique_ptr<MCAsmBackend> &&TAB, | |||
77 | raw_pwrite_stream &OS, | |||
78 | std::unique_ptr<MCCodeEmitter> &&CE, | |||
79 | bool RelaxAll, bool DWARFMustBeAtTheEnd, | |||
80 | bool LabelSections = false); | |||
81 | MCStreamer *createWasmStreamer(MCContext &Ctx, | |||
82 | std::unique_ptr<MCAsmBackend> &&TAB, | |||
83 | raw_pwrite_stream &OS, | |||
84 | std::unique_ptr<MCCodeEmitter> &&CE, | |||
85 | bool RelaxAll); | |||
86 | ||||
87 | MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx); | |||
88 | ||||
89 | MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, | |||
90 | LLVMSymbolLookupCallback SymbolLookUp, | |||
91 | void *DisInfo, MCContext *Ctx, | |||
92 | std::unique_ptr<MCRelocationInfo> &&RelInfo); | |||
93 | ||||
94 | /// Target - Wrapper for Target specific information. | |||
95 | /// | |||
96 | /// For registration purposes, this is a POD type so that targets can be | |||
97 | /// registered without the use of static constructors. | |||
98 | /// | |||
99 | /// Targets should implement a single global instance of this class (which | |||
100 | /// will be zero initialized), and pass that instance to the TargetRegistry as | |||
101 | /// part of their initialization. | |||
102 | class Target { | |||
103 | public: | |||
104 | friend struct TargetRegistry; | |||
105 | ||||
106 | using ArchMatchFnTy = bool (*)(Triple::ArchType Arch); | |||
107 | ||||
108 | using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI, | |||
109 | const Triple &TT); | |||
110 | using MCInstrInfoCtorFnTy = MCInstrInfo *(*)(); | |||
111 | using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info); | |||
112 | using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT); | |||
113 | using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT, | |||
114 | StringRef CPU, | |||
115 | StringRef Features); | |||
116 | using TargetMachineCtorTy = TargetMachine | |||
117 | *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features, | |||
118 | const TargetOptions &Options, Optional<Reloc::Model> RM, | |||
119 | Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT); | |||
120 | // If it weren't for layering issues (this header is in llvm/Support, but | |||
121 | // depends on MC?) this should take the Streamer by value rather than rvalue | |||
122 | // reference. | |||
123 | using AsmPrinterCtorTy = AsmPrinter *(*)( | |||
124 | TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer); | |||
125 | using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T, | |||
126 | const MCSubtargetInfo &STI, | |||
127 | const MCRegisterInfo &MRI, | |||
128 | const MCTargetOptions &Options); | |||
129 | using MCAsmParserCtorTy = MCTargetAsmParser *(*)( | |||
130 | const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII, | |||
131 | const MCTargetOptions &Options); | |||
132 | using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T, | |||
133 | const MCSubtargetInfo &STI, | |||
134 | MCContext &Ctx); | |||
135 | using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T, | |||
136 | unsigned SyntaxVariant, | |||
137 | const MCAsmInfo &MAI, | |||
138 | const MCInstrInfo &MII, | |||
139 | const MCRegisterInfo &MRI); | |||
140 | using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II, | |||
141 | const MCRegisterInfo &MRI, | |||
142 | MCContext &Ctx); | |||
143 | using ELFStreamerCtorTy = | |||
144 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, | |||
145 | std::unique_ptr<MCAsmBackend> &&TAB, | |||
146 | raw_pwrite_stream &OS, | |||
147 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); | |||
148 | using MachOStreamerCtorTy = | |||
149 | MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, | |||
150 | raw_pwrite_stream &OS, | |||
151 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, | |||
152 | bool DWARFMustBeAtTheEnd); | |||
153 | using COFFStreamerCtorTy = | |||
154 | MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, | |||
155 | raw_pwrite_stream &OS, | |||
156 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, | |||
157 | bool IncrementalLinkerCompatible); | |||
158 | using WasmStreamerCtorTy = | |||
159 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, | |||
160 | std::unique_ptr<MCAsmBackend> &&TAB, | |||
161 | raw_pwrite_stream &OS, | |||
162 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); | |||
163 | using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S); | |||
164 | using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)( | |||
165 | MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, | |||
166 | bool IsVerboseAsm); | |||
167 | using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)( | |||
168 | MCStreamer &S, const MCSubtargetInfo &STI); | |||
169 | using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT, | |||
170 | MCContext &Ctx); | |||
171 | using MCSymbolizerCtorTy = MCSymbolizer *(*)( | |||
172 | const Triple &TT, LLVMOpInfoCallback GetOpInfo, | |||
173 | LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, | |||
174 | std::unique_ptr<MCRelocationInfo> &&RelInfo); | |||
175 | ||||
176 | private: | |||
177 | /// Next - The next registered target in the linked list, maintained by the | |||
178 | /// TargetRegistry. | |||
179 | Target *Next; | |||
180 | ||||
181 | /// The target function for checking if an architecture is supported. | |||
182 | ArchMatchFnTy ArchMatchFn; | |||
183 | ||||
184 | /// Name - The target name. | |||
185 | const char *Name; | |||
186 | ||||
187 | /// ShortDesc - A short description of the target. | |||
188 | const char *ShortDesc; | |||
189 | ||||
190 | /// BackendName - The name of the backend implementation. This must match the | |||
191 | /// name of the 'def X : Target ...' in TableGen. | |||
192 | const char *BackendName; | |||
193 | ||||
194 | /// HasJIT - Whether this target supports the JIT. | |||
195 | bool HasJIT; | |||
196 | ||||
197 | /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if | |||
198 | /// registered. | |||
199 | MCAsmInfoCtorFnTy MCAsmInfoCtorFn; | |||
200 | ||||
201 | /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, | |||
202 | /// if registered. | |||
203 | MCInstrInfoCtorFnTy MCInstrInfoCtorFn; | |||
204 | ||||
205 | /// MCInstrAnalysisCtorFn - Constructor function for this target's | |||
206 | /// MCInstrAnalysis, if registered. | |||
207 | MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn; | |||
208 | ||||
209 | /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, | |||
210 | /// if registered. | |||
211 | MCRegInfoCtorFnTy MCRegInfoCtorFn; | |||
212 | ||||
213 | /// MCSubtargetInfoCtorFn - Constructor function for this target's | |||
214 | /// MCSubtargetInfo, if registered. | |||
215 | MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; | |||
216 | ||||
217 | /// TargetMachineCtorFn - Construction function for this target's | |||
218 | /// TargetMachine, if registered. | |||
219 | TargetMachineCtorTy TargetMachineCtorFn; | |||
220 | ||||
221 | /// MCAsmBackendCtorFn - Construction function for this target's | |||
222 | /// MCAsmBackend, if registered. | |||
223 | MCAsmBackendCtorTy MCAsmBackendCtorFn; | |||
224 | ||||
225 | /// MCAsmParserCtorFn - Construction function for this target's | |||
226 | /// MCTargetAsmParser, if registered. | |||
227 | MCAsmParserCtorTy MCAsmParserCtorFn; | |||
228 | ||||
229 | /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, | |||
230 | /// if registered. | |||
231 | AsmPrinterCtorTy AsmPrinterCtorFn; | |||
232 | ||||
233 | /// MCDisassemblerCtorFn - Construction function for this target's | |||
234 | /// MCDisassembler, if registered. | |||
235 | MCDisassemblerCtorTy MCDisassemblerCtorFn; | |||
236 | ||||
237 | /// MCInstPrinterCtorFn - Construction function for this target's | |||
238 | /// MCInstPrinter, if registered. | |||
239 | MCInstPrinterCtorTy MCInstPrinterCtorFn; | |||
240 | ||||
241 | /// MCCodeEmitterCtorFn - Construction function for this target's | |||
242 | /// CodeEmitter, if registered. | |||
243 | MCCodeEmitterCtorTy MCCodeEmitterCtorFn; | |||
244 | ||||
245 | // Construction functions for the various object formats, if registered. | |||
246 | COFFStreamerCtorTy COFFStreamerCtorFn = nullptr; | |||
247 | MachOStreamerCtorTy MachOStreamerCtorFn = nullptr; | |||
248 | ELFStreamerCtorTy ELFStreamerCtorFn = nullptr; | |||
249 | WasmStreamerCtorTy WasmStreamerCtorFn = nullptr; | |||
250 | ||||
251 | /// Construction function for this target's null TargetStreamer, if | |||
252 | /// registered (default = nullptr). | |||
253 | NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr; | |||
254 | ||||
255 | /// Construction function for this target's asm TargetStreamer, if | |||
256 | /// registered (default = nullptr). | |||
257 | AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr; | |||
258 | ||||
259 | /// Construction function for this target's obj TargetStreamer, if | |||
260 | /// registered (default = nullptr). | |||
261 | ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr; | |||
262 | ||||
263 | /// MCRelocationInfoCtorFn - Construction function for this target's | |||
264 | /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo) | |||
265 | MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr; | |||
266 | ||||
267 | /// MCSymbolizerCtorFn - Construction function for this target's | |||
268 | /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer) | |||
269 | MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr; | |||
270 | ||||
271 | public: | |||
272 | Target() = default; | |||
273 | ||||
274 | /// @name Target Information | |||
275 | /// @{ | |||
276 | ||||
277 | // getNext - Return the next registered target. | |||
278 | const Target *getNext() const { return Next; } | |||
279 | ||||
280 | /// getName - Get the target name. | |||
281 | const char *getName() const { return Name; } | |||
282 | ||||
283 | /// getShortDescription - Get a short description of the target. | |||
284 | const char *getShortDescription() const { return ShortDesc; } | |||
285 | ||||
286 | /// getBackendName - Get the backend name. | |||
287 | const char *getBackendName() const { return BackendName; } | |||
288 | ||||
289 | /// @} | |||
290 | /// @name Feature Predicates | |||
291 | /// @{ | |||
292 | ||||
293 | /// hasJIT - Check if this targets supports the just-in-time compilation. | |||
294 | bool hasJIT() const { return HasJIT; } | |||
295 | ||||
296 | /// hasTargetMachine - Check if this target supports code generation. | |||
297 | bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; } | |||
298 | ||||
299 | /// hasMCAsmBackend - Check if this target supports .o generation. | |||
300 | bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; } | |||
301 | ||||
302 | /// hasMCAsmParser - Check if this target supports assembly parsing. | |||
303 | bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; } | |||
304 | ||||
305 | /// @} | |||
306 | /// @name Feature Constructors | |||
307 | /// @{ | |||
308 | ||||
309 | /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified | |||
310 | /// target triple. | |||
311 | /// | |||
312 | /// \param TheTriple This argument is used to determine the target machine | |||
313 | /// feature set; it should always be provided. Generally this should be | |||
314 | /// either the target triple from the module, or the target triple of the | |||
315 | /// host if that does not exist. | |||
316 | MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, | |||
317 | StringRef TheTriple) const { | |||
318 | if (!MCAsmInfoCtorFn) | |||
319 | return nullptr; | |||
320 | return MCAsmInfoCtorFn(MRI, Triple(TheTriple)); | |||
321 | } | |||
322 | ||||
323 | /// createMCInstrInfo - Create a MCInstrInfo implementation. | |||
324 | /// | |||
325 | MCInstrInfo *createMCInstrInfo() const { | |||
326 | if (!MCInstrInfoCtorFn) | |||
327 | return nullptr; | |||
328 | return MCInstrInfoCtorFn(); | |||
329 | } | |||
330 | ||||
331 | /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation. | |||
332 | /// | |||
333 | MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const { | |||
334 | if (!MCInstrAnalysisCtorFn) | |||
335 | return nullptr; | |||
336 | return MCInstrAnalysisCtorFn(Info); | |||
337 | } | |||
338 | ||||
339 | /// createMCRegInfo - Create a MCRegisterInfo implementation. | |||
340 | /// | |||
341 | MCRegisterInfo *createMCRegInfo(StringRef TT) const { | |||
342 | if (!MCRegInfoCtorFn) | |||
343 | return nullptr; | |||
344 | return MCRegInfoCtorFn(Triple(TT)); | |||
345 | } | |||
346 | ||||
347 | /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. | |||
348 | /// | |||
349 | /// \param TheTriple This argument is used to determine the target machine | |||
350 | /// feature set; it should always be provided. Generally this should be | |||
351 | /// either the target triple from the module, or the target triple of the | |||
352 | /// host if that does not exist. | |||
353 | /// \param CPU This specifies the name of the target CPU. | |||
354 | /// \param Features This specifies the string representation of the | |||
355 | /// additional target features. | |||
356 | MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, | |||
357 | StringRef Features) const { | |||
358 | if (!MCSubtargetInfoCtorFn) | |||
359 | return nullptr; | |||
360 | return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features); | |||
361 | } | |||
362 | ||||
363 | /// createTargetMachine - Create a target specific machine implementation | |||
364 | /// for the specified \p Triple. | |||
365 | /// | |||
366 | /// \param TT This argument is used to determine the target machine | |||
367 | /// feature set; it should always be provided. Generally this should be | |||
368 | /// either the target triple from the module, or the target triple of the | |||
369 | /// host if that does not exist. | |||
370 | TargetMachine *createTargetMachine(StringRef TT, StringRef CPU, | |||
371 | StringRef Features, | |||
372 | const TargetOptions &Options, | |||
373 | Optional<Reloc::Model> RM, | |||
374 | Optional<CodeModel::Model> CM = None, | |||
375 | CodeGenOpt::Level OL = CodeGenOpt::Default, | |||
376 | bool JIT = false) const { | |||
377 | if (!TargetMachineCtorFn) | |||
378 | return nullptr; | |||
379 | return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM, | |||
380 | CM, OL, JIT); | |||
381 | } | |||
382 | ||||
383 | /// createMCAsmBackend - Create a target specific assembly parser. | |||
384 | MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI, | |||
385 | const MCRegisterInfo &MRI, | |||
386 | const MCTargetOptions &Options) const { | |||
387 | if (!MCAsmBackendCtorFn) | |||
388 | return nullptr; | |||
389 | return MCAsmBackendCtorFn(*this, STI, MRI, Options); | |||
390 | } | |||
391 | ||||
392 | /// createMCAsmParser - Create a target specific assembly parser. | |||
393 | /// | |||
394 | /// \param Parser The target independent parser implementation to use for | |||
395 | /// parsing and lexing. | |||
396 | MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI, | |||
397 | MCAsmParser &Parser, | |||
398 | const MCInstrInfo &MII, | |||
399 | const MCTargetOptions &Options) const { | |||
400 | if (!MCAsmParserCtorFn) | |||
401 | return nullptr; | |||
402 | return MCAsmParserCtorFn(STI, Parser, MII, Options); | |||
403 | } | |||
404 | ||||
405 | /// createAsmPrinter - Create a target specific assembly printer pass. This | |||
406 | /// takes ownership of the MCStreamer object. | |||
407 | AsmPrinter *createAsmPrinter(TargetMachine &TM, | |||
408 | std::unique_ptr<MCStreamer> &&Streamer) const { | |||
409 | if (!AsmPrinterCtorFn) | |||
410 | return nullptr; | |||
411 | return AsmPrinterCtorFn(TM, std::move(Streamer)); | |||
412 | } | |||
413 | ||||
414 | MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI, | |||
415 | MCContext &Ctx) const { | |||
416 | if (!MCDisassemblerCtorFn) | |||
417 | return nullptr; | |||
418 | return MCDisassemblerCtorFn(*this, STI, Ctx); | |||
419 | } | |||
420 | ||||
421 | MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, | |||
422 | const MCAsmInfo &MAI, | |||
423 | const MCInstrInfo &MII, | |||
424 | const MCRegisterInfo &MRI) const { | |||
425 | if (!MCInstPrinterCtorFn) | |||
426 | return nullptr; | |||
427 | return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI); | |||
428 | } | |||
429 | ||||
430 | /// createMCCodeEmitter - Create a target specific code emitter. | |||
431 | MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II, | |||
432 | const MCRegisterInfo &MRI, | |||
433 | MCContext &Ctx) const { | |||
434 | if (!MCCodeEmitterCtorFn) | |||
435 | return nullptr; | |||
436 | return MCCodeEmitterCtorFn(II, MRI, Ctx); | |||
437 | } | |||
438 | ||||
439 | /// Create a target specific MCStreamer. | |||
440 | /// | |||
441 | /// \param T The target triple. | |||
442 | /// \param Ctx The target context. | |||
443 | /// \param TAB The target assembler backend object. Takes ownership. | |||
444 | /// \param OS The stream object. | |||
445 | /// \param Emitter The target independent assembler object.Takes ownership. | |||
446 | /// \param RelaxAll Relax all fixups? | |||
447 | MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx, | |||
448 | std::unique_ptr<MCAsmBackend> &&TAB, | |||
449 | raw_pwrite_stream &OS, | |||
450 | std::unique_ptr<MCCodeEmitter> &&Emitter, | |||
451 | const MCSubtargetInfo &STI, bool RelaxAll, | |||
452 | bool IncrementalLinkerCompatible, | |||
453 | bool DWARFMustBeAtTheEnd) const { | |||
454 | MCStreamer *S; | |||
455 | switch (T.getObjectFormat()) { | |||
456 | default: | |||
457 | llvm_unreachable("Unknown object format")::llvm::llvm_unreachable_internal("Unknown object format", "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/TargetRegistry.h" , 457); | |||
458 | case Triple::COFF: | |||
459 | assert(T.isOSWindows() && "only Windows COFF is supported")(static_cast <bool> (T.isOSWindows() && "only Windows COFF is supported" ) ? void (0) : __assert_fail ("T.isOSWindows() && \"only Windows COFF is supported\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/TargetRegistry.h" , 459, __extension__ __PRETTY_FUNCTION__)); | |||
460 | S = COFFStreamerCtorFn(Ctx, std::move(TAB), OS, std::move(Emitter), | |||
461 | RelaxAll, IncrementalLinkerCompatible); | |||
462 | break; | |||
463 | case Triple::MachO: | |||
464 | if (MachOStreamerCtorFn) | |||
465 | S = MachOStreamerCtorFn(Ctx, std::move(TAB), OS, std::move(Emitter), | |||
466 | RelaxAll, DWARFMustBeAtTheEnd); | |||
467 | else | |||
468 | S = createMachOStreamer(Ctx, std::move(TAB), OS, std::move(Emitter), | |||
469 | RelaxAll, DWARFMustBeAtTheEnd); | |||
470 | break; | |||
471 | case Triple::ELF: | |||
472 | if (ELFStreamerCtorFn) | |||
473 | S = ELFStreamerCtorFn(T, Ctx, std::move(TAB), OS, std::move(Emitter), | |||
474 | RelaxAll); | |||
475 | else | |||
476 | S = createELFStreamer(Ctx, std::move(TAB), OS, std::move(Emitter), | |||
477 | RelaxAll); | |||
478 | break; | |||
479 | case Triple::Wasm: | |||
480 | if (WasmStreamerCtorFn) | |||
481 | S = WasmStreamerCtorFn(T, Ctx, std::move(TAB), OS, std::move(Emitter), | |||
482 | RelaxAll); | |||
483 | else | |||
484 | S = createWasmStreamer(Ctx, std::move(TAB), OS, std::move(Emitter), | |||
485 | RelaxAll); | |||
486 | break; | |||
487 | } | |||
488 | if (ObjectTargetStreamerCtorFn) | |||
489 | ObjectTargetStreamerCtorFn(*S, STI); | |||
490 | return S; | |||
491 | } | |||
492 | ||||
493 | MCStreamer *createAsmStreamer(MCContext &Ctx, | |||
494 | std::unique_ptr<formatted_raw_ostream> OS, | |||
495 | bool IsVerboseAsm, bool UseDwarfDirectory, | |||
496 | MCInstPrinter *InstPrint, MCCodeEmitter *CE, | |||
497 | MCAsmBackend *TAB, bool ShowInst) const { | |||
498 | formatted_raw_ostream &OSRef = *OS; | |||
499 | MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm, | |||
500 | UseDwarfDirectory, InstPrint, CE, | |||
501 | TAB, ShowInst); | |||
502 | createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm); | |||
| ||||
503 | return S; | |||
504 | } | |||
505 | ||||
506 | MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, | |||
507 | formatted_raw_ostream &OS, | |||
508 | MCInstPrinter *InstPrint, | |||
509 | bool IsVerboseAsm) const { | |||
510 | if (AsmTargetStreamerCtorFn) | |||
511 | return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm); | |||
512 | return nullptr; | |||
513 | } | |||
514 | ||||
515 | MCStreamer *createNullStreamer(MCContext &Ctx) const { | |||
516 | MCStreamer *S = llvm::createNullStreamer(Ctx); | |||
517 | createNullTargetStreamer(*S); | |||
518 | return S; | |||
519 | } | |||
520 | ||||
521 | MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const { | |||
522 | if (NullTargetStreamerCtorFn) | |||
523 | return NullTargetStreamerCtorFn(S); | |||
524 | return nullptr; | |||
525 | } | |||
526 | ||||
527 | /// createMCRelocationInfo - Create a target specific MCRelocationInfo. | |||
528 | /// | |||
529 | /// \param TT The target triple. | |||
530 | /// \param Ctx The target context. | |||
531 | MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const { | |||
532 | MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn | |||
533 | ? MCRelocationInfoCtorFn | |||
534 | : llvm::createMCRelocationInfo; | |||
535 | return Fn(Triple(TT), Ctx); | |||
536 | } | |||
537 | ||||
538 | /// createMCSymbolizer - Create a target specific MCSymbolizer. | |||
539 | /// | |||
540 | /// \param TT The target triple. | |||
541 | /// \param GetOpInfo The function to get the symbolic information for | |||
542 | /// operands. | |||
543 | /// \param SymbolLookUp The function to lookup a symbol name. | |||
544 | /// \param DisInfo The pointer to the block of symbolic information for above | |||
545 | /// call | |||
546 | /// back. | |||
547 | /// \param Ctx The target context. | |||
548 | /// \param RelInfo The relocation information for this target. Takes | |||
549 | /// ownership. | |||
550 | MCSymbolizer * | |||
551 | createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, | |||
552 | LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, | |||
553 | MCContext *Ctx, | |||
554 | std::unique_ptr<MCRelocationInfo> &&RelInfo) const { | |||
555 | MCSymbolizerCtorTy Fn = | |||
556 | MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer; | |||
557 | return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx, | |||
558 | std::move(RelInfo)); | |||
559 | } | |||
560 | ||||
561 | /// @} | |||
562 | }; | |||
563 | ||||
564 | /// TargetRegistry - Generic interface to target specific features. | |||
565 | struct TargetRegistry { | |||
566 | // FIXME: Make this a namespace, probably just move all the Register* | |||
567 | // functions into Target (currently they all just set members on the Target | |||
568 | // anyway, and Target friends this class so those functions can... | |||
569 | // function). | |||
570 | TargetRegistry() = delete; | |||
571 | ||||
572 | class iterator | |||
573 | : public std::iterator<std::forward_iterator_tag, Target, ptrdiff_t> { | |||
574 | friend struct TargetRegistry; | |||
575 | ||||
576 | const Target *Current = nullptr; | |||
577 | ||||
578 | explicit iterator(Target *T) : Current(T) {} | |||
579 | ||||
580 | public: | |||
581 | iterator() = default; | |||
582 | ||||
583 | bool operator==(const iterator &x) const { return Current == x.Current; } | |||
584 | bool operator!=(const iterator &x) const { return !operator==(x); } | |||
585 | ||||
586 | // Iterator traversal: forward iteration only | |||
587 | iterator &operator++() { // Preincrement | |||
588 | assert(Current && "Cannot increment end iterator!")(static_cast <bool> (Current && "Cannot increment end iterator!" ) ? void (0) : __assert_fail ("Current && \"Cannot increment end iterator!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/TargetRegistry.h" , 588, __extension__ __PRETTY_FUNCTION__)); | |||
589 | Current = Current->getNext(); | |||
590 | return *this; | |||
591 | } | |||
592 | iterator operator++(int) { // Postincrement | |||
593 | iterator tmp = *this; | |||
594 | ++*this; | |||
595 | return tmp; | |||
596 | } | |||
597 | ||||
598 | const Target &operator*() const { | |||
599 | assert(Current && "Cannot dereference end iterator!")(static_cast <bool> (Current && "Cannot dereference end iterator!" ) ? void (0) : __assert_fail ("Current && \"Cannot dereference end iterator!\"" , "/build/llvm-toolchain-snapshot-7~svn329677/include/llvm/Support/TargetRegistry.h" , 599, __extension__ __PRETTY_FUNCTION__)); | |||
600 | return *Current; | |||
601 | } | |||
602 | ||||
603 | const Target *operator->() const { return &operator*(); } | |||
604 | }; | |||
605 | ||||
606 | /// printRegisteredTargetsForVersion - Print the registered targets | |||
607 | /// appropriately for inclusion in a tool's version output. | |||
608 | static void printRegisteredTargetsForVersion(raw_ostream &OS); | |||
609 | ||||
610 | /// @name Registry Access | |||
611 | /// @{ | |||
612 | ||||
613 | static iterator_range<iterator> targets(); | |||
614 | ||||
615 | /// lookupTarget - Lookup a target based on a target triple. | |||
616 | /// | |||
617 | /// \param Triple - The triple to use for finding a target. | |||
618 | /// \param Error - On failure, an error string describing why no target was | |||
619 | /// found. | |||
620 | static const Target *lookupTarget(const std::string &Triple, | |||
621 | std::string &Error); | |||
622 | ||||
623 | /// lookupTarget - Lookup a target based on an architecture name | |||
624 | /// and a target triple. If the architecture name is non-empty, | |||
625 | /// then the lookup is done by architecture. Otherwise, the target | |||
626 | /// triple is used. | |||
627 | /// | |||
628 | /// \param ArchName - The architecture to use for finding a target. | |||
629 | /// \param TheTriple - The triple to use for finding a target. The | |||
630 | /// triple is updated with canonical architecture name if a lookup | |||
631 | /// by architecture is done. | |||
632 | /// \param Error - On failure, an error string describing why no target was | |||
633 | /// found. | |||
634 | static const Target *lookupTarget(const std::string &ArchName, | |||
635 | Triple &TheTriple, std::string &Error); | |||
636 | ||||
637 | /// @} | |||
638 | /// @name Target Registration | |||
639 | /// @{ | |||
640 | ||||
641 | /// RegisterTarget - Register the given target. Attempts to register a | |||
642 | /// target which has already been registered will be ignored. | |||
643 | /// | |||
644 | /// Clients are responsible for ensuring that registration doesn't occur | |||
645 | /// while another thread is attempting to access the registry. Typically | |||
646 | /// this is done by initializing all targets at program startup. | |||
647 | /// | |||
648 | /// @param T - The target being registered. | |||
649 | /// @param Name - The target name. This should be a static string. | |||
650 | /// @param ShortDesc - A short target description. This should be a static | |||
651 | /// string. | |||
652 | /// @param BackendName - The name of the backend. This should be a static | |||
653 | /// string that is the same for all targets that share a backend | |||
654 | /// implementation and must match the name used in the 'def X : Target ...' in | |||
655 | /// TableGen. | |||
656 | /// @param ArchMatchFn - The arch match checking function for this target. | |||
657 | /// @param HasJIT - Whether the target supports JIT code | |||
658 | /// generation. | |||
659 | static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, | |||
660 | const char *BackendName, | |||
661 | Target::ArchMatchFnTy ArchMatchFn, | |||
662 | bool HasJIT = false); | |||
663 | ||||
664 | /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the | |||
665 | /// given target. | |||
666 | /// | |||
667 | /// Clients are responsible for ensuring that registration doesn't occur | |||
668 | /// while another thread is attempting to access the registry. Typically | |||
669 | /// this is done by initializing all targets at program startup. | |||
670 | /// | |||
671 | /// @param T - The target being registered. | |||
672 | /// @param Fn - A function to construct a MCAsmInfo for the target. | |||
673 | static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { | |||
674 | T.MCAsmInfoCtorFn = Fn; | |||
675 | } | |||
676 | ||||
677 | /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the | |||
678 | /// given target. | |||
679 | /// | |||
680 | /// Clients are responsible for ensuring that registration doesn't occur | |||
681 | /// while another thread is attempting to access the registry. Typically | |||
682 | /// this is done by initializing all targets at program startup. | |||
683 | /// | |||
684 | /// @param T - The target being registered. | |||
685 | /// @param Fn - A function to construct a MCInstrInfo for the target. | |||
686 | static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) { | |||
687 | T.MCInstrInfoCtorFn = Fn; | |||
688 | } | |||
689 | ||||
690 | /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for | |||
691 | /// the given target. | |||
692 | static void RegisterMCInstrAnalysis(Target &T, | |||
693 | Target::MCInstrAnalysisCtorFnTy Fn) { | |||
694 | T.MCInstrAnalysisCtorFn = Fn; | |||
695 | } | |||
696 | ||||
697 | /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the | |||
698 | /// given target. | |||
699 | /// | |||
700 | /// Clients are responsible for ensuring that registration doesn't occur | |||
701 | /// while another thread is attempting to access the registry. Typically | |||
702 | /// this is done by initializing all targets at program startup. | |||
703 | /// | |||
704 | /// @param T - The target being registered. | |||
705 | /// @param Fn - A function to construct a MCRegisterInfo for the target. | |||
706 | static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) { | |||
707 | T.MCRegInfoCtorFn = Fn; | |||
708 | } | |||
709 | ||||
710 | /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for | |||
711 | /// the given target. | |||
712 | /// | |||
713 | /// Clients are responsible for ensuring that registration doesn't occur | |||
714 | /// while another thread is attempting to access the registry. Typically | |||
715 | /// this is done by initializing all targets at program startup. | |||
716 | /// | |||
717 | /// @param T - The target being registered. | |||
718 | /// @param Fn - A function to construct a MCSubtargetInfo for the target. | |||
719 | static void RegisterMCSubtargetInfo(Target &T, | |||
720 | Target::MCSubtargetInfoCtorFnTy Fn) { | |||
721 | T.MCSubtargetInfoCtorFn = Fn; | |||
722 | } | |||
723 | ||||
724 | /// RegisterTargetMachine - Register a TargetMachine implementation for the | |||
725 | /// given target. | |||
726 | /// | |||
727 | /// Clients are responsible for ensuring that registration doesn't occur | |||
728 | /// while another thread is attempting to access the registry. Typically | |||
729 | /// this is done by initializing all targets at program startup. | |||
730 | /// | |||
731 | /// @param T - The target being registered. | |||
732 | /// @param Fn - A function to construct a TargetMachine for the target. | |||
733 | static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) { | |||
734 | T.TargetMachineCtorFn = Fn; | |||
735 | } | |||
736 | ||||
737 | /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the | |||
738 | /// given target. | |||
739 | /// | |||
740 | /// Clients are responsible for ensuring that registration doesn't occur | |||
741 | /// while another thread is attempting to access the registry. Typically | |||
742 | /// this is done by initializing all targets at program startup. | |||
743 | /// | |||
744 | /// @param T - The target being registered. | |||
745 | /// @param Fn - A function to construct an AsmBackend for the target. | |||
746 | static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { | |||
747 | T.MCAsmBackendCtorFn = Fn; | |||
748 | } | |||
749 | ||||
750 | /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for | |||
751 | /// the given target. | |||
752 | /// | |||
753 | /// Clients are responsible for ensuring that registration doesn't occur | |||
754 | /// while another thread is attempting to access the registry. Typically | |||
755 | /// this is done by initializing all targets at program startup. | |||
756 | /// | |||
757 | /// @param T - The target being registered. | |||
758 | /// @param Fn - A function to construct an MCTargetAsmParser for the target. | |||
759 | static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) { | |||
760 | T.MCAsmParserCtorFn = Fn; | |||
761 | } | |||
762 | ||||
763 | /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given | |||
764 | /// target. | |||
765 | /// | |||
766 | /// Clients are responsible for ensuring that registration doesn't occur | |||
767 | /// while another thread is attempting to access the registry. Typically | |||
768 | /// this is done by initializing all targets at program startup. | |||
769 | /// | |||
770 | /// @param T - The target being registered. | |||
771 | /// @param Fn - A function to construct an AsmPrinter for the target. | |||
772 | static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { | |||
773 | T.AsmPrinterCtorFn = Fn; | |||
774 | } | |||
775 | ||||
776 | /// RegisterMCDisassembler - Register a MCDisassembler implementation for | |||
777 | /// the given target. | |||
778 | /// | |||
779 | /// Clients are responsible for ensuring that registration doesn't occur | |||
780 | /// while another thread is attempting to access the registry. Typically | |||
781 | /// this is done by initializing all targets at program startup. | |||
782 | /// | |||
783 | /// @param T - The target being registered. | |||
784 | /// @param Fn - A function to construct an MCDisassembler for the target. | |||
785 | static void RegisterMCDisassembler(Target &T, | |||
786 | Target::MCDisassemblerCtorTy Fn) { | |||
787 | T.MCDisassemblerCtorFn = Fn; | |||
788 | } | |||
789 | ||||
790 | /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the | |||
791 | /// given target. | |||
792 | /// | |||
793 | /// Clients are responsible for ensuring that registration doesn't occur | |||
794 | /// while another thread is attempting to access the registry. Typically | |||
795 | /// this is done by initializing all targets at program startup. | |||
796 | /// | |||
797 | /// @param T - The target being registered. | |||
798 | /// @param Fn - A function to construct an MCInstPrinter for the target. | |||
799 | static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) { | |||
800 | T.MCInstPrinterCtorFn = Fn; | |||
801 | } | |||
802 | ||||
803 | /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the | |||
804 | /// given target. | |||
805 | /// | |||
806 | /// Clients are responsible for ensuring that registration doesn't occur | |||
807 | /// while another thread is attempting to access the registry. Typically | |||
808 | /// this is done by initializing all targets at program startup. | |||
809 | /// | |||
810 | /// @param T - The target being registered. | |||
811 | /// @param Fn - A function to construct an MCCodeEmitter for the target. | |||
812 | static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) { | |||
813 | T.MCCodeEmitterCtorFn = Fn; | |||
814 | } | |||
815 | ||||
816 | static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) { | |||
817 | T.COFFStreamerCtorFn = Fn; | |||
818 | } | |||
819 | ||||
820 | static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) { | |||
821 | T.MachOStreamerCtorFn = Fn; | |||
822 | } | |||
823 | ||||
824 | static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) { | |||
825 | T.ELFStreamerCtorFn = Fn; | |||
826 | } | |||
827 | ||||
828 | static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) { | |||
829 | T.WasmStreamerCtorFn = Fn; | |||
830 | } | |||
831 | ||||
832 | static void RegisterNullTargetStreamer(Target &T, | |||
833 | Target::NullTargetStreamerCtorTy Fn) { | |||
834 | T.NullTargetStreamerCtorFn = Fn; | |||
835 | } | |||
836 | ||||
837 | static void RegisterAsmTargetStreamer(Target &T, | |||
838 | Target::AsmTargetStreamerCtorTy Fn) { | |||
839 | T.AsmTargetStreamerCtorFn = Fn; | |||
840 | } | |||
841 | ||||
842 | static void | |||
843 | RegisterObjectTargetStreamer(Target &T, | |||
844 | Target::ObjectTargetStreamerCtorTy Fn) { | |||
845 | T.ObjectTargetStreamerCtorFn = Fn; | |||
846 | } | |||
847 | ||||
848 | /// RegisterMCRelocationInfo - Register an MCRelocationInfo | |||
849 | /// implementation for the given target. | |||
850 | /// | |||
851 | /// Clients are responsible for ensuring that registration doesn't occur | |||
852 | /// while another thread is attempting to access the registry. Typically | |||
853 | /// this is done by initializing all targets at program startup. | |||
854 | /// | |||
855 | /// @param T - The target being registered. | |||
856 | /// @param Fn - A function to construct an MCRelocationInfo for the target. | |||
857 | static void RegisterMCRelocationInfo(Target &T, | |||
858 | Target::MCRelocationInfoCtorTy Fn) { | |||
859 | T.MCRelocationInfoCtorFn = Fn; | |||
860 | } | |||
861 | ||||
862 | /// RegisterMCSymbolizer - Register an MCSymbolizer | |||
863 | /// implementation for the given target. | |||
864 | /// | |||
865 | /// Clients are responsible for ensuring that registration doesn't occur | |||
866 | /// while another thread is attempting to access the registry. Typically | |||
867 | /// this is done by initializing all targets at program startup. | |||
868 | /// | |||
869 | /// @param T - The target being registered. | |||
870 | /// @param Fn - A function to construct an MCSymbolizer for the target. | |||
871 | static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) { | |||
872 | T.MCSymbolizerCtorFn = Fn; | |||
873 | } | |||
874 | ||||
875 | /// @} | |||
876 | }; | |||
877 | ||||
878 | //===--------------------------------------------------------------------===// | |||
879 | ||||
880 | /// RegisterTarget - Helper template for registering a target, for use in the | |||
881 | /// target's initialization function. Usage: | |||
882 | /// | |||
883 | /// | |||
884 | /// Target &getTheFooTarget() { // The global target instance. | |||
885 | /// static Target TheFooTarget; | |||
886 | /// return TheFooTarget; | |||
887 | /// } | |||
888 | /// extern "C" void LLVMInitializeFooTargetInfo() { | |||
889 | /// RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo | |||
890 | /// description", "Foo" /* Backend Name */); | |||
891 | /// } | |||
892 | template <Triple::ArchType TargetArchType = Triple::UnknownArch, | |||
893 | bool HasJIT = false> | |||
894 | struct RegisterTarget { | |||
895 | RegisterTarget(Target &T, const char *Name, const char *Desc, | |||
896 | const char *BackendName) { | |||
897 | TargetRegistry::RegisterTarget(T, Name, Desc, BackendName, &getArchMatch, | |||
898 | HasJIT); | |||
899 | } | |||
900 | ||||
901 | static bool getArchMatch(Triple::ArchType Arch) { | |||
902 | return Arch == TargetArchType; | |||
903 | } | |||
904 | }; | |||
905 | ||||
906 | /// RegisterMCAsmInfo - Helper template for registering a target assembly info | |||
907 | /// implementation. This invokes the static "Create" method on the class to | |||
908 | /// actually do the construction. Usage: | |||
909 | /// | |||
910 | /// extern "C" void LLVMInitializeFooTarget() { | |||
911 | /// extern Target TheFooTarget; | |||
912 | /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); | |||
913 | /// } | |||
914 | template <class MCAsmInfoImpl> struct RegisterMCAsmInfo { | |||
915 | RegisterMCAsmInfo(Target &T) { | |||
916 | TargetRegistry::RegisterMCAsmInfo(T, &Allocator); | |||
917 | } | |||
918 | ||||
919 | private: | |||
920 | static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, | |||
921 | const Triple &TT) { | |||
922 | return new MCAsmInfoImpl(TT); | |||
923 | } | |||
924 | }; | |||
925 | ||||
926 | /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info | |||
927 | /// implementation. This invokes the specified function to do the | |||
928 | /// construction. Usage: | |||
929 | /// | |||
930 | /// extern "C" void LLVMInitializeFooTarget() { | |||
931 | /// extern Target TheFooTarget; | |||
932 | /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); | |||
933 | /// } | |||
934 | struct RegisterMCAsmInfoFn { | |||
935 | RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { | |||
936 | TargetRegistry::RegisterMCAsmInfo(T, Fn); | |||
937 | } | |||
938 | }; | |||
939 | ||||
940 | /// RegisterMCInstrInfo - Helper template for registering a target instruction | |||
941 | /// info implementation. This invokes the static "Create" method on the class | |||
942 | /// to actually do the construction. Usage: | |||
943 | /// | |||
944 | /// extern "C" void LLVMInitializeFooTarget() { | |||
945 | /// extern Target TheFooTarget; | |||
946 | /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget); | |||
947 | /// } | |||
948 | template <class MCInstrInfoImpl> struct RegisterMCInstrInfo { | |||
949 | RegisterMCInstrInfo(Target &T) { | |||
950 | TargetRegistry::RegisterMCInstrInfo(T, &Allocator); | |||
951 | } | |||
952 | ||||
953 | private: | |||
954 | static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); } | |||
955 | }; | |||
956 | ||||
957 | /// RegisterMCInstrInfoFn - Helper template for registering a target | |||
958 | /// instruction info implementation. This invokes the specified function to | |||
959 | /// do the construction. Usage: | |||
960 | /// | |||
961 | /// extern "C" void LLVMInitializeFooTarget() { | |||
962 | /// extern Target TheFooTarget; | |||
963 | /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction); | |||
964 | /// } | |||
965 | struct RegisterMCInstrInfoFn { | |||
966 | RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) { | |||
967 | TargetRegistry::RegisterMCInstrInfo(T, Fn); | |||
968 | } | |||
969 | }; | |||
970 | ||||
971 | /// RegisterMCInstrAnalysis - Helper template for registering a target | |||
972 | /// instruction analyzer implementation. This invokes the static "Create" | |||
973 | /// method on the class to actually do the construction. Usage: | |||
974 | /// | |||
975 | /// extern "C" void LLVMInitializeFooTarget() { | |||
976 | /// extern Target TheFooTarget; | |||
977 | /// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget); | |||
978 | /// } | |||
979 | template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis { | |||
980 | RegisterMCInstrAnalysis(Target &T) { | |||
981 | TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator); | |||
982 | } | |||
983 | ||||
984 | private: | |||
985 | static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) { | |||
986 | return new MCInstrAnalysisImpl(Info); | |||
987 | } | |||
988 | }; | |||
989 | ||||
990 | /// RegisterMCInstrAnalysisFn - Helper template for registering a target | |||
991 | /// instruction analyzer implementation. This invokes the specified function | |||
992 | /// to do the construction. Usage: | |||
993 | /// | |||
994 | /// extern "C" void LLVMInitializeFooTarget() { | |||
995 | /// extern Target TheFooTarget; | |||
996 | /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction); | |||
997 | /// } | |||
998 | struct RegisterMCInstrAnalysisFn { | |||
999 | RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) { | |||
1000 | TargetRegistry::RegisterMCInstrAnalysis(T, Fn); | |||
1001 | } | |||
1002 | }; | |||
1003 | ||||
1004 | /// RegisterMCRegInfo - Helper template for registering a target register info | |||
1005 | /// implementation. This invokes the static "Create" method on the class to | |||
1006 | /// actually do the construction. Usage: | |||
1007 | /// | |||
1008 | /// extern "C" void LLVMInitializeFooTarget() { | |||
1009 | /// extern Target TheFooTarget; | |||
1010 | /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget); | |||
1011 | /// } | |||
1012 | template <class MCRegisterInfoImpl> struct RegisterMCRegInfo { | |||
1013 | RegisterMCRegInfo(Target &T) { | |||
1014 | TargetRegistry::RegisterMCRegInfo(T, &Allocator); | |||
1015 | } | |||
1016 | ||||
1017 | private: | |||
1018 | static MCRegisterInfo *Allocator(const Triple & /*TT*/) { | |||
1019 | return new MCRegisterInfoImpl(); | |||
1020 | } | |||
1021 | }; | |||
1022 | ||||
1023 | /// RegisterMCRegInfoFn - Helper template for registering a target register | |||
1024 | /// info implementation. This invokes the specified function to do the | |||
1025 | /// construction. Usage: | |||
1026 | /// | |||
1027 | /// extern "C" void LLVMInitializeFooTarget() { | |||
1028 | /// extern Target TheFooTarget; | |||
1029 | /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction); | |||
1030 | /// } | |||
1031 | struct RegisterMCRegInfoFn { | |||
1032 | RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) { | |||
1033 | TargetRegistry::RegisterMCRegInfo(T, Fn); | |||
1034 | } | |||
1035 | }; | |||
1036 | ||||
1037 | /// RegisterMCSubtargetInfo - Helper template for registering a target | |||
1038 | /// subtarget info implementation. This invokes the static "Create" method | |||
1039 | /// on the class to actually do the construction. Usage: | |||
1040 | /// | |||
1041 | /// extern "C" void LLVMInitializeFooTarget() { | |||
1042 | /// extern Target TheFooTarget; | |||
1043 | /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); | |||
1044 | /// } | |||
1045 | template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo { | |||
1046 | RegisterMCSubtargetInfo(Target &T) { | |||
1047 | TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); | |||
1048 | } | |||
1049 | ||||
1050 | private: | |||
1051 | static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/, | |||
1052 | StringRef /*FS*/) { | |||
1053 | return new MCSubtargetInfoImpl(); | |||
1054 | } | |||
1055 | }; | |||
1056 | ||||
1057 | /// RegisterMCSubtargetInfoFn - Helper template for registering a target | |||
1058 | /// subtarget info implementation. This invokes the specified function to | |||
1059 | /// do the construction. Usage: | |||
1060 | /// | |||
1061 | /// extern "C" void LLVMInitializeFooTarget() { | |||
1062 | /// extern Target TheFooTarget; | |||
1063 | /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); | |||
1064 | /// } | |||
1065 | struct RegisterMCSubtargetInfoFn { | |||
1066 | RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { | |||
1067 | TargetRegistry::RegisterMCSubtargetInfo(T, Fn); | |||
1068 | } | |||
1069 | }; | |||
1070 | ||||
1071 | /// RegisterTargetMachine - Helper template for registering a target machine | |||
1072 | /// implementation, for use in the target machine initialization | |||
1073 | /// function. Usage: | |||
1074 | /// | |||
1075 | /// extern "C" void LLVMInitializeFooTarget() { | |||
1076 | /// extern Target TheFooTarget; | |||
1077 | /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget); | |||
1078 | /// } | |||
1079 | template <class TargetMachineImpl> struct RegisterTargetMachine { | |||
1080 | RegisterTargetMachine(Target &T) { | |||
1081 | TargetRegistry::RegisterTargetMachine(T, &Allocator); | |||
1082 | } | |||
1083 | ||||
1084 | private: | |||
1085 | static TargetMachine * | |||
1086 | Allocator(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, | |||
1087 | const TargetOptions &Options, Optional<Reloc::Model> RM, | |||
1088 | Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT) { | |||
1089 | return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT); | |||
1090 | } | |||
1091 | }; | |||
1092 | ||||
1093 | /// RegisterMCAsmBackend - Helper template for registering a target specific | |||
1094 | /// assembler backend. Usage: | |||
1095 | /// | |||
1096 | /// extern "C" void LLVMInitializeFooMCAsmBackend() { | |||
1097 | /// extern Target TheFooTarget; | |||
1098 | /// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget); | |||
1099 | /// } | |||
1100 | template <class MCAsmBackendImpl> struct RegisterMCAsmBackend { | |||
1101 | RegisterMCAsmBackend(Target &T) { | |||
1102 | TargetRegistry::RegisterMCAsmBackend(T, &Allocator); | |||
1103 | } | |||
1104 | ||||
1105 | private: | |||
1106 | static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI, | |||
1107 | const MCRegisterInfo &MRI, | |||
1108 | const MCTargetOptions &Options) { | |||
1109 | return new MCAsmBackendImpl(T, STI, MRI); | |||
1110 | } | |||
1111 | }; | |||
1112 | ||||
1113 | /// RegisterMCAsmParser - Helper template for registering a target specific | |||
1114 | /// assembly parser, for use in the target machine initialization | |||
1115 | /// function. Usage: | |||
1116 | /// | |||
1117 | /// extern "C" void LLVMInitializeFooMCAsmParser() { | |||
1118 | /// extern Target TheFooTarget; | |||
1119 | /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget); | |||
1120 | /// } | |||
1121 | template <class MCAsmParserImpl> struct RegisterMCAsmParser { | |||
1122 | RegisterMCAsmParser(Target &T) { | |||
1123 | TargetRegistry::RegisterMCAsmParser(T, &Allocator); | |||
1124 | } | |||
1125 | ||||
1126 | private: | |||
1127 | static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI, | |||
1128 | MCAsmParser &P, const MCInstrInfo &MII, | |||
1129 | const MCTargetOptions &Options) { | |||
1130 | return new MCAsmParserImpl(STI, P, MII, Options); | |||
1131 | } | |||
1132 | }; | |||
1133 | ||||
1134 | /// RegisterAsmPrinter - Helper template for registering a target specific | |||
1135 | /// assembly printer, for use in the target machine initialization | |||
1136 | /// function. Usage: | |||
1137 | /// | |||
1138 | /// extern "C" void LLVMInitializeFooAsmPrinter() { | |||
1139 | /// extern Target TheFooTarget; | |||
1140 | /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); | |||
1141 | /// } | |||
1142 | template <class AsmPrinterImpl> struct RegisterAsmPrinter { | |||
1143 | RegisterAsmPrinter(Target &T) { | |||
1144 | TargetRegistry::RegisterAsmPrinter(T, &Allocator); | |||
1145 | } | |||
1146 | ||||
1147 | private: | |||
1148 | static AsmPrinter *Allocator(TargetMachine &TM, | |||
1149 | std::unique_ptr<MCStreamer> &&Streamer) { | |||
1150 | return new AsmPrinterImpl(TM, std::move(Streamer)); | |||
1151 | } | |||
1152 | }; | |||
1153 | ||||
1154 | /// RegisterMCCodeEmitter - Helper template for registering a target specific | |||
1155 | /// machine code emitter, for use in the target initialization | |||
1156 | /// function. Usage: | |||
1157 | /// | |||
1158 | /// extern "C" void LLVMInitializeFooMCCodeEmitter() { | |||
1159 | /// extern Target TheFooTarget; | |||
1160 | /// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget); | |||
1161 | /// } | |||
1162 | template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter { | |||
1163 | RegisterMCCodeEmitter(Target &T) { | |||
1164 | TargetRegistry::RegisterMCCodeEmitter(T, &Allocator); | |||
1165 | } | |||
1166 | ||||
1167 | private: | |||
1168 | static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/, | |||
1169 | const MCRegisterInfo & /*MRI*/, | |||
1170 | MCContext & /*Ctx*/) { | |||
1171 | return new MCCodeEmitterImpl(); | |||
1172 | } | |||
1173 | }; | |||
1174 | ||||
1175 | } // end namespace llvm | |||
1176 | ||||
1177 | #endif // LLVM_SUPPORT_TARGETREGISTRY_H |
1 | // unique_ptr implementation -*- C++ -*- |
2 | |
3 | // Copyright (C) 2008-2017 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file bits/unique_ptr.h |
26 | * This is an internal header file, included by other library headers. |
27 | * Do not attempt to use it directly. @headername{memory} |
28 | */ |
29 | |
30 | #ifndef _UNIQUE_PTR_H1 |
31 | #define _UNIQUE_PTR_H1 1 |
32 | |
33 | #include <bits/c++config.h> |
34 | #include <debug/assertions.h> |
35 | #include <type_traits> |
36 | #include <utility> |
37 | #include <tuple> |
38 | #include <bits/stl_function.h> |
39 | #include <bits/functional_hash.h> |
40 | |
41 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
42 | { |
43 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
44 | |
45 | /** |
46 | * @addtogroup pointer_abstractions |
47 | * @{ |
48 | */ |
49 | |
50 | #if _GLIBCXX_USE_DEPRECATED1 |
51 | template<typename> class auto_ptr; |
52 | #endif |
53 | |
54 | /// Primary template of default_delete, used by unique_ptr |
55 | template<typename _Tp> |
56 | struct default_delete |
57 | { |
58 | /// Default constructor |
59 | constexpr default_delete() noexcept = default; |
60 | |
61 | /** @brief Converting constructor. |
62 | * |
63 | * Allows conversion from a deleter for arrays of another type, @p _Up, |
64 | * only if @p _Up* is convertible to @p _Tp*. |
65 | */ |
66 | template<typename _Up, typename = typename |
67 | enable_if<is_convertible<_Up*, _Tp*>::value>::type> |
68 | default_delete(const default_delete<_Up>&) noexcept { } |
69 | |
70 | /// Calls @c delete @p __ptr |
71 | void |
72 | operator()(_Tp* __ptr) const |
73 | { |
74 | static_assert(!is_void<_Tp>::value, |
75 | "can't delete pointer to incomplete type"); |
76 | static_assert(sizeof(_Tp)>0, |
77 | "can't delete pointer to incomplete type"); |
78 | delete __ptr; |
79 | } |
80 | }; |
81 | |
82 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
83 | // DR 740 - omit specialization for array objects with a compile time length |
84 | /// Specialization for arrays, default_delete. |
85 | template<typename _Tp> |
86 | struct default_delete<_Tp[]> |
87 | { |
88 | public: |
89 | /// Default constructor |
90 | constexpr default_delete() noexcept = default; |
91 | |
92 | /** @brief Converting constructor. |
93 | * |
94 | * Allows conversion from a deleter for arrays of another type, such as |
95 | * a const-qualified version of @p _Tp. |
96 | * |
97 | * Conversions from types derived from @c _Tp are not allowed because |
98 | * it is unsafe to @c delete[] an array of derived types through a |
99 | * pointer to the base type. |
100 | */ |
101 | template<typename _Up, typename = typename |
102 | enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type> |
103 | default_delete(const default_delete<_Up[]>&) noexcept { } |
104 | |
105 | /// Calls @c delete[] @p __ptr |
106 | template<typename _Up> |
107 | typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type |
108 | operator()(_Up* __ptr) const |
109 | { |
110 | static_assert(sizeof(_Tp)>0, |
111 | "can't delete pointer to incomplete type"); |
112 | delete [] __ptr; |
113 | } |
114 | }; |
115 | |
116 | template <typename _Tp, typename _Dp> |
117 | class __uniq_ptr_impl |
118 | { |
119 | template <typename _Up, typename _Ep, typename = void> |
120 | struct _Ptr |
121 | { |
122 | using type = _Up*; |
123 | }; |
124 | |
125 | template <typename _Up, typename _Ep> |
126 | struct |
127 | _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> |
128 | { |
129 | using type = typename remove_reference<_Ep>::type::pointer; |
130 | }; |
131 | |
132 | public: |
133 | using _DeleterConstraint = enable_if< |
134 | __and_<__not_<is_pointer<_Dp>>, |
135 | is_default_constructible<_Dp>>::value>; |
136 | |
137 | using pointer = typename _Ptr<_Tp, _Dp>::type; |
138 | |
139 | __uniq_ptr_impl() = default; |
140 | __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; } |
141 | |
142 | template<typename _Del> |
143 | __uniq_ptr_impl(pointer __p, _Del&& __d) |
144 | : _M_t(__p, std::forward<_Del>(__d)) { } |
145 | |
146 | pointer& _M_ptr() { return std::get<0>(_M_t); } |
147 | pointer _M_ptr() const { return std::get<0>(_M_t); } |
148 | _Dp& _M_deleter() { return std::get<1>(_M_t); } |
149 | const _Dp& _M_deleter() const { return std::get<1>(_M_t); } |
150 | |
151 | private: |
152 | tuple<pointer, _Dp> _M_t; |
153 | }; |
154 | |
155 | /// 20.7.1.2 unique_ptr for single objects. |
156 | template <typename _Tp, typename _Dp = default_delete<_Tp>> |
157 | class unique_ptr |
158 | { |
159 | template <class _Up> |
160 | using _DeleterConstraint = |
161 | typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; |
162 | |
163 | __uniq_ptr_impl<_Tp, _Dp> _M_t; |
164 | |
165 | public: |
166 | using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; |
167 | using element_type = _Tp; |
168 | using deleter_type = _Dp; |
169 | |
170 | // helper template for detecting a safe conversion from another |
171 | // unique_ptr |
172 | template<typename _Up, typename _Ep> |
173 | using __safe_conversion_up = __and_< |
174 | is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, |
175 | __not_<is_array<_Up>>, |
176 | __or_<__and_<is_reference<deleter_type>, |
177 | is_same<deleter_type, _Ep>>, |
178 | __and_<__not_<is_reference<deleter_type>>, |
179 | is_convertible<_Ep, deleter_type>> |
180 | > |
181 | >; |
182 | |
183 | // Constructors. |
184 | |
185 | /// Default constructor, creates a unique_ptr that owns nothing. |
186 | template <typename _Up = _Dp, |
187 | typename = _DeleterConstraint<_Up>> |
188 | constexpr unique_ptr() noexcept |
189 | : _M_t() |
190 | { } |
191 | |
192 | /** Takes ownership of a pointer. |
193 | * |
194 | * @param __p A pointer to an object of @c element_type |
195 | * |
196 | * The deleter will be value-initialized. |
197 | */ |
198 | template <typename _Up = _Dp, |
199 | typename = _DeleterConstraint<_Up>> |
200 | explicit |
201 | unique_ptr(pointer __p) noexcept |
202 | : _M_t(__p) |
203 | { } |
204 | |
205 | /** Takes ownership of a pointer. |
206 | * |
207 | * @param __p A pointer to an object of @c element_type |
208 | * @param __d A reference to a deleter. |
209 | * |
210 | * The deleter will be initialized with @p __d |
211 | */ |
212 | unique_ptr(pointer __p, |
213 | typename conditional<is_reference<deleter_type>::value, |
214 | deleter_type, const deleter_type&>::type __d) noexcept |
215 | : _M_t(__p, __d) { } |
216 | |
217 | /** Takes ownership of a pointer. |
218 | * |
219 | * @param __p A pointer to an object of @c element_type |
220 | * @param __d An rvalue reference to a deleter. |
221 | * |
222 | * The deleter will be initialized with @p std::move(__d) |
223 | */ |
224 | unique_ptr(pointer __p, |
225 | typename remove_reference<deleter_type>::type&& __d) noexcept |
226 | : _M_t(std::move(__p), std::move(__d)) |
227 | { static_assert(!std::is_reference<deleter_type>::value, |
228 | "rvalue deleter bound to reference"); } |
229 | |
230 | /// Creates a unique_ptr that owns nothing. |
231 | template <typename _Up = _Dp, |
232 | typename = _DeleterConstraint<_Up>> |
233 | constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } |
234 | |
235 | // Move constructors. |
236 | |
237 | /// Move constructor. |
238 | unique_ptr(unique_ptr&& __u) noexcept |
239 | : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } |
240 | |
241 | /** @brief Converting constructor from another type |
242 | * |
243 | * Requires that the pointer owned by @p __u is convertible to the |
244 | * type of pointer owned by this object, @p __u does not own an array, |
245 | * and @p __u has a compatible deleter type. |
246 | */ |
247 | template<typename _Up, typename _Ep, typename = _Require< |
248 | __safe_conversion_up<_Up, _Ep>, |
249 | typename conditional<is_reference<_Dp>::value, |
250 | is_same<_Ep, _Dp>, |
251 | is_convertible<_Ep, _Dp>>::type>> |
252 | unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept |
253 | : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) |
254 | { } |
255 | |
256 | #if _GLIBCXX_USE_DEPRECATED1 |
257 | /// Converting constructor from @c auto_ptr |
258 | template<typename _Up, typename = _Require< |
259 | is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> |
260 | unique_ptr(auto_ptr<_Up>&& __u) noexcept; |
261 | #endif |
262 | |
263 | /// Destructor, invokes the deleter if the stored pointer is not null. |
264 | ~unique_ptr() noexcept |
265 | { |
266 | auto& __ptr = _M_t._M_ptr(); |
267 | if (__ptr != nullptr) |
268 | get_deleter()(__ptr); |
269 | __ptr = pointer(); |
270 | } |
271 | |
272 | // Assignment. |
273 | |
274 | /** @brief Move assignment operator. |
275 | * |
276 | * @param __u The object to transfer ownership from. |
277 | * |
278 | * Invokes the deleter first if this object owns a pointer. |
279 | */ |
280 | unique_ptr& |
281 | operator=(unique_ptr&& __u) noexcept |
282 | { |
283 | reset(__u.release()); |
284 | get_deleter() = std::forward<deleter_type>(__u.get_deleter()); |
285 | return *this; |
286 | } |
287 | |
288 | /** @brief Assignment from another type. |
289 | * |
290 | * @param __u The object to transfer ownership from, which owns a |
291 | * convertible pointer to a non-array object. |
292 | * |
293 | * Invokes the deleter first if this object owns a pointer. |
294 | */ |
295 | template<typename _Up, typename _Ep> |
296 | typename enable_if< __and_< |
297 | __safe_conversion_up<_Up, _Ep>, |
298 | is_assignable<deleter_type&, _Ep&&> |
299 | >::value, |
300 | unique_ptr&>::type |
301 | operator=(unique_ptr<_Up, _Ep>&& __u) noexcept |
302 | { |
303 | reset(__u.release()); |
304 | get_deleter() = std::forward<_Ep>(__u.get_deleter()); |
305 | return *this; |
306 | } |
307 | |
308 | /// Reset the %unique_ptr to empty, invoking the deleter if necessary. |
309 | unique_ptr& |
310 | operator=(nullptr_t) noexcept |
311 | { |
312 | reset(); |
313 | return *this; |
314 | } |
315 | |
316 | // Observers. |
317 | |
318 | /// Dereference the stored pointer. |
319 | typename add_lvalue_reference<element_type>::type |
320 | operator*() const |
321 | { |
322 | __glibcxx_assert(get() != pointer()); |
323 | return *get(); |
324 | } |
325 | |
326 | /// Return the stored pointer. |
327 | pointer |
328 | operator->() const noexcept |
329 | { |
330 | _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); |
331 | return get(); |
332 | } |
333 | |
334 | /// Return the stored pointer. |
335 | pointer |
336 | get() const noexcept |
337 | { return _M_t._M_ptr(); } |
338 | |
339 | /// Return a reference to the stored deleter. |
340 | deleter_type& |
341 | get_deleter() noexcept |
342 | { return _M_t._M_deleter(); } |
343 | |
344 | /// Return a reference to the stored deleter. |
345 | const deleter_type& |
346 | get_deleter() const noexcept |
347 | { return _M_t._M_deleter(); } |
348 | |
349 | /// Return @c true if the stored pointer is not null. |
350 | explicit operator bool() const noexcept |
351 | { return get() == pointer() ? false : true; } |
352 | |
353 | // Modifiers. |
354 | |
355 | /// Release ownership of any stored pointer. |
356 | pointer |
357 | release() noexcept |
358 | { |
359 | pointer __p = get(); |
360 | _M_t._M_ptr() = pointer(); |
361 | return __p; |
362 | } |
363 | |
364 | /** @brief Replace the stored pointer. |
365 | * |
366 | * @param __p The new pointer to store. |
367 | * |
368 | * The deleter will be invoked if a pointer is already owned. |
369 | */ |
370 | void |
371 | reset(pointer __p = pointer()) noexcept |
372 | { |
373 | using std::swap; |
374 | swap(_M_t._M_ptr(), __p); |
375 | if (__p != pointer()) |
376 | get_deleter()(__p); |
377 | } |
378 | |
379 | /// Exchange the pointer and deleter with another object. |
380 | void |
381 | swap(unique_ptr& __u) noexcept |
382 | { |
383 | using std::swap; |
384 | swap(_M_t, __u._M_t); |
385 | } |
386 | |
387 | // Disable copy from lvalue. |
388 | unique_ptr(const unique_ptr&) = delete; |
389 | unique_ptr& operator=(const unique_ptr&) = delete; |
390 | }; |
391 | |
392 | /// 20.7.1.3 unique_ptr for array objects with a runtime length |
393 | // [unique.ptr.runtime] |
394 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
395 | // DR 740 - omit specialization for array objects with a compile time length |
396 | template<typename _Tp, typename _Dp> |
397 | class unique_ptr<_Tp[], _Dp> |
398 | { |
399 | template <typename _Up> |
400 | using _DeleterConstraint = |
401 | typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; |
402 | |
403 | __uniq_ptr_impl<_Tp, _Dp> _M_t; |
404 | |
405 | template<typename _Up> |
406 | using __remove_cv = typename remove_cv<_Up>::type; |
407 | |
408 | // like is_base_of<_Tp, _Up> but false if unqualified types are the same |
409 | template<typename _Up> |
410 | using __is_derived_Tp |
411 | = __and_< is_base_of<_Tp, _Up>, |
412 | __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; |
413 | |
414 | public: |
415 | using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; |
416 | using element_type = _Tp; |
417 | using deleter_type = _Dp; |
418 | |
419 | // helper template for detecting a safe conversion from another |
420 | // unique_ptr |
421 | template<typename _Up, typename _Ep, |
422 | typename _Up_up = unique_ptr<_Up, _Ep>, |
423 | typename _Up_element_type = typename _Up_up::element_type> |
424 | using __safe_conversion_up = __and_< |
425 | is_array<_Up>, |
426 | is_same<pointer, element_type*>, |
427 | is_same<typename _Up_up::pointer, _Up_element_type*>, |
428 | is_convertible<_Up_element_type(*)[], element_type(*)[]>, |
429 | __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>, |
430 | __and_<__not_<is_reference<deleter_type>>, |
431 | is_convertible<_Ep, deleter_type>>> |
432 | >; |
433 | |
434 | // helper template for detecting a safe conversion from a raw pointer |
435 | template<typename _Up> |
436 | using __safe_conversion_raw = __and_< |
437 | __or_<__or_<is_same<_Up, pointer>, |
438 | is_same<_Up, nullptr_t>>, |
439 | __and_<is_pointer<_Up>, |
440 | is_same<pointer, element_type*>, |
441 | is_convertible< |
442 | typename remove_pointer<_Up>::type(*)[], |
443 | element_type(*)[]> |
444 | > |
445 | > |
446 | >; |
447 | |
448 | // Constructors. |
449 | |
450 | /// Default constructor, creates a unique_ptr that owns nothing. |
451 | template <typename _Up = _Dp, |
452 | typename = _DeleterConstraint<_Up>> |
453 | constexpr unique_ptr() noexcept |
454 | : _M_t() |
455 | { } |
456 | |
457 | /** Takes ownership of a pointer. |
458 | * |
459 | * @param __p A pointer to an array of a type safely convertible |
460 | * to an array of @c element_type |
461 | * |
462 | * The deleter will be value-initialized. |
463 | */ |
464 | template<typename _Up, |
465 | typename _Vp = _Dp, |
466 | typename = _DeleterConstraint<_Vp>, |
467 | typename = typename enable_if< |
468 | __safe_conversion_raw<_Up>::value, bool>::type> |
469 | explicit |
470 | unique_ptr(_Up __p) noexcept |
471 | : _M_t(__p) |
472 | { } |
473 | |
474 | /** Takes ownership of a pointer. |
475 | * |
476 | * @param __p A pointer to an array of a type safely convertible |
477 | * to an array of @c element_type |
478 | * @param __d A reference to a deleter. |
479 | * |
480 | * The deleter will be initialized with @p __d |
481 | */ |
482 | template<typename _Up, |
483 | typename = typename enable_if< |
484 | __safe_conversion_raw<_Up>::value, bool>::type> |
485 | unique_ptr(_Up __p, |
486 | typename conditional<is_reference<deleter_type>::value, |
487 | deleter_type, const deleter_type&>::type __d) noexcept |
488 | : _M_t(__p, __d) { } |
489 | |
490 | /** Takes ownership of a pointer. |
491 | * |
492 | * @param __p A pointer to an array of a type safely convertible |
493 | * to an array of @c element_type |
494 | * @param __d A reference to a deleter. |
495 | * |
496 | * The deleter will be initialized with @p std::move(__d) |
497 | */ |
498 | template<typename _Up, |
499 | typename = typename enable_if< |
500 | __safe_conversion_raw<_Up>::value, bool>::type> |
501 | unique_ptr(_Up __p, typename |
502 | remove_reference<deleter_type>::type&& __d) noexcept |
503 | : _M_t(std::move(__p), std::move(__d)) |
504 | { static_assert(!is_reference<deleter_type>::value, |
505 | "rvalue deleter bound to reference"); } |
506 | |
507 | /// Move constructor. |
508 | unique_ptr(unique_ptr&& __u) noexcept |
509 | : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } |
510 | |
511 | /// Creates a unique_ptr that owns nothing. |
512 | template <typename _Up = _Dp, |
513 | typename = _DeleterConstraint<_Up>> |
514 | constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } |
515 | |
516 | template<typename _Up, typename _Ep, |
517 | typename = _Require<__safe_conversion_up<_Up, _Ep>>> |
518 | unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept |
519 | : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) |
520 | { } |
521 | |
522 | /// Destructor, invokes the deleter if the stored pointer is not null. |
523 | ~unique_ptr() |
524 | { |
525 | auto& __ptr = _M_t._M_ptr(); |
526 | if (__ptr != nullptr) |
527 | get_deleter()(__ptr); |
528 | __ptr = pointer(); |
529 | } |
530 | |
531 | // Assignment. |
532 | |
533 | /** @brief Move assignment operator. |
534 | * |
535 | * @param __u The object to transfer ownership from. |
536 | * |
537 | * Invokes the deleter first if this object owns a pointer. |
538 | */ |
539 | unique_ptr& |
540 | operator=(unique_ptr&& __u) noexcept |
541 | { |
542 | reset(__u.release()); |
543 | get_deleter() = std::forward<deleter_type>(__u.get_deleter()); |
544 | return *this; |
545 | } |
546 | |
547 | /** @brief Assignment from another type. |
548 | * |
549 | * @param __u The object to transfer ownership from, which owns a |
550 | * convertible pointer to an array object. |
551 | * |
552 | * Invokes the deleter first if this object owns a pointer. |
553 | */ |
554 | template<typename _Up, typename _Ep> |
555 | typename |
556 | enable_if<__and_<__safe_conversion_up<_Up, _Ep>, |
557 | is_assignable<deleter_type&, _Ep&&> |
558 | >::value, |
559 | unique_ptr&>::type |
560 | operator=(unique_ptr<_Up, _Ep>&& __u) noexcept |
561 | { |
562 | reset(__u.release()); |
563 | get_deleter() = std::forward<_Ep>(__u.get_deleter()); |
564 | return *this; |
565 | } |
566 | |
567 | /// Reset the %unique_ptr to empty, invoking the deleter if necessary. |
568 | unique_ptr& |
569 | operator=(nullptr_t) noexcept |
570 | { |
571 | reset(); |
572 | return *this; |
573 | } |
574 | |
575 | // Observers. |
576 | |
577 | /// Access an element of owned array. |
578 | typename std::add_lvalue_reference<element_type>::type |
579 | operator[](size_t __i) const |
580 | { |
581 | __glibcxx_assert(get() != pointer()); |
582 | return get()[__i]; |
583 | } |
584 | |
585 | /// Return the stored pointer. |
586 | pointer |
587 | get() const noexcept |
588 | { return _M_t._M_ptr(); } |
589 | |
590 | /// Return a reference to the stored deleter. |
591 | deleter_type& |
592 | get_deleter() noexcept |
593 | { return _M_t._M_deleter(); } |
594 | |
595 | /// Return a reference to the stored deleter. |
596 | const deleter_type& |
597 | get_deleter() const noexcept |
598 | { return _M_t._M_deleter(); } |
599 | |
600 | /// Return @c true if the stored pointer is not null. |
601 | explicit operator bool() const noexcept |
602 | { return get() == pointer() ? false : true; } |
603 | |
604 | // Modifiers. |
605 | |
606 | /// Release ownership of any stored pointer. |
607 | pointer |
608 | release() noexcept |
609 | { |
610 | pointer __p = get(); |
611 | _M_t._M_ptr() = pointer(); |
612 | return __p; |
613 | } |
614 | |
615 | /** @brief Replace the stored pointer. |
616 | * |
617 | * @param __p The new pointer to store. |
618 | * |
619 | * The deleter will be invoked if a pointer is already owned. |
620 | */ |
621 | template <typename _Up, |
622 | typename = _Require< |
623 | __or_<is_same<_Up, pointer>, |
624 | __and_<is_same<pointer, element_type*>, |
625 | is_pointer<_Up>, |
626 | is_convertible< |
627 | typename remove_pointer<_Up>::type(*)[], |
628 | element_type(*)[] |
629 | > |
630 | > |
631 | > |
632 | >> |
633 | void |
634 | reset(_Up __p) noexcept |
635 | { |
636 | pointer __ptr = __p; |
637 | using std::swap; |
638 | swap(_M_t._M_ptr(), __ptr); |
639 | if (__ptr != nullptr) |
640 | get_deleter()(__ptr); |
641 | } |
642 | |
643 | void reset(nullptr_t = nullptr) noexcept |
644 | { |
645 | reset(pointer()); |
646 | } |
647 | |
648 | /// Exchange the pointer and deleter with another object. |
649 | void |
650 | swap(unique_ptr& __u) noexcept |
651 | { |
652 | using std::swap; |
653 | swap(_M_t, __u._M_t); |
654 | } |
655 | |
656 | // Disable copy from lvalue. |
657 | unique_ptr(const unique_ptr&) = delete; |
658 | unique_ptr& operator=(const unique_ptr&) = delete; |
659 | }; |
660 | |
661 | template<typename _Tp, typename _Dp> |
662 | inline |
663 | #if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11 |
664 | // Constrained free swap overload, see p0185r1 |
665 | typename enable_if<__is_swappable<_Dp>::value>::type |
666 | #else |
667 | void |
668 | #endif |
669 | swap(unique_ptr<_Tp, _Dp>& __x, |
670 | unique_ptr<_Tp, _Dp>& __y) noexcept |
671 | { __x.swap(__y); } |
672 | |
673 | #if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11 |
674 | template<typename _Tp, typename _Dp> |
675 | typename enable_if<!__is_swappable<_Dp>::value>::type |
676 | swap(unique_ptr<_Tp, _Dp>&, |
677 | unique_ptr<_Tp, _Dp>&) = delete; |
678 | #endif |
679 | |
680 | template<typename _Tp, typename _Dp, |
681 | typename _Up, typename _Ep> |
682 | inline bool |
683 | operator==(const unique_ptr<_Tp, _Dp>& __x, |
684 | const unique_ptr<_Up, _Ep>& __y) |
685 | { return __x.get() == __y.get(); } |
686 | |
687 | template<typename _Tp, typename _Dp> |
688 | inline bool |
689 | operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept |
690 | { return !__x; } |
691 | |
692 | template<typename _Tp, typename _Dp> |
693 | inline bool |
694 | operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept |
695 | { return !__x; } |
696 | |
697 | template<typename _Tp, typename _Dp, |
698 | typename _Up, typename _Ep> |
699 | inline bool |
700 | operator!=(const unique_ptr<_Tp, _Dp>& __x, |
701 | const unique_ptr<_Up, _Ep>& __y) |
702 | { return __x.get() != __y.get(); } |
703 | |
704 | template<typename _Tp, typename _Dp> |
705 | inline bool |
706 | operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept |
707 | { return (bool)__x; } |
708 | |
709 | template<typename _Tp, typename _Dp> |
710 | inline bool |
711 | operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept |
712 | { return (bool)__x; } |
713 | |
714 | template<typename _Tp, typename _Dp, |
715 | typename _Up, typename _Ep> |
716 | inline bool |
717 | operator<(const unique_ptr<_Tp, _Dp>& __x, |
718 | const unique_ptr<_Up, _Ep>& __y) |
719 | { |
720 | typedef typename |
721 | std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, |
722 | typename unique_ptr<_Up, _Ep>::pointer>::type _CT; |
723 | return std::less<_CT>()(__x.get(), __y.get()); |
724 | } |
725 | |
726 | template<typename _Tp, typename _Dp> |
727 | inline bool |
728 | operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
729 | { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), |
730 | nullptr); } |
731 | |
732 | template<typename _Tp, typename _Dp> |
733 | inline bool |
734 | operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
735 | { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, |
736 | __x.get()); } |
737 | |
738 | template<typename _Tp, typename _Dp, |
739 | typename _Up, typename _Ep> |
740 | inline bool |
741 | operator<=(const unique_ptr<_Tp, _Dp>& __x, |
742 | const unique_ptr<_Up, _Ep>& __y) |
743 | { return !(__y < __x); } |
744 | |
745 | template<typename _Tp, typename _Dp> |
746 | inline bool |
747 | operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
748 | { return !(nullptr < __x); } |
749 | |
750 | template<typename _Tp, typename _Dp> |
751 | inline bool |
752 | operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
753 | { return !(__x < nullptr); } |
754 | |
755 | template<typename _Tp, typename _Dp, |
756 | typename _Up, typename _Ep> |
757 | inline bool |
758 | operator>(const unique_ptr<_Tp, _Dp>& __x, |
759 | const unique_ptr<_Up, _Ep>& __y) |
760 | { return (__y < __x); } |
761 | |
762 | template<typename _Tp, typename _Dp> |
763 | inline bool |
764 | operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
765 | { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, |
766 | __x.get()); } |
767 | |
768 | template<typename _Tp, typename _Dp> |
769 | inline bool |
770 | operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
771 | { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), |
772 | nullptr); } |
773 | |
774 | template<typename _Tp, typename _Dp, |
775 | typename _Up, typename _Ep> |
776 | inline bool |
777 | operator>=(const unique_ptr<_Tp, _Dp>& __x, |
778 | const unique_ptr<_Up, _Ep>& __y) |
779 | { return !(__x < __y); } |
780 | |
781 | template<typename _Tp, typename _Dp> |
782 | inline bool |
783 | operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
784 | { return !(__x < nullptr); } |
785 | |
786 | template<typename _Tp, typename _Dp> |
787 | inline bool |
788 | operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
789 | { return !(nullptr < __x); } |
790 | |
791 | /// std::hash specialization for unique_ptr. |
792 | template<typename _Tp, typename _Dp> |
793 | struct hash<unique_ptr<_Tp, _Dp>> |
794 | : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, |
795 | private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer> |
796 | { |
797 | size_t |
798 | operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept |
799 | { |
800 | typedef unique_ptr<_Tp, _Dp> _UP; |
801 | return std::hash<typename _UP::pointer>()(__u.get()); |
802 | } |
803 | }; |
804 | |
805 | #if __cplusplus201103L > 201103L |
806 | |
807 | #define __cpp_lib_make_unique 201304 |
808 | |
809 | template<typename _Tp> |
810 | struct _MakeUniq |
811 | { typedef unique_ptr<_Tp> __single_object; }; |
812 | |
813 | template<typename _Tp> |
814 | struct _MakeUniq<_Tp[]> |
815 | { typedef unique_ptr<_Tp[]> __array; }; |
816 | |
817 | template<typename _Tp, size_t _Bound> |
818 | struct _MakeUniq<_Tp[_Bound]> |
819 | { struct __invalid_type { }; }; |
820 | |
821 | /// std::make_unique for single objects |
822 | template<typename _Tp, typename... _Args> |
823 | inline typename _MakeUniq<_Tp>::__single_object |
824 | make_unique(_Args&&... __args) |
825 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } |
826 | |
827 | /// std::make_unique for arrays of unknown bound |
828 | template<typename _Tp> |
829 | inline typename _MakeUniq<_Tp>::__array |
830 | make_unique(size_t __num) |
831 | { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } |
832 | |
833 | /// Disable std::make_unique for arrays of known bound |
834 | template<typename _Tp, typename... _Args> |
835 | inline typename _MakeUniq<_Tp>::__invalid_type |
836 | make_unique(_Args&&...) = delete; |
837 | #endif |
838 | |
839 | // @} group pointer_abstractions |
840 | |
841 | _GLIBCXX_END_NAMESPACE_VERSION |
842 | } // namespace |
843 | |
844 | #endif /* _UNIQUE_PTR_H */ |