File: | tools/bugpoint/Miscompilation.cpp |
Warning: | line 354, column 9 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- Miscompilation.cpp - Debug program miscompilations -----------------===// | |||
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 optimizer and code generation miscompilation debugging | |||
11 | // support. | |||
12 | // | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #include "BugDriver.h" | |||
16 | #include "ListReducer.h" | |||
17 | #include "ToolRunner.h" | |||
18 | #include "llvm/Config/config.h" // for HAVE_LINK_R | |||
19 | #include "llvm/IR/Constants.h" | |||
20 | #include "llvm/IR/DerivedTypes.h" | |||
21 | #include "llvm/IR/Instructions.h" | |||
22 | #include "llvm/IR/Module.h" | |||
23 | #include "llvm/IR/Verifier.h" | |||
24 | #include "llvm/Linker/Linker.h" | |||
25 | #include "llvm/Pass.h" | |||
26 | #include "llvm/Support/CommandLine.h" | |||
27 | #include "llvm/Support/FileUtilities.h" | |||
28 | #include "llvm/Transforms/Utils/Cloning.h" | |||
29 | ||||
30 | using namespace llvm; | |||
31 | ||||
32 | namespace llvm { | |||
33 | extern cl::opt<std::string> OutputPrefix; | |||
34 | extern cl::list<std::string> InputArgv; | |||
35 | } // end namespace llvm | |||
36 | ||||
37 | namespace { | |||
38 | static llvm::cl::opt<bool> DisableLoopExtraction( | |||
39 | "disable-loop-extraction", | |||
40 | cl::desc("Don't extract loops when searching for miscompilations"), | |||
41 | cl::init(false)); | |||
42 | static llvm::cl::opt<bool> DisableBlockExtraction( | |||
43 | "disable-block-extraction", | |||
44 | cl::desc("Don't extract blocks when searching for miscompilations"), | |||
45 | cl::init(false)); | |||
46 | ||||
47 | class ReduceMiscompilingPasses : public ListReducer<std::string> { | |||
48 | BugDriver &BD; | |||
49 | ||||
50 | public: | |||
51 | ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} | |||
52 | ||||
53 | Expected<TestResult> doTest(std::vector<std::string> &Prefix, | |||
54 | std::vector<std::string> &Suffix) override; | |||
55 | }; | |||
56 | } // end anonymous namespace | |||
57 | ||||
58 | /// TestResult - After passes have been split into a test group and a control | |||
59 | /// group, see if they still break the program. | |||
60 | /// | |||
61 | Expected<ReduceMiscompilingPasses::TestResult> | |||
62 | ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, | |||
63 | std::vector<std::string> &Suffix) { | |||
64 | // First, run the program with just the Suffix passes. If it is still broken | |||
65 | // with JUST the kept passes, discard the prefix passes. | |||
66 | outs() << "Checking to see if '" << getPassesString(Suffix) | |||
67 | << "' compiles correctly: "; | |||
68 | ||||
69 | std::string BitcodeResult; | |||
70 | if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false /*delete*/, | |||
71 | true /*quiet*/)) { | |||
72 | errs() << " Error running this sequence of passes" | |||
73 | << " on the input program!\n"; | |||
74 | BD.setPassesToRun(Suffix); | |||
75 | BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); | |||
76 | // TODO: This should propagate the error instead of exiting. | |||
77 | if (Error E = BD.debugOptimizerCrash()) | |||
78 | exit(1); | |||
79 | exit(0); | |||
80 | } | |||
81 | ||||
82 | // Check to see if the finished program matches the reference output... | |||
83 | Expected<bool> Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", | |||
84 | true /*delete bitcode*/); | |||
85 | if (Error E = Diff.takeError()) | |||
86 | return std::move(E); | |||
87 | if (*Diff) { | |||
88 | outs() << " nope.\n"; | |||
89 | if (Suffix.empty()) { | |||
90 | errs() << BD.getToolName() << ": I'm confused: the test fails when " | |||
91 | << "no passes are run, nondeterministic program?\n"; | |||
92 | exit(1); | |||
93 | } | |||
94 | return KeepSuffix; // Miscompilation detected! | |||
95 | } | |||
96 | outs() << " yup.\n"; // No miscompilation! | |||
97 | ||||
98 | if (Prefix.empty()) | |||
99 | return NoFailure; | |||
100 | ||||
101 | // Next, see if the program is broken if we run the "prefix" passes first, | |||
102 | // then separately run the "kept" passes. | |||
103 | outs() << "Checking to see if '" << getPassesString(Prefix) | |||
104 | << "' compiles correctly: "; | |||
105 | ||||
106 | // If it is not broken with the kept passes, it's possible that the prefix | |||
107 | // passes must be run before the kept passes to break it. If the program | |||
108 | // WORKS after the prefix passes, but then fails if running the prefix AND | |||
109 | // kept passes, we can update our bitcode file to include the result of the | |||
110 | // prefix passes, then discard the prefix passes. | |||
111 | // | |||
112 | if (BD.runPasses(BD.getProgram(), Prefix, BitcodeResult, false /*delete*/, | |||
113 | true /*quiet*/)) { | |||
114 | errs() << " Error running this sequence of passes" | |||
115 | << " on the input program!\n"; | |||
116 | BD.setPassesToRun(Prefix); | |||
117 | BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); | |||
118 | // TODO: This should propagate the error instead of exiting. | |||
119 | if (Error E = BD.debugOptimizerCrash()) | |||
120 | exit(1); | |||
121 | exit(0); | |||
122 | } | |||
123 | ||||
124 | // If the prefix maintains the predicate by itself, only keep the prefix! | |||
125 | Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", false); | |||
126 | if (Error E = Diff.takeError()) | |||
127 | return std::move(E); | |||
128 | if (*Diff) { | |||
129 | outs() << " nope.\n"; | |||
130 | sys::fs::remove(BitcodeResult); | |||
131 | return KeepPrefix; | |||
132 | } | |||
133 | outs() << " yup.\n"; // No miscompilation! | |||
134 | ||||
135 | // Ok, so now we know that the prefix passes work, try running the suffix | |||
136 | // passes on the result of the prefix passes. | |||
137 | // | |||
138 | std::unique_ptr<Module> PrefixOutput = | |||
139 | parseInputFile(BitcodeResult, BD.getContext()); | |||
140 | if (!PrefixOutput) { | |||
141 | errs() << BD.getToolName() << ": Error reading bitcode file '" | |||
142 | << BitcodeResult << "'!\n"; | |||
143 | exit(1); | |||
144 | } | |||
145 | sys::fs::remove(BitcodeResult); | |||
146 | ||||
147 | // Don't check if there are no passes in the suffix. | |||
148 | if (Suffix.empty()) | |||
149 | return NoFailure; | |||
150 | ||||
151 | outs() << "Checking to see if '" << getPassesString(Suffix) | |||
152 | << "' passes compile correctly after the '" << getPassesString(Prefix) | |||
153 | << "' passes: "; | |||
154 | ||||
155 | std::unique_ptr<Module> OriginalInput( | |||
156 | BD.swapProgramIn(PrefixOutput.release())); | |||
157 | if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false /*delete*/, | |||
158 | true /*quiet*/)) { | |||
159 | errs() << " Error running this sequence of passes" | |||
160 | << " on the input program!\n"; | |||
161 | BD.setPassesToRun(Suffix); | |||
162 | BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); | |||
163 | // TODO: This should propagate the error instead of exiting. | |||
164 | if (Error E = BD.debugOptimizerCrash()) | |||
165 | exit(1); | |||
166 | exit(0); | |||
167 | } | |||
168 | ||||
169 | // Run the result... | |||
170 | Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", | |||
171 | true /*delete bitcode*/); | |||
172 | if (Error E = Diff.takeError()) | |||
173 | return std::move(E); | |||
174 | if (*Diff) { | |||
175 | outs() << " nope.\n"; | |||
176 | return KeepSuffix; | |||
177 | } | |||
178 | ||||
179 | // Otherwise, we must not be running the bad pass anymore. | |||
180 | outs() << " yup.\n"; // No miscompilation! | |||
181 | // Restore orig program & free test. | |||
182 | delete BD.swapProgramIn(OriginalInput.release()); | |||
183 | return NoFailure; | |||
184 | } | |||
185 | ||||
186 | namespace { | |||
187 | class ReduceMiscompilingFunctions : public ListReducer<Function *> { | |||
188 | BugDriver &BD; | |||
189 | Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, | |||
190 | std::unique_ptr<Module>); | |||
191 | ||||
192 | public: | |||
193 | ReduceMiscompilingFunctions(BugDriver &bd, | |||
194 | Expected<bool> (*F)(BugDriver &, | |||
195 | std::unique_ptr<Module>, | |||
196 | std::unique_ptr<Module>)) | |||
197 | : BD(bd), TestFn(F) {} | |||
198 | ||||
199 | Expected<TestResult> doTest(std::vector<Function *> &Prefix, | |||
200 | std::vector<Function *> &Suffix) override { | |||
201 | if (!Suffix.empty()) { | |||
202 | Expected<bool> Ret = TestFuncs(Suffix); | |||
203 | if (Error E = Ret.takeError()) | |||
204 | return std::move(E); | |||
205 | if (*Ret) | |||
206 | return KeepSuffix; | |||
207 | } | |||
208 | if (!Prefix.empty()) { | |||
209 | Expected<bool> Ret = TestFuncs(Prefix); | |||
210 | if (Error E = Ret.takeError()) | |||
211 | return std::move(E); | |||
212 | if (*Ret) | |||
213 | return KeepPrefix; | |||
214 | } | |||
215 | return NoFailure; | |||
216 | } | |||
217 | ||||
218 | Expected<bool> TestFuncs(const std::vector<Function *> &Prefix); | |||
219 | }; | |||
220 | } // end anonymous namespace | |||
221 | ||||
222 | /// Given two modules, link them together and run the program, checking to see | |||
223 | /// if the program matches the diff. If there is an error, return NULL. If not, | |||
224 | /// return the merged module. The Broken argument will be set to true if the | |||
225 | /// output is different. If the DeleteInputs argument is set to true then this | |||
226 | /// function deletes both input modules before it returns. | |||
227 | /// | |||
228 | static Expected<std::unique_ptr<Module>> testMergedProgram(const BugDriver &BD, | |||
229 | const Module &M1, | |||
230 | const Module &M2, | |||
231 | bool &Broken) { | |||
232 | // Resulting merge of M1 and M2. | |||
233 | auto Merged = CloneModule(&M1); | |||
234 | if (Linker::linkModules(*Merged, CloneModule(&M2))) | |||
235 | // TODO: Shouldn't we thread the error up instead of exiting? | |||
236 | exit(1); | |||
237 | ||||
238 | // Execute the program. | |||
239 | Expected<bool> Diff = BD.diffProgram(Merged.get(), "", "", false); | |||
240 | if (Error E = Diff.takeError()) | |||
241 | return std::move(E); | |||
242 | Broken = *Diff; | |||
243 | return std::move(Merged); | |||
244 | } | |||
245 | ||||
246 | /// TestFuncs - split functions in a Module into two groups: those that are | |||
247 | /// under consideration for miscompilation vs. those that are not, and test | |||
248 | /// accordingly. Each group of functions becomes a separate Module. | |||
249 | /// | |||
250 | Expected<bool> | |||
251 | ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function *> &Funcs) { | |||
252 | // Test to see if the function is misoptimized if we ONLY run it on the | |||
253 | // functions listed in Funcs. | |||
254 | outs() << "Checking to see if the program is misoptimized when " | |||
255 | << (Funcs.size() == 1 ? "this function is" : "these functions are") | |||
256 | << " run through the pass" | |||
257 | << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; | |||
258 | PrintFunctionList(Funcs); | |||
259 | outs() << '\n'; | |||
260 | ||||
261 | // Create a clone for two reasons: | |||
262 | // * If the optimization passes delete any function, the deleted function | |||
263 | // will be in the clone and Funcs will still point to valid memory | |||
264 | // * If the optimization passes use interprocedural information to break | |||
265 | // a function, we want to continue with the original function. Otherwise | |||
266 | // we can conclude that a function triggers the bug when in fact one | |||
267 | // needs a larger set of original functions to do so. | |||
268 | ValueToValueMapTy VMap; | |||
269 | Module *Clone = CloneModule(BD.getProgram(), VMap).release(); | |||
270 | Module *Orig = BD.swapProgramIn(Clone); | |||
271 | ||||
272 | std::vector<Function *> FuncsOnClone; | |||
273 | for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { | |||
274 | Function *F = cast<Function>(VMap[Funcs[i]]); | |||
275 | FuncsOnClone.push_back(F); | |||
276 | } | |||
277 | ||||
278 | // Split the module into the two halves of the program we want. | |||
279 | VMap.clear(); | |||
280 | std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); | |||
281 | std::unique_ptr<Module> ToOptimize = | |||
282 | SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap); | |||
283 | ||||
284 | Expected<bool> Broken = | |||
285 | TestFn(BD, std::move(ToOptimize), std::move(ToNotOptimize)); | |||
286 | ||||
287 | delete BD.swapProgramIn(Orig); | |||
288 | ||||
289 | return Broken; | |||
290 | } | |||
291 | ||||
292 | /// DisambiguateGlobalSymbols - Give anonymous global values names. | |||
293 | /// | |||
294 | static void DisambiguateGlobalSymbols(Module *M) { | |||
295 | for (Module::global_iterator I = M->global_begin(), E = M->global_end(); | |||
296 | I != E; ++I) | |||
297 | if (!I->hasName()) | |||
298 | I->setName("anon_global"); | |||
299 | for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) | |||
300 | if (!I->hasName()) | |||
301 | I->setName("anon_fn"); | |||
302 | } | |||
303 | ||||
304 | /// Given a reduced list of functions that still exposed the bug, check to see | |||
305 | /// if we can extract the loops in the region without obscuring the bug. If so, | |||
306 | /// it reduces the amount of code identified. | |||
307 | /// | |||
308 | static Expected<bool> | |||
309 | ExtractLoops(BugDriver &BD, | |||
310 | Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, | |||
311 | std::unique_ptr<Module>), | |||
312 | std::vector<Function *> &MiscompiledFunctions) { | |||
313 | bool MadeChange = false; | |||
314 | while (1) { | |||
| ||||
315 | if (BugpointIsInterrupted) | |||
316 | return MadeChange; | |||
317 | ||||
318 | ValueToValueMapTy VMap; | |||
319 | std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); | |||
320 | Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize.get(), | |||
321 | MiscompiledFunctions, VMap) | |||
322 | .release(); | |||
323 | std::unique_ptr<Module> ToOptimizeLoopExtracted = | |||
324 | BD.extractLoop(ToOptimize); | |||
325 | if (!ToOptimizeLoopExtracted) { | |||
326 | // If the loop extractor crashed or if there were no extractible loops, | |||
327 | // then this chapter of our odyssey is over with. | |||
328 | delete ToOptimize; | |||
329 | return MadeChange; | |||
330 | } | |||
331 | ||||
332 | errs() << "Extracted a loop from the breaking portion of the program.\n"; | |||
333 | ||||
334 | // Bugpoint is intentionally not very trusting of LLVM transformations. In | |||
335 | // particular, we're not going to assume that the loop extractor works, so | |||
336 | // we're going to test the newly loop extracted program to make sure nothing | |||
337 | // has broken. If something broke, then we'll inform the user and stop | |||
338 | // extraction. | |||
339 | AbstractInterpreter *AI = BD.switchToSafeInterpreter(); | |||
340 | bool Failure; | |||
341 | Expected<std::unique_ptr<Module>> New = testMergedProgram( | |||
342 | BD, *ToOptimizeLoopExtracted, *ToNotOptimize, Failure); | |||
343 | if (Error E = New.takeError()) | |||
344 | return std::move(E); | |||
345 | if (!*New) | |||
346 | return false; | |||
347 | ||||
348 | // Delete the original and set the new program. | |||
349 | Module *Old = BD.swapProgramIn(New->release()); | |||
350 | for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) | |||
351 | MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); | |||
352 | delete Old; | |||
353 | ||||
354 | if (Failure) { | |||
| ||||
355 | BD.switchToInterpreter(AI); | |||
356 | ||||
357 | // Merged program doesn't work anymore! | |||
358 | errs() << " *** ERROR: Loop extraction broke the program. :(" | |||
359 | << " Please report a bug!\n"; | |||
360 | errs() << " Continuing on with un-loop-extracted version.\n"; | |||
361 | ||||
362 | BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc", | |||
363 | ToNotOptimize.get()); | |||
364 | BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc", | |||
365 | ToOptimize); | |||
366 | BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", | |||
367 | ToOptimizeLoopExtracted.get()); | |||
368 | ||||
369 | errs() << "Please submit the " << OutputPrefix | |||
370 | << "-loop-extract-fail-*.bc files.\n"; | |||
371 | delete ToOptimize; | |||
372 | return MadeChange; | |||
373 | } | |||
374 | delete ToOptimize; | |||
375 | BD.switchToInterpreter(AI); | |||
376 | ||||
377 | outs() << " Testing after loop extraction:\n"; | |||
378 | // Clone modules, the tester function will free them. | |||
379 | std::unique_ptr<Module> TOLEBackup = | |||
380 | CloneModule(ToOptimizeLoopExtracted.get(), VMap); | |||
381 | std::unique_ptr<Module> TNOBackup = CloneModule(ToNotOptimize.get(), VMap); | |||
382 | ||||
383 | for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) | |||
384 | MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]); | |||
385 | ||||
386 | Expected<bool> Result = TestFn(BD, std::move(ToOptimizeLoopExtracted), | |||
387 | std::move(ToNotOptimize)); | |||
388 | if (Error E = Result.takeError()) | |||
389 | return std::move(E); | |||
390 | ||||
391 | ToOptimizeLoopExtracted = std::move(TOLEBackup); | |||
392 | ToNotOptimize = std::move(TNOBackup); | |||
393 | ||||
394 | if (!*Result) { | |||
395 | outs() << "*** Loop extraction masked the problem. Undoing.\n"; | |||
396 | // If the program is not still broken, then loop extraction did something | |||
397 | // that masked the error. Stop loop extraction now. | |||
398 | ||||
399 | std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; | |||
400 | for (Function *F : MiscompiledFunctions) { | |||
401 | MisCompFunctions.emplace_back(F->getName(), F->getFunctionType()); | |||
402 | } | |||
403 | ||||
404 | if (Linker::linkModules(*ToNotOptimize, | |||
405 | std::move(ToOptimizeLoopExtracted))) | |||
406 | exit(1); | |||
407 | ||||
408 | MiscompiledFunctions.clear(); | |||
409 | for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { | |||
410 | Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); | |||
411 | ||||
412 | assert(NewF && "Function not found??")(static_cast <bool> (NewF && "Function not found??" ) ? void (0) : __assert_fail ("NewF && \"Function not found??\"" , "/build/llvm-toolchain-snapshot-7~svn325118/tools/bugpoint/Miscompilation.cpp" , 412, __extension__ __PRETTY_FUNCTION__)); | |||
413 | MiscompiledFunctions.push_back(NewF); | |||
414 | } | |||
415 | ||||
416 | BD.setNewProgram(ToNotOptimize.release()); | |||
417 | return MadeChange; | |||
418 | } | |||
419 | ||||
420 | outs() << "*** Loop extraction successful!\n"; | |||
421 | ||||
422 | std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; | |||
423 | for (Module::iterator I = ToOptimizeLoopExtracted->begin(), | |||
424 | E = ToOptimizeLoopExtracted->end(); | |||
425 | I != E; ++I) | |||
426 | if (!I->isDeclaration()) | |||
427 | MisCompFunctions.emplace_back(I->getName(), I->getFunctionType()); | |||
428 | ||||
429 | // Okay, great! Now we know that we extracted a loop and that loop | |||
430 | // extraction both didn't break the program, and didn't mask the problem. | |||
431 | // Replace the current program with the loop extracted version, and try to | |||
432 | // extract another loop. | |||
433 | if (Linker::linkModules(*ToNotOptimize, std::move(ToOptimizeLoopExtracted))) | |||
434 | exit(1); | |||
435 | ||||
436 | // All of the Function*'s in the MiscompiledFunctions list are in the old | |||
437 | // module. Update this list to include all of the functions in the | |||
438 | // optimized and loop extracted module. | |||
439 | MiscompiledFunctions.clear(); | |||
440 | for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { | |||
441 | Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first); | |||
442 | ||||
443 | assert(NewF && "Function not found??")(static_cast <bool> (NewF && "Function not found??" ) ? void (0) : __assert_fail ("NewF && \"Function not found??\"" , "/build/llvm-toolchain-snapshot-7~svn325118/tools/bugpoint/Miscompilation.cpp" , 443, __extension__ __PRETTY_FUNCTION__)); | |||
444 | MiscompiledFunctions.push_back(NewF); | |||
445 | } | |||
446 | ||||
447 | BD.setNewProgram(ToNotOptimize.release()); | |||
448 | MadeChange = true; | |||
449 | } | |||
450 | } | |||
451 | ||||
452 | namespace { | |||
453 | class ReduceMiscompiledBlocks : public ListReducer<BasicBlock *> { | |||
454 | BugDriver &BD; | |||
455 | Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, | |||
456 | std::unique_ptr<Module>); | |||
457 | std::vector<Function *> FunctionsBeingTested; | |||
458 | ||||
459 | public: | |||
460 | ReduceMiscompiledBlocks(BugDriver &bd, | |||
461 | Expected<bool> (*F)(BugDriver &, | |||
462 | std::unique_ptr<Module>, | |||
463 | std::unique_ptr<Module>), | |||
464 | const std::vector<Function *> &Fns) | |||
465 | : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} | |||
466 | ||||
467 | Expected<TestResult> doTest(std::vector<BasicBlock *> &Prefix, | |||
468 | std::vector<BasicBlock *> &Suffix) override { | |||
469 | if (!Suffix.empty()) { | |||
470 | Expected<bool> Ret = TestFuncs(Suffix); | |||
471 | if (Error E = Ret.takeError()) | |||
472 | return std::move(E); | |||
473 | if (*Ret) | |||
474 | return KeepSuffix; | |||
475 | } | |||
476 | if (!Prefix.empty()) { | |||
477 | Expected<bool> Ret = TestFuncs(Prefix); | |||
478 | if (Error E = Ret.takeError()) | |||
479 | return std::move(E); | |||
480 | if (*Ret) | |||
481 | return KeepPrefix; | |||
482 | } | |||
483 | return NoFailure; | |||
484 | } | |||
485 | ||||
486 | Expected<bool> TestFuncs(const std::vector<BasicBlock *> &BBs); | |||
487 | }; | |||
488 | } // end anonymous namespace | |||
489 | ||||
490 | /// TestFuncs - Extract all blocks for the miscompiled functions except for the | |||
491 | /// specified blocks. If the problem still exists, return true. | |||
492 | /// | |||
493 | Expected<bool> | |||
494 | ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs) { | |||
495 | // Test to see if the function is misoptimized if we ONLY run it on the | |||
496 | // functions listed in Funcs. | |||
497 | outs() << "Checking to see if the program is misoptimized when all "; | |||
498 | if (!BBs.empty()) { | |||
499 | outs() << "but these " << BBs.size() << " blocks are extracted: "; | |||
500 | for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) | |||
501 | outs() << BBs[i]->getName() << " "; | |||
502 | if (BBs.size() > 10) | |||
503 | outs() << "..."; | |||
504 | } else { | |||
505 | outs() << "blocks are extracted."; | |||
506 | } | |||
507 | outs() << '\n'; | |||
508 | ||||
509 | // Split the module into the two halves of the program we want. | |||
510 | ValueToValueMapTy VMap; | |||
511 | Module *Clone = CloneModule(BD.getProgram(), VMap).release(); | |||
512 | Module *Orig = BD.swapProgramIn(Clone); | |||
513 | std::vector<Function *> FuncsOnClone; | |||
514 | std::vector<BasicBlock *> BBsOnClone; | |||
515 | for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { | |||
516 | Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); | |||
517 | FuncsOnClone.push_back(F); | |||
518 | } | |||
519 | for (unsigned i = 0, e = BBs.size(); i != e; ++i) { | |||
520 | BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]); | |||
521 | BBsOnClone.push_back(BB); | |||
522 | } | |||
523 | VMap.clear(); | |||
524 | ||||
525 | std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap); | |||
526 | std::unique_ptr<Module> ToOptimize = | |||
527 | SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap); | |||
528 | ||||
529 | // Try the extraction. If it doesn't work, then the block extractor crashed | |||
530 | // or something, in which case bugpoint can't chase down this possibility. | |||
531 | if (std::unique_ptr<Module> New = | |||
532 | BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize.get())) { | |||
533 | Expected<bool> Ret = TestFn(BD, std::move(New), std::move(ToNotOptimize)); | |||
534 | delete BD.swapProgramIn(Orig); | |||
535 | return Ret; | |||
536 | } | |||
537 | delete BD.swapProgramIn(Orig); | |||
538 | return false; | |||
539 | } | |||
540 | ||||
541 | /// Given a reduced list of functions that still expose the bug, extract as many | |||
542 | /// basic blocks from the region as possible without obscuring the bug. | |||
543 | /// | |||
544 | static Expected<bool> | |||
545 | ExtractBlocks(BugDriver &BD, | |||
546 | Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, | |||
547 | std::unique_ptr<Module>), | |||
548 | std::vector<Function *> &MiscompiledFunctions) { | |||
549 | if (BugpointIsInterrupted) | |||
550 | return false; | |||
551 | ||||
552 | std::vector<BasicBlock *> Blocks; | |||
553 | for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) | |||
554 | for (BasicBlock &BB : *MiscompiledFunctions[i]) | |||
555 | Blocks.push_back(&BB); | |||
556 | ||||
557 | // Use the list reducer to identify blocks that can be extracted without | |||
558 | // obscuring the bug. The Blocks list will end up containing blocks that must | |||
559 | // be retained from the original program. | |||
560 | unsigned OldSize = Blocks.size(); | |||
561 | ||||
562 | // Check to see if all blocks are extractible first. | |||
563 | Expected<bool> Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) | |||
564 | .TestFuncs(std::vector<BasicBlock *>()); | |||
565 | if (Error E = Ret.takeError()) | |||
566 | return std::move(E); | |||
567 | if (*Ret) { | |||
568 | Blocks.clear(); | |||
569 | } else { | |||
570 | Expected<bool> Ret = | |||
571 | ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) | |||
572 | .reduceList(Blocks); | |||
573 | if (Error E = Ret.takeError()) | |||
574 | return std::move(E); | |||
575 | if (Blocks.size() == OldSize) | |||
576 | return false; | |||
577 | } | |||
578 | ||||
579 | ValueToValueMapTy VMap; | |||
580 | Module *ProgClone = CloneModule(BD.getProgram(), VMap).release(); | |||
581 | Module *ToExtract = | |||
582 | SplitFunctionsOutOfModule(ProgClone, MiscompiledFunctions, VMap) | |||
583 | .release(); | |||
584 | std::unique_ptr<Module> Extracted = | |||
585 | BD.extractMappedBlocksFromModule(Blocks, ToExtract); | |||
586 | if (!Extracted) { | |||
587 | // Weird, extraction should have worked. | |||
588 | errs() << "Nondeterministic problem extracting blocks??\n"; | |||
589 | delete ProgClone; | |||
590 | delete ToExtract; | |||
591 | return false; | |||
592 | } | |||
593 | ||||
594 | // Otherwise, block extraction succeeded. Link the two program fragments back | |||
595 | // together. | |||
596 | delete ToExtract; | |||
597 | ||||
598 | std::vector<std::pair<std::string, FunctionType *>> MisCompFunctions; | |||
599 | for (Module::iterator I = Extracted->begin(), E = Extracted->end(); I != E; | |||
600 | ++I) | |||
601 | if (!I->isDeclaration()) | |||
602 | MisCompFunctions.emplace_back(I->getName(), I->getFunctionType()); | |||
603 | ||||
604 | if (Linker::linkModules(*ProgClone, std::move(Extracted))) | |||
605 | exit(1); | |||
606 | ||||
607 | // Set the new program and delete the old one. | |||
608 | BD.setNewProgram(ProgClone); | |||
609 | ||||
610 | // Update the list of miscompiled functions. | |||
611 | MiscompiledFunctions.clear(); | |||
612 | ||||
613 | for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { | |||
614 | Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first); | |||
615 | assert(NewF && "Function not found??")(static_cast <bool> (NewF && "Function not found??" ) ? void (0) : __assert_fail ("NewF && \"Function not found??\"" , "/build/llvm-toolchain-snapshot-7~svn325118/tools/bugpoint/Miscompilation.cpp" , 615, __extension__ __PRETTY_FUNCTION__)); | |||
616 | MiscompiledFunctions.push_back(NewF); | |||
617 | } | |||
618 | ||||
619 | return true; | |||
620 | } | |||
621 | ||||
622 | /// This is a generic driver to narrow down miscompilations, either in an | |||
623 | /// optimization or a code generator. | |||
624 | /// | |||
625 | static Expected<std::vector<Function *>> DebugAMiscompilation( | |||
626 | BugDriver &BD, | |||
627 | Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>, | |||
628 | std::unique_ptr<Module>)) { | |||
629 | // Okay, now that we have reduced the list of passes which are causing the | |||
630 | // failure, see if we can pin down which functions are being | |||
631 | // miscompiled... first build a list of all of the non-external functions in | |||
632 | // the program. | |||
633 | std::vector<Function *> MiscompiledFunctions; | |||
634 | Module *Prog = BD.getProgram(); | |||
635 | for (Function &F : *Prog) | |||
636 | if (!F.isDeclaration()) | |||
637 | MiscompiledFunctions.push_back(&F); | |||
638 | ||||
639 | // Do the reduction... | |||
640 | if (!BugpointIsInterrupted) { | |||
641 | Expected<bool> Ret = ReduceMiscompilingFunctions(BD, TestFn) | |||
642 | .reduceList(MiscompiledFunctions); | |||
643 | if (Error E = Ret.takeError()) { | |||
644 | errs() << "\n***Cannot reduce functions: "; | |||
645 | return std::move(E); | |||
646 | } | |||
647 | } | |||
648 | outs() << "\n*** The following function" | |||
649 | << (MiscompiledFunctions.size() == 1 ? " is" : "s are") | |||
650 | << " being miscompiled: "; | |||
651 | PrintFunctionList(MiscompiledFunctions); | |||
652 | outs() << '\n'; | |||
653 | ||||
654 | // See if we can rip any loops out of the miscompiled functions and still | |||
655 | // trigger the problem. | |||
656 | ||||
657 | if (!BugpointIsInterrupted && !DisableLoopExtraction) { | |||
658 | Expected<bool> Ret = ExtractLoops(BD, TestFn, MiscompiledFunctions); | |||
659 | if (Error E = Ret.takeError()) | |||
660 | return std::move(E); | |||
661 | if (*Ret) { | |||
662 | // Okay, we extracted some loops and the problem still appears. See if | |||
663 | // we can eliminate some of the created functions from being candidates. | |||
664 | DisambiguateGlobalSymbols(BD.getProgram()); | |||
665 | ||||
666 | // Do the reduction... | |||
667 | if (!BugpointIsInterrupted) | |||
668 | Ret = ReduceMiscompilingFunctions(BD, TestFn) | |||
669 | .reduceList(MiscompiledFunctions); | |||
670 | if (Error E = Ret.takeError()) | |||
671 | return std::move(E); | |||
672 | ||||
673 | outs() << "\n*** The following function" | |||
674 | << (MiscompiledFunctions.size() == 1 ? " is" : "s are") | |||
675 | << " being miscompiled: "; | |||
676 | PrintFunctionList(MiscompiledFunctions); | |||
677 | outs() << '\n'; | |||
678 | } | |||
679 | } | |||
680 | ||||
681 | if (!BugpointIsInterrupted && !DisableBlockExtraction) { | |||
682 | Expected<bool> Ret = ExtractBlocks(BD, TestFn, MiscompiledFunctions); | |||
683 | if (Error E = Ret.takeError()) | |||
684 | return std::move(E); | |||
685 | if (*Ret) { | |||
686 | // Okay, we extracted some blocks and the problem still appears. See if | |||
687 | // we can eliminate some of the created functions from being candidates. | |||
688 | DisambiguateGlobalSymbols(BD.getProgram()); | |||
689 | ||||
690 | // Do the reduction... | |||
691 | Ret = ReduceMiscompilingFunctions(BD, TestFn) | |||
692 | .reduceList(MiscompiledFunctions); | |||
693 | if (Error E = Ret.takeError()) | |||
694 | return std::move(E); | |||
695 | ||||
696 | outs() << "\n*** The following function" | |||
697 | << (MiscompiledFunctions.size() == 1 ? " is" : "s are") | |||
698 | << " being miscompiled: "; | |||
699 | PrintFunctionList(MiscompiledFunctions); | |||
700 | outs() << '\n'; | |||
701 | } | |||
702 | } | |||
703 | ||||
704 | return MiscompiledFunctions; | |||
705 | } | |||
706 | ||||
707 | /// This is the predicate function used to check to see if the "Test" portion of | |||
708 | /// the program is misoptimized. If so, return true. In any case, both module | |||
709 | /// arguments are deleted. | |||
710 | /// | |||
711 | static Expected<bool> TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test, | |||
712 | std::unique_ptr<Module> Safe) { | |||
713 | // Run the optimization passes on ToOptimize, producing a transformed version | |||
714 | // of the functions being tested. | |||
715 | outs() << " Optimizing functions being tested: "; | |||
716 | std::unique_ptr<Module> Optimized = | |||
717 | BD.runPassesOn(Test.get(), BD.getPassesToRun()); | |||
718 | if (!Optimized) { | |||
719 | errs() << " Error running this sequence of passes" | |||
720 | << " on the input program!\n"; | |||
721 | delete BD.swapProgramIn(Test.get()); | |||
722 | BD.EmitProgressBitcode(Test.get(), "pass-error", false); | |||
723 | if (Error E = BD.debugOptimizerCrash()) | |||
724 | return std::move(E); | |||
725 | return false; | |||
726 | } | |||
727 | outs() << "done.\n"; | |||
728 | ||||
729 | outs() << " Checking to see if the merged program executes correctly: "; | |||
730 | bool Broken; | |||
731 | auto Result = testMergedProgram(BD, *Optimized, *Safe, Broken); | |||
732 | if (Error E = Result.takeError()) | |||
733 | return std::move(E); | |||
734 | if (auto New = std::move(*Result)) { | |||
735 | outs() << (Broken ? " nope.\n" : " yup.\n"); | |||
736 | // Delete the original and set the new program. | |||
737 | delete BD.swapProgramIn(New.release()); | |||
738 | } | |||
739 | return Broken; | |||
740 | } | |||
741 | ||||
742 | /// debugMiscompilation - This method is used when the passes selected are not | |||
743 | /// crashing, but the generated output is semantically different from the | |||
744 | /// input. | |||
745 | /// | |||
746 | Error BugDriver::debugMiscompilation() { | |||
747 | // Make sure something was miscompiled... | |||
748 | if (!BugpointIsInterrupted) { | |||
749 | Expected<bool> Result = | |||
750 | ReduceMiscompilingPasses(*this).reduceList(PassesToRun); | |||
751 | if (Error E = Result.takeError()) | |||
752 | return E; | |||
753 | if (!*Result) | |||
754 | return make_error<StringError>( | |||
755 | "*** Optimized program matches reference output! No problem" | |||
756 | " detected...\nbugpoint can't help you with your problem!\n", | |||
757 | inconvertibleErrorCode()); | |||
758 | } | |||
759 | ||||
760 | outs() << "\n*** Found miscompiling pass" | |||
761 | << (getPassesToRun().size() == 1 ? "" : "es") << ": " | |||
762 | << getPassesString(getPassesToRun()) << '\n'; | |||
763 | EmitProgressBitcode(Program, "passinput"); | |||
764 | ||||
765 | Expected<std::vector<Function *>> MiscompiledFunctions = | |||
766 | DebugAMiscompilation(*this, TestOptimizer); | |||
767 | if (Error E = MiscompiledFunctions.takeError()) | |||
768 | return E; | |||
769 | ||||
770 | // Output a bunch of bitcode files for the user... | |||
771 | outs() << "Outputting reduced bitcode files which expose the problem:\n"; | |||
772 | ValueToValueMapTy VMap; | |||
773 | Module *ToNotOptimize = CloneModule(getProgram(), VMap).release(); | |||
774 | Module *ToOptimize = | |||
775 | SplitFunctionsOutOfModule(ToNotOptimize, *MiscompiledFunctions, VMap) | |||
776 | .release(); | |||
777 | ||||
778 | outs() << " Non-optimized portion: "; | |||
779 | EmitProgressBitcode(ToNotOptimize, "tonotoptimize", true); | |||
780 | delete ToNotOptimize; // Delete hacked module. | |||
781 | ||||
782 | outs() << " Portion that is input to optimizer: "; | |||
783 | EmitProgressBitcode(ToOptimize, "tooptimize"); | |||
784 | delete ToOptimize; // Delete hacked module. | |||
785 | ||||
786 | return Error::success(); | |||
787 | } | |||
788 | ||||
789 | /// Get the specified modules ready for code generator testing. | |||
790 | /// | |||
791 | static void CleanupAndPrepareModules(BugDriver &BD, | |||
792 | std::unique_ptr<Module> &Test, | |||
793 | Module *Safe) { | |||
794 | // Clean up the modules, removing extra cruft that we don't need anymore... | |||
795 | Test = BD.performFinalCleanups(Test.get()); | |||
796 | ||||
797 | // If we are executing the JIT, we have several nasty issues to take care of. | |||
798 | if (!BD.isExecutingJIT()) | |||
799 | return; | |||
800 | ||||
801 | // First, if the main function is in the Safe module, we must add a stub to | |||
802 | // the Test module to call into it. Thus, we create a new function `main' | |||
803 | // which just calls the old one. | |||
804 | if (Function *oldMain = Safe->getFunction("main")) | |||
805 | if (!oldMain->isDeclaration()) { | |||
806 | // Rename it | |||
807 | oldMain->setName("llvm_bugpoint_old_main"); | |||
808 | // Create a NEW `main' function with same type in the test module. | |||
809 | Function *newMain = | |||
810 | Function::Create(oldMain->getFunctionType(), | |||
811 | GlobalValue::ExternalLinkage, "main", Test.get()); | |||
812 | // Create an `oldmain' prototype in the test module, which will | |||
813 | // corresponds to the real main function in the same module. | |||
814 | Function *oldMainProto = Function::Create(oldMain->getFunctionType(), | |||
815 | GlobalValue::ExternalLinkage, | |||
816 | oldMain->getName(), Test.get()); | |||
817 | // Set up and remember the argument list for the main function. | |||
818 | std::vector<Value *> args; | |||
819 | for (Function::arg_iterator I = newMain->arg_begin(), | |||
820 | E = newMain->arg_end(), | |||
821 | OI = oldMain->arg_begin(); | |||
822 | I != E; ++I, ++OI) { | |||
823 | I->setName(OI->getName()); // Copy argument names from oldMain | |||
824 | args.push_back(&*I); | |||
825 | } | |||
826 | ||||
827 | // Call the old main function and return its result | |||
828 | BasicBlock *BB = BasicBlock::Create(Safe->getContext(), "entry", newMain); | |||
829 | CallInst *call = CallInst::Create(oldMainProto, args, "", BB); | |||
830 | ||||
831 | // If the type of old function wasn't void, return value of call | |||
832 | ReturnInst::Create(Safe->getContext(), call, BB); | |||
833 | } | |||
834 | ||||
835 | // The second nasty issue we must deal with in the JIT is that the Safe | |||
836 | // module cannot directly reference any functions defined in the test | |||
837 | // module. Instead, we use a JIT API call to dynamically resolve the | |||
838 | // symbol. | |||
839 | ||||
840 | // Add the resolver to the Safe module. | |||
841 | // Prototype: void *getPointerToNamedFunction(const char* Name) | |||
842 | Constant *resolverFunc = Safe->getOrInsertFunction( | |||
843 | "getPointerToNamedFunction", Type::getInt8PtrTy(Safe->getContext()), | |||
844 | Type::getInt8PtrTy(Safe->getContext())); | |||
845 | ||||
846 | // Use the function we just added to get addresses of functions we need. | |||
847 | for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { | |||
848 | if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc && | |||
849 | !F->isIntrinsic() /* ignore intrinsics */) { | |||
850 | Function *TestFn = Test->getFunction(F->getName()); | |||
851 | ||||
852 | // Don't forward functions which are external in the test module too. | |||
853 | if (TestFn && !TestFn->isDeclaration()) { | |||
854 | // 1. Add a string constant with its name to the global file | |||
855 | Constant *InitArray = | |||
856 | ConstantDataArray::getString(F->getContext(), F->getName()); | |||
857 | GlobalVariable *funcName = new GlobalVariable( | |||
858 | *Safe, InitArray->getType(), true /*isConstant*/, | |||
859 | GlobalValue::InternalLinkage, InitArray, F->getName() + "_name"); | |||
860 | ||||
861 | // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an | |||
862 | // sbyte* so it matches the signature of the resolver function. | |||
863 | ||||
864 | // GetElementPtr *funcName, ulong 0, ulong 0 | |||
865 | std::vector<Constant *> GEPargs( | |||
866 | 2, Constant::getNullValue(Type::getInt32Ty(F->getContext()))); | |||
867 | Value *GEP = ConstantExpr::getGetElementPtr(InitArray->getType(), | |||
868 | funcName, GEPargs); | |||
869 | std::vector<Value *> ResolverArgs; | |||
870 | ResolverArgs.push_back(GEP); | |||
871 | ||||
872 | // Rewrite uses of F in global initializers, etc. to uses of a wrapper | |||
873 | // function that dynamically resolves the calls to F via our JIT API | |||
874 | if (!F->use_empty()) { | |||
875 | // Create a new global to hold the cached function pointer. | |||
876 | Constant *NullPtr = ConstantPointerNull::get(F->getType()); | |||
877 | GlobalVariable *Cache = new GlobalVariable( | |||
878 | *F->getParent(), F->getType(), false, | |||
879 | GlobalValue::InternalLinkage, NullPtr, F->getName() + ".fpcache"); | |||
880 | ||||
881 | // Construct a new stub function that will re-route calls to F | |||
882 | FunctionType *FuncTy = F->getFunctionType(); | |||
883 | Function *FuncWrapper = | |||
884 | Function::Create(FuncTy, GlobalValue::InternalLinkage, | |||
885 | F->getName() + "_wrapper", F->getParent()); | |||
886 | BasicBlock *EntryBB = | |||
887 | BasicBlock::Create(F->getContext(), "entry", FuncWrapper); | |||
888 | BasicBlock *DoCallBB = | |||
889 | BasicBlock::Create(F->getContext(), "usecache", FuncWrapper); | |||
890 | BasicBlock *LookupBB = | |||
891 | BasicBlock::Create(F->getContext(), "lookupfp", FuncWrapper); | |||
892 | ||||
893 | // Check to see if we already looked up the value. | |||
894 | Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB); | |||
895 | Value *IsNull = new ICmpInst(*EntryBB, ICmpInst::ICMP_EQ, CachedVal, | |||
896 | NullPtr, "isNull"); | |||
897 | BranchInst::Create(LookupBB, DoCallBB, IsNull, EntryBB); | |||
898 | ||||
899 | // Resolve the call to function F via the JIT API: | |||
900 | // | |||
901 | // call resolver(GetElementPtr...) | |||
902 | CallInst *Resolver = CallInst::Create(resolverFunc, ResolverArgs, | |||
903 | "resolver", LookupBB); | |||
904 | ||||
905 | // Cast the result from the resolver to correctly-typed function. | |||
906 | CastInst *CastedResolver = new BitCastInst( | |||
907 | Resolver, PointerType::getUnqual(F->getFunctionType()), | |||
908 | "resolverCast", LookupBB); | |||
909 | ||||
910 | // Save the value in our cache. | |||
911 | new StoreInst(CastedResolver, Cache, LookupBB); | |||
912 | BranchInst::Create(DoCallBB, LookupBB); | |||
913 | ||||
914 | PHINode *FuncPtr = | |||
915 | PHINode::Create(NullPtr->getType(), 2, "fp", DoCallBB); | |||
916 | FuncPtr->addIncoming(CastedResolver, LookupBB); | |||
917 | FuncPtr->addIncoming(CachedVal, EntryBB); | |||
918 | ||||
919 | // Save the argument list. | |||
920 | std::vector<Value *> Args; | |||
921 | for (Argument &A : FuncWrapper->args()) | |||
922 | Args.push_back(&A); | |||
923 | ||||
924 | // Pass on the arguments to the real function, return its result | |||
925 | if (F->getReturnType()->isVoidTy()) { | |||
926 | CallInst::Create(FuncPtr, Args, "", DoCallBB); | |||
927 | ReturnInst::Create(F->getContext(), DoCallBB); | |||
928 | } else { | |||
929 | CallInst *Call = | |||
930 | CallInst::Create(FuncPtr, Args, "retval", DoCallBB); | |||
931 | ReturnInst::Create(F->getContext(), Call, DoCallBB); | |||
932 | } | |||
933 | ||||
934 | // Use the wrapper function instead of the old function | |||
935 | F->replaceAllUsesWith(FuncWrapper); | |||
936 | } | |||
937 | } | |||
938 | } | |||
939 | } | |||
940 | ||||
941 | if (verifyModule(*Test) || verifyModule(*Safe)) { | |||
942 | errs() << "Bugpoint has a bug, which corrupted a module!!\n"; | |||
943 | abort(); | |||
944 | } | |||
945 | } | |||
946 | ||||
947 | /// This is the predicate function used to check to see if the "Test" portion of | |||
948 | /// the program is miscompiled by the code generator under test. If so, return | |||
949 | /// true. In any case, both module arguments are deleted. | |||
950 | /// | |||
951 | static Expected<bool> TestCodeGenerator(BugDriver &BD, | |||
952 | std::unique_ptr<Module> Test, | |||
953 | std::unique_ptr<Module> Safe) { | |||
954 | CleanupAndPrepareModules(BD, Test, Safe.get()); | |||
955 | ||||
956 | SmallString<128> TestModuleBC; | |||
957 | int TestModuleFD; | |||
958 | std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", | |||
959 | TestModuleFD, TestModuleBC); | |||
960 | if (EC) { | |||
961 | errs() << BD.getToolName() | |||
962 | << "Error making unique filename: " << EC.message() << "\n"; | |||
963 | exit(1); | |||
964 | } | |||
965 | if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test.get())) { | |||
966 | errs() << "Error writing bitcode to `" << TestModuleBC.str() | |||
967 | << "'\nExiting."; | |||
968 | exit(1); | |||
969 | } | |||
970 | ||||
971 | FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps); | |||
972 | ||||
973 | // Make the shared library | |||
974 | SmallString<128> SafeModuleBC; | |||
975 | int SafeModuleFD; | |||
976 | EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, | |||
977 | SafeModuleBC); | |||
978 | if (EC) { | |||
979 | errs() << BD.getToolName() | |||
980 | << "Error making unique filename: " << EC.message() << "\n"; | |||
981 | exit(1); | |||
982 | } | |||
983 | ||||
984 | if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe.get())) { | |||
985 | errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; | |||
986 | exit(1); | |||
987 | } | |||
988 | ||||
989 | FileRemover SafeModuleBCRemover(SafeModuleBC.str(), !SaveTemps); | |||
990 | ||||
991 | Expected<std::string> SharedObject = | |||
992 | BD.compileSharedObject(SafeModuleBC.str()); | |||
993 | if (Error E = SharedObject.takeError()) | |||
994 | return std::move(E); | |||
995 | ||||
996 | FileRemover SharedObjectRemover(*SharedObject, !SaveTemps); | |||
997 | ||||
998 | // Run the code generator on the `Test' code, loading the shared library. | |||
999 | // The function returns whether or not the new output differs from reference. | |||
1000 | Expected<bool> Result = | |||
1001 | BD.diffProgram(BD.getProgram(), TestModuleBC.str(), *SharedObject, false); | |||
1002 | if (Error E = Result.takeError()) | |||
1003 | return std::move(E); | |||
1004 | ||||
1005 | if (*Result) | |||
1006 | errs() << ": still failing!\n"; | |||
1007 | else | |||
1008 | errs() << ": didn't fail.\n"; | |||
1009 | ||||
1010 | return Result; | |||
1011 | } | |||
1012 | ||||
1013 | /// debugCodeGenerator - debug errors in LLC, LLI, or CBE. | |||
1014 | /// | |||
1015 | Error BugDriver::debugCodeGenerator() { | |||
1016 | if ((void *)SafeInterpreter == (void *)Interpreter) { | |||
1017 | Expected<std::string> Result = | |||
1018 | executeProgramSafely(Program, "bugpoint.safe.out"); | |||
1019 | if (Result) { | |||
1020 | outs() << "\n*** The \"safe\" i.e. 'known good' backend cannot match " | |||
1021 | << "the reference diff. This may be due to a\n front-end " | |||
1022 | << "bug or a bug in the original program, but this can also " | |||
1023 | << "happen if bugpoint isn't running the program with the " | |||
1024 | << "right flags or input.\n I left the result of executing " | |||
1025 | << "the program with the \"safe\" backend in this file for " | |||
1026 | << "you: '" << *Result << "'.\n"; | |||
1027 | } | |||
1028 | return Error::success(); | |||
1029 | } | |||
1030 | ||||
1031 | DisambiguateGlobalSymbols(Program); | |||
1032 | ||||
1033 | Expected<std::vector<Function *>> Funcs = | |||
1034 | DebugAMiscompilation(*this, TestCodeGenerator); | |||
1035 | if (Error E = Funcs.takeError()) | |||
1036 | return E; | |||
1037 | ||||
1038 | // Split the module into the two halves of the program we want. | |||
1039 | ValueToValueMapTy VMap; | |||
1040 | std::unique_ptr<Module> ToNotCodeGen = CloneModule(getProgram(), VMap); | |||
1041 | std::unique_ptr<Module> ToCodeGen = | |||
1042 | SplitFunctionsOutOfModule(ToNotCodeGen.get(), *Funcs, VMap); | |||
1043 | ||||
1044 | // Condition the modules | |||
1045 | CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen.get()); | |||
1046 | ||||
1047 | SmallString<128> TestModuleBC; | |||
1048 | int TestModuleFD; | |||
1049 | std::error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc", | |||
1050 | TestModuleFD, TestModuleBC); | |||
1051 | if (EC) { | |||
1052 | errs() << getToolName() << "Error making unique filename: " << EC.message() | |||
1053 | << "\n"; | |||
1054 | exit(1); | |||
1055 | } | |||
1056 | ||||
1057 | if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen.get())) { | |||
1058 | errs() << "Error writing bitcode to `" << TestModuleBC << "'\nExiting."; | |||
1059 | exit(1); | |||
1060 | } | |||
1061 | ||||
1062 | // Make the shared library | |||
1063 | SmallString<128> SafeModuleBC; | |||
1064 | int SafeModuleFD; | |||
1065 | EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD, | |||
1066 | SafeModuleBC); | |||
1067 | if (EC) { | |||
1068 | errs() << getToolName() << "Error making unique filename: " << EC.message() | |||
1069 | << "\n"; | |||
1070 | exit(1); | |||
1071 | } | |||
1072 | ||||
1073 | if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, | |||
1074 | ToNotCodeGen.get())) { | |||
1075 | errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; | |||
1076 | exit(1); | |||
1077 | } | |||
1078 | Expected<std::string> SharedObject = compileSharedObject(SafeModuleBC.str()); | |||
1079 | if (Error E = SharedObject.takeError()) | |||
1080 | return E; | |||
1081 | ||||
1082 | outs() << "You can reproduce the problem with the command line: \n"; | |||
1083 | if (isExecutingJIT()) { | |||
1084 | outs() << " lli -load " << *SharedObject << " " << TestModuleBC; | |||
1085 | } else { | |||
1086 | outs() << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; | |||
1087 | outs() << " cc " << *SharedObject << " " << TestModuleBC.str() << ".s -o " | |||
1088 | << TestModuleBC << ".exe\n"; | |||
1089 | outs() << " ./" << TestModuleBC << ".exe"; | |||
1090 | } | |||
1091 | for (unsigned i = 0, e = InputArgv.size(); i != e; ++i) | |||
1092 | outs() << " " << InputArgv[i]; | |||
1093 | outs() << '\n'; | |||
1094 | outs() << "The shared object was created with:\n llc -march=c " | |||
1095 | << SafeModuleBC.str() << " -o temporary.c\n" | |||
1096 | << " cc -xc temporary.c -O2 -o " << *SharedObject; | |||
1097 | if (TargetTriple.getArch() == Triple::sparc) | |||
1098 | outs() << " -G"; // Compile a shared library, `-G' for Sparc | |||
1099 | else | |||
1100 | outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others | |||
1101 | ||||
1102 | outs() << " -fno-strict-aliasing\n"; | |||
1103 | ||||
1104 | return Error::success(); | |||
1105 | } |
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 */ |
1 | // <tuple> -*- C++ -*- |
2 | |
3 | // Copyright (C) 2007-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 include/tuple |
26 | * This is a Standard C++ Library header. |
27 | */ |
28 | |
29 | #ifndef _GLIBCXX_TUPLE1 |
30 | #define _GLIBCXX_TUPLE1 1 |
31 | |
32 | #pragma GCC system_header |
33 | |
34 | #if __cplusplus201103L < 201103L |
35 | # include <bits/c++0x_warning.h> |
36 | #else |
37 | |
38 | #include <utility> |
39 | #include <array> |
40 | #include <bits/uses_allocator.h> |
41 | #include <bits/invoke.h> |
42 | |
43 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
44 | { |
45 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
46 | |
47 | /** |
48 | * @addtogroup utilities |
49 | * @{ |
50 | */ |
51 | |
52 | template<typename... _Elements> |
53 | class tuple; |
54 | |
55 | template<typename _Tp> |
56 | struct __is_empty_non_tuple : is_empty<_Tp> { }; |
57 | |
58 | // Using EBO for elements that are tuples causes ambiguous base errors. |
59 | template<typename _El0, typename... _El> |
60 | struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; |
61 | |
62 | // Use the Empty Base-class Optimization for empty, non-final types. |
63 | template<typename _Tp> |
64 | using __empty_not_final |
65 | = typename conditional<__is_final(_Tp), false_type, |
66 | __is_empty_non_tuple<_Tp>>::type; |
67 | |
68 | template<std::size_t _Idx, typename _Head, |
69 | bool = __empty_not_final<_Head>::value> |
70 | struct _Head_base; |
71 | |
72 | template<std::size_t _Idx, typename _Head> |
73 | struct _Head_base<_Idx, _Head, true> |
74 | : public _Head |
75 | { |
76 | constexpr _Head_base() |
77 | : _Head() { } |
78 | |
79 | constexpr _Head_base(const _Head& __h) |
80 | : _Head(__h) { } |
81 | |
82 | constexpr _Head_base(const _Head_base&) = default; |
83 | constexpr _Head_base(_Head_base&&) = default; |
84 | |
85 | template<typename _UHead> |
86 | constexpr _Head_base(_UHead&& __h) |
87 | : _Head(std::forward<_UHead>(__h)) { } |
88 | |
89 | _Head_base(allocator_arg_t, __uses_alloc0) |
90 | : _Head() { } |
91 | |
92 | template<typename _Alloc> |
93 | _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) |
94 | : _Head(allocator_arg, *__a._M_a) { } |
95 | |
96 | template<typename _Alloc> |
97 | _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) |
98 | : _Head(*__a._M_a) { } |
99 | |
100 | template<typename _UHead> |
101 | _Head_base(__uses_alloc0, _UHead&& __uhead) |
102 | : _Head(std::forward<_UHead>(__uhead)) { } |
103 | |
104 | template<typename _Alloc, typename _UHead> |
105 | _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) |
106 | : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } |
107 | |
108 | template<typename _Alloc, typename _UHead> |
109 | _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) |
110 | : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } |
111 | |
112 | static constexpr _Head& |
113 | _M_head(_Head_base& __b) noexcept { return __b; } |
114 | |
115 | static constexpr const _Head& |
116 | _M_head(const _Head_base& __b) noexcept { return __b; } |
117 | }; |
118 | |
119 | template<std::size_t _Idx, typename _Head> |
120 | struct _Head_base<_Idx, _Head, false> |
121 | { |
122 | constexpr _Head_base() |
123 | : _M_head_impl() { } |
124 | |
125 | constexpr _Head_base(const _Head& __h) |
126 | : _M_head_impl(__h) { } |
127 | |
128 | constexpr _Head_base(const _Head_base&) = default; |
129 | constexpr _Head_base(_Head_base&&) = default; |
130 | |
131 | template<typename _UHead> |
132 | constexpr _Head_base(_UHead&& __h) |
133 | : _M_head_impl(std::forward<_UHead>(__h)) { } |
134 | |
135 | _Head_base(allocator_arg_t, __uses_alloc0) |
136 | : _M_head_impl() { } |
137 | |
138 | template<typename _Alloc> |
139 | _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) |
140 | : _M_head_impl(allocator_arg, *__a._M_a) { } |
141 | |
142 | template<typename _Alloc> |
143 | _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) |
144 | : _M_head_impl(*__a._M_a) { } |
145 | |
146 | template<typename _UHead> |
147 | _Head_base(__uses_alloc0, _UHead&& __uhead) |
148 | : _M_head_impl(std::forward<_UHead>(__uhead)) { } |
149 | |
150 | template<typename _Alloc, typename _UHead> |
151 | _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) |
152 | : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) |
153 | { } |
154 | |
155 | template<typename _Alloc, typename _UHead> |
156 | _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) |
157 | : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } |
158 | |
159 | static constexpr _Head& |
160 | _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } |
161 | |
162 | static constexpr const _Head& |
163 | _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } |
164 | |
165 | _Head _M_head_impl; |
166 | }; |
167 | |
168 | /** |
169 | * Contains the actual implementation of the @c tuple template, stored |
170 | * as a recursive inheritance hierarchy from the first element (most |
171 | * derived class) to the last (least derived class). The @c Idx |
172 | * parameter gives the 0-based index of the element stored at this |
173 | * point in the hierarchy; we use it to implement a constant-time |
174 | * get() operation. |
175 | */ |
176 | template<std::size_t _Idx, typename... _Elements> |
177 | struct _Tuple_impl; |
178 | |
179 | /** |
180 | * Recursive tuple implementation. Here we store the @c Head element |
181 | * and derive from a @c Tuple_impl containing the remaining elements |
182 | * (which contains the @c Tail). |
183 | */ |
184 | template<std::size_t _Idx, typename _Head, typename... _Tail> |
185 | struct _Tuple_impl<_Idx, _Head, _Tail...> |
186 | : public _Tuple_impl<_Idx + 1, _Tail...>, |
187 | private _Head_base<_Idx, _Head> |
188 | { |
189 | template<std::size_t, typename...> friend class _Tuple_impl; |
190 | |
191 | typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; |
192 | typedef _Head_base<_Idx, _Head> _Base; |
193 | |
194 | static constexpr _Head& |
195 | _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
196 | |
197 | static constexpr const _Head& |
198 | _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
199 | |
200 | static constexpr _Inherited& |
201 | _M_tail(_Tuple_impl& __t) noexcept { return __t; } |
202 | |
203 | static constexpr const _Inherited& |
204 | _M_tail(const _Tuple_impl& __t) noexcept { return __t; } |
205 | |
206 | constexpr _Tuple_impl() |
207 | : _Inherited(), _Base() { } |
208 | |
209 | explicit |
210 | constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) |
211 | : _Inherited(__tail...), _Base(__head) { } |
212 | |
213 | template<typename _UHead, typename... _UTail, typename = typename |
214 | enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> |
215 | explicit |
216 | constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) |
217 | : _Inherited(std::forward<_UTail>(__tail)...), |
218 | _Base(std::forward<_UHead>(__head)) { } |
219 | |
220 | constexpr _Tuple_impl(const _Tuple_impl&) = default; |
221 | |
222 | constexpr |
223 | _Tuple_impl(_Tuple_impl&& __in) |
224 | noexcept(__and_<is_nothrow_move_constructible<_Head>, |
225 | is_nothrow_move_constructible<_Inherited>>::value) |
226 | : _Inherited(std::move(_M_tail(__in))), |
227 | _Base(std::forward<_Head>(_M_head(__in))) { } |
228 | |
229 | template<typename... _UElements> |
230 | constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) |
231 | : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), |
232 | _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } |
233 | |
234 | template<typename _UHead, typename... _UTails> |
235 | constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) |
236 | : _Inherited(std::move |
237 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), |
238 | _Base(std::forward<_UHead> |
239 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } |
240 | |
241 | template<typename _Alloc> |
242 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) |
243 | : _Inherited(__tag, __a), |
244 | _Base(__tag, __use_alloc<_Head>(__a)) { } |
245 | |
246 | template<typename _Alloc> |
247 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
248 | const _Head& __head, const _Tail&... __tail) |
249 | : _Inherited(__tag, __a, __tail...), |
250 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } |
251 | |
252 | template<typename _Alloc, typename _UHead, typename... _UTail, |
253 | typename = typename enable_if<sizeof...(_Tail) |
254 | == sizeof...(_UTail)>::type> |
255 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
256 | _UHead&& __head, _UTail&&... __tail) |
257 | : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), |
258 | _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
259 | std::forward<_UHead>(__head)) { } |
260 | |
261 | template<typename _Alloc> |
262 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
263 | const _Tuple_impl& __in) |
264 | : _Inherited(__tag, __a, _M_tail(__in)), |
265 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } |
266 | |
267 | template<typename _Alloc> |
268 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
269 | _Tuple_impl&& __in) |
270 | : _Inherited(__tag, __a, std::move(_M_tail(__in))), |
271 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
272 | std::forward<_Head>(_M_head(__in))) { } |
273 | |
274 | template<typename _Alloc, typename... _UElements> |
275 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
276 | const _Tuple_impl<_Idx, _UElements...>& __in) |
277 | : _Inherited(__tag, __a, |
278 | _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), |
279 | _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
280 | _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } |
281 | |
282 | template<typename _Alloc, typename _UHead, typename... _UTails> |
283 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
284 | _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) |
285 | : _Inherited(__tag, __a, std::move |
286 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), |
287 | _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
288 | std::forward<_UHead> |
289 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } |
290 | |
291 | _Tuple_impl& |
292 | operator=(const _Tuple_impl& __in) |
293 | { |
294 | _M_head(*this) = _M_head(__in); |
295 | _M_tail(*this) = _M_tail(__in); |
296 | return *this; |
297 | } |
298 | |
299 | _Tuple_impl& |
300 | operator=(_Tuple_impl&& __in) |
301 | noexcept(__and_<is_nothrow_move_assignable<_Head>, |
302 | is_nothrow_move_assignable<_Inherited>>::value) |
303 | { |
304 | _M_head(*this) = std::forward<_Head>(_M_head(__in)); |
305 | _M_tail(*this) = std::move(_M_tail(__in)); |
306 | return *this; |
307 | } |
308 | |
309 | template<typename... _UElements> |
310 | _Tuple_impl& |
311 | operator=(const _Tuple_impl<_Idx, _UElements...>& __in) |
312 | { |
313 | _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); |
314 | _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); |
315 | return *this; |
316 | } |
317 | |
318 | template<typename _UHead, typename... _UTails> |
319 | _Tuple_impl& |
320 | operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) |
321 | { |
322 | _M_head(*this) = std::forward<_UHead> |
323 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); |
324 | _M_tail(*this) = std::move |
325 | (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); |
326 | return *this; |
327 | } |
328 | |
329 | protected: |
330 | void |
331 | _M_swap(_Tuple_impl& __in) |
332 | noexcept(__is_nothrow_swappable<_Head>::value |
333 | && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) |
334 | { |
335 | using std::swap; |
336 | swap(_M_head(*this), _M_head(__in)); |
337 | _Inherited::_M_swap(_M_tail(__in)); |
338 | } |
339 | }; |
340 | |
341 | // Basis case of inheritance recursion. |
342 | template<std::size_t _Idx, typename _Head> |
343 | struct _Tuple_impl<_Idx, _Head> |
344 | : private _Head_base<_Idx, _Head> |
345 | { |
346 | template<std::size_t, typename...> friend class _Tuple_impl; |
347 | |
348 | typedef _Head_base<_Idx, _Head> _Base; |
349 | |
350 | static constexpr _Head& |
351 | _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
352 | |
353 | static constexpr const _Head& |
354 | _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } |
355 | |
356 | constexpr _Tuple_impl() |
357 | : _Base() { } |
358 | |
359 | explicit |
360 | constexpr _Tuple_impl(const _Head& __head) |
361 | : _Base(__head) { } |
362 | |
363 | template<typename _UHead> |
364 | explicit |
365 | constexpr _Tuple_impl(_UHead&& __head) |
366 | : _Base(std::forward<_UHead>(__head)) { } |
367 | |
368 | constexpr _Tuple_impl(const _Tuple_impl&) = default; |
369 | |
370 | constexpr |
371 | _Tuple_impl(_Tuple_impl&& __in) |
372 | noexcept(is_nothrow_move_constructible<_Head>::value) |
373 | : _Base(std::forward<_Head>(_M_head(__in))) { } |
374 | |
375 | template<typename _UHead> |
376 | constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) |
377 | : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } |
378 | |
379 | template<typename _UHead> |
380 | constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) |
381 | : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) |
382 | { } |
383 | |
384 | template<typename _Alloc> |
385 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) |
386 | : _Base(__tag, __use_alloc<_Head>(__a)) { } |
387 | |
388 | template<typename _Alloc> |
389 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
390 | const _Head& __head) |
391 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } |
392 | |
393 | template<typename _Alloc, typename _UHead> |
394 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
395 | _UHead&& __head) |
396 | : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
397 | std::forward<_UHead>(__head)) { } |
398 | |
399 | template<typename _Alloc> |
400 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
401 | const _Tuple_impl& __in) |
402 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } |
403 | |
404 | template<typename _Alloc> |
405 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
406 | _Tuple_impl&& __in) |
407 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
408 | std::forward<_Head>(_M_head(__in))) { } |
409 | |
410 | template<typename _Alloc, typename _UHead> |
411 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
412 | const _Tuple_impl<_Idx, _UHead>& __in) |
413 | : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), |
414 | _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } |
415 | |
416 | template<typename _Alloc, typename _UHead> |
417 | _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, |
418 | _Tuple_impl<_Idx, _UHead>&& __in) |
419 | : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), |
420 | std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) |
421 | { } |
422 | |
423 | _Tuple_impl& |
424 | operator=(const _Tuple_impl& __in) |
425 | { |
426 | _M_head(*this) = _M_head(__in); |
427 | return *this; |
428 | } |
429 | |
430 | _Tuple_impl& |
431 | operator=(_Tuple_impl&& __in) |
432 | noexcept(is_nothrow_move_assignable<_Head>::value) |
433 | { |
434 | _M_head(*this) = std::forward<_Head>(_M_head(__in)); |
435 | return *this; |
436 | } |
437 | |
438 | template<typename _UHead> |
439 | _Tuple_impl& |
440 | operator=(const _Tuple_impl<_Idx, _UHead>& __in) |
441 | { |
442 | _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); |
443 | return *this; |
444 | } |
445 | |
446 | template<typename _UHead> |
447 | _Tuple_impl& |
448 | operator=(_Tuple_impl<_Idx, _UHead>&& __in) |
449 | { |
450 | _M_head(*this) |
451 | = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); |
452 | return *this; |
453 | } |
454 | |
455 | protected: |
456 | void |
457 | _M_swap(_Tuple_impl& __in) |
458 | noexcept(__is_nothrow_swappable<_Head>::value) |
459 | { |
460 | using std::swap; |
461 | swap(_M_head(*this), _M_head(__in)); |
462 | } |
463 | }; |
464 | |
465 | // Concept utility functions, reused in conditionally-explicit |
466 | // constructors. |
467 | template<bool, typename... _Elements> |
468 | struct _TC |
469 | { |
470 | template<typename... _UElements> |
471 | static constexpr bool _ConstructibleTuple() |
472 | { |
473 | return __and_<is_constructible<_Elements, const _UElements&>...>::value; |
474 | } |
475 | |
476 | template<typename... _UElements> |
477 | static constexpr bool _ImplicitlyConvertibleTuple() |
478 | { |
479 | return __and_<is_convertible<const _UElements&, _Elements>...>::value; |
480 | } |
481 | |
482 | template<typename... _UElements> |
483 | static constexpr bool _MoveConstructibleTuple() |
484 | { |
485 | return __and_<is_constructible<_Elements, _UElements&&>...>::value; |
486 | } |
487 | |
488 | template<typename... _UElements> |
489 | static constexpr bool _ImplicitlyMoveConvertibleTuple() |
490 | { |
491 | return __and_<is_convertible<_UElements&&, _Elements>...>::value; |
492 | } |
493 | |
494 | template<typename _SrcTuple> |
495 | static constexpr bool _NonNestedTuple() |
496 | { |
497 | return __and_<__not_<is_same<tuple<_Elements...>, |
498 | typename remove_cv< |
499 | typename remove_reference<_SrcTuple>::type |
500 | >::type>>, |
501 | __not_<is_convertible<_SrcTuple, _Elements...>>, |
502 | __not_<is_constructible<_Elements..., _SrcTuple>> |
503 | >::value; |
504 | } |
505 | template<typename... _UElements> |
506 | static constexpr bool _NotSameTuple() |
507 | { |
508 | return __not_<is_same<tuple<_Elements...>, |
509 | typename remove_const< |
510 | typename remove_reference<_UElements...>::type |
511 | >::type>>::value; |
512 | } |
513 | }; |
514 | |
515 | template<typename... _Elements> |
516 | struct _TC<false, _Elements...> |
517 | { |
518 | template<typename... _UElements> |
519 | static constexpr bool _ConstructibleTuple() |
520 | { |
521 | return false; |
522 | } |
523 | |
524 | template<typename... _UElements> |
525 | static constexpr bool _ImplicitlyConvertibleTuple() |
526 | { |
527 | return false; |
528 | } |
529 | |
530 | template<typename... _UElements> |
531 | static constexpr bool _MoveConstructibleTuple() |
532 | { |
533 | return false; |
534 | } |
535 | |
536 | template<typename... _UElements> |
537 | static constexpr bool _ImplicitlyMoveConvertibleTuple() |
538 | { |
539 | return false; |
540 | } |
541 | |
542 | template<typename... _UElements> |
543 | static constexpr bool _NonNestedTuple() |
544 | { |
545 | return true; |
546 | } |
547 | template<typename... _UElements> |
548 | static constexpr bool _NotSameTuple() |
549 | { |
550 | return true; |
551 | } |
552 | }; |
553 | |
554 | /// Primary class template, tuple |
555 | template<typename... _Elements> |
556 | class tuple : public _Tuple_impl<0, _Elements...> |
557 | { |
558 | typedef _Tuple_impl<0, _Elements...> _Inherited; |
559 | |
560 | // Used for constraining the default constructor so |
561 | // that it becomes dependent on the constraints. |
562 | template<typename _Dummy> |
563 | struct _TC2 |
564 | { |
565 | static constexpr bool _DefaultConstructibleTuple() |
566 | { |
567 | return __and_<is_default_constructible<_Elements>...>::value; |
568 | } |
569 | static constexpr bool _ImplicitlyDefaultConstructibleTuple() |
570 | { |
571 | return __and_<__is_implicitly_default_constructible<_Elements>...> |
572 | ::value; |
573 | } |
574 | }; |
575 | |
576 | public: |
577 | template<typename _Dummy = void, |
578 | typename enable_if<_TC2<_Dummy>:: |
579 | _ImplicitlyDefaultConstructibleTuple(), |
580 | bool>::type = true> |
581 | constexpr tuple() |
582 | : _Inherited() { } |
583 | |
584 | template<typename _Dummy = void, |
585 | typename enable_if<_TC2<_Dummy>:: |
586 | _DefaultConstructibleTuple() |
587 | && |
588 | !_TC2<_Dummy>:: |
589 | _ImplicitlyDefaultConstructibleTuple(), |
590 | bool>::type = false> |
591 | explicit constexpr tuple() |
592 | : _Inherited() { } |
593 | |
594 | // Shortcut for the cases where constructors taking _Elements... |
595 | // need to be constrained. |
596 | template<typename _Dummy> using _TCC = |
597 | _TC<is_same<_Dummy, void>::value, |
598 | _Elements...>; |
599 | |
600 | template<typename _Dummy = void, |
601 | typename enable_if< |
602 | _TCC<_Dummy>::template |
603 | _ConstructibleTuple<_Elements...>() |
604 | && _TCC<_Dummy>::template |
605 | _ImplicitlyConvertibleTuple<_Elements...>() |
606 | && (sizeof...(_Elements) >= 1), |
607 | bool>::type=true> |
608 | constexpr tuple(const _Elements&... __elements) |
609 | : _Inherited(__elements...) { } |
610 | |
611 | template<typename _Dummy = void, |
612 | typename enable_if< |
613 | _TCC<_Dummy>::template |
614 | _ConstructibleTuple<_Elements...>() |
615 | && !_TCC<_Dummy>::template |
616 | _ImplicitlyConvertibleTuple<_Elements...>() |
617 | && (sizeof...(_Elements) >= 1), |
618 | bool>::type=false> |
619 | explicit constexpr tuple(const _Elements&... __elements) |
620 | : _Inherited(__elements...) { } |
621 | |
622 | // Shortcut for the cases where constructors taking _UElements... |
623 | // need to be constrained. |
624 | template<typename... _UElements> using _TMC = |
625 | _TC<(sizeof...(_Elements) == sizeof...(_UElements)) |
626 | && (_TC<(sizeof...(_UElements)==1), _Elements...>:: |
627 | template _NotSameTuple<_UElements...>()), |
628 | _Elements...>; |
629 | |
630 | // Shortcut for the cases where constructors taking tuple<_UElements...> |
631 | // need to be constrained. |
632 | template<typename... _UElements> using _TMCT = |
633 | _TC<(sizeof...(_Elements) == sizeof...(_UElements)) |
634 | && !is_same<tuple<_Elements...>, |
635 | tuple<_UElements...>>::value, |
636 | _Elements...>; |
637 | |
638 | template<typename... _UElements, typename |
639 | enable_if< |
640 | _TMC<_UElements...>::template |
641 | _MoveConstructibleTuple<_UElements...>() |
642 | && _TMC<_UElements...>::template |
643 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
644 | && (sizeof...(_Elements) >= 1), |
645 | bool>::type=true> |
646 | constexpr tuple(_UElements&&... __elements) |
647 | : _Inherited(std::forward<_UElements>(__elements)...) { } |
648 | |
649 | template<typename... _UElements, typename |
650 | enable_if< |
651 | _TMC<_UElements...>::template |
652 | _MoveConstructibleTuple<_UElements...>() |
653 | && !_TMC<_UElements...>::template |
654 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
655 | && (sizeof...(_Elements) >= 1), |
656 | bool>::type=false> |
657 | explicit constexpr tuple(_UElements&&... __elements) |
658 | : _Inherited(std::forward<_UElements>(__elements)...) { } |
659 | |
660 | constexpr tuple(const tuple&) = default; |
661 | |
662 | constexpr tuple(tuple&&) = default; |
663 | |
664 | // Shortcut for the cases where constructors taking tuples |
665 | // must avoid creating temporaries. |
666 | template<typename _Dummy> using _TNTC = |
667 | _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1, |
668 | _Elements...>; |
669 | |
670 | template<typename... _UElements, typename _Dummy = void, typename |
671 | enable_if<_TMCT<_UElements...>::template |
672 | _ConstructibleTuple<_UElements...>() |
673 | && _TMCT<_UElements...>::template |
674 | _ImplicitlyConvertibleTuple<_UElements...>() |
675 | && _TNTC<_Dummy>::template |
676 | _NonNestedTuple<const tuple<_UElements...>&>(), |
677 | bool>::type=true> |
678 | constexpr tuple(const tuple<_UElements...>& __in) |
679 | : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
680 | { } |
681 | |
682 | template<typename... _UElements, typename _Dummy = void, typename |
683 | enable_if<_TMCT<_UElements...>::template |
684 | _ConstructibleTuple<_UElements...>() |
685 | && !_TMCT<_UElements...>::template |
686 | _ImplicitlyConvertibleTuple<_UElements...>() |
687 | && _TNTC<_Dummy>::template |
688 | _NonNestedTuple<const tuple<_UElements...>&>(), |
689 | bool>::type=false> |
690 | explicit constexpr tuple(const tuple<_UElements...>& __in) |
691 | : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
692 | { } |
693 | |
694 | template<typename... _UElements, typename _Dummy = void, typename |
695 | enable_if<_TMCT<_UElements...>::template |
696 | _MoveConstructibleTuple<_UElements...>() |
697 | && _TMCT<_UElements...>::template |
698 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
699 | && _TNTC<_Dummy>::template |
700 | _NonNestedTuple<tuple<_UElements...>&&>(), |
701 | bool>::type=true> |
702 | constexpr tuple(tuple<_UElements...>&& __in) |
703 | : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } |
704 | |
705 | template<typename... _UElements, typename _Dummy = void, typename |
706 | enable_if<_TMCT<_UElements...>::template |
707 | _MoveConstructibleTuple<_UElements...>() |
708 | && !_TMCT<_UElements...>::template |
709 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
710 | && _TNTC<_Dummy>::template |
711 | _NonNestedTuple<tuple<_UElements...>&&>(), |
712 | bool>::type=false> |
713 | explicit constexpr tuple(tuple<_UElements...>&& __in) |
714 | : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } |
715 | |
716 | // Allocator-extended constructors. |
717 | |
718 | template<typename _Alloc> |
719 | tuple(allocator_arg_t __tag, const _Alloc& __a) |
720 | : _Inherited(__tag, __a) { } |
721 | |
722 | template<typename _Alloc, typename _Dummy = void, |
723 | typename enable_if< |
724 | _TCC<_Dummy>::template |
725 | _ConstructibleTuple<_Elements...>() |
726 | && _TCC<_Dummy>::template |
727 | _ImplicitlyConvertibleTuple<_Elements...>(), |
728 | bool>::type=true> |
729 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
730 | const _Elements&... __elements) |
731 | : _Inherited(__tag, __a, __elements...) { } |
732 | |
733 | template<typename _Alloc, typename _Dummy = void, |
734 | typename enable_if< |
735 | _TCC<_Dummy>::template |
736 | _ConstructibleTuple<_Elements...>() |
737 | && !_TCC<_Dummy>::template |
738 | _ImplicitlyConvertibleTuple<_Elements...>(), |
739 | bool>::type=false> |
740 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
741 | const _Elements&... __elements) |
742 | : _Inherited(__tag, __a, __elements...) { } |
743 | |
744 | template<typename _Alloc, typename... _UElements, typename |
745 | enable_if<_TMC<_UElements...>::template |
746 | _MoveConstructibleTuple<_UElements...>() |
747 | && _TMC<_UElements...>::template |
748 | _ImplicitlyMoveConvertibleTuple<_UElements...>(), |
749 | bool>::type=true> |
750 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
751 | _UElements&&... __elements) |
752 | : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) |
753 | { } |
754 | |
755 | template<typename _Alloc, typename... _UElements, typename |
756 | enable_if<_TMC<_UElements...>::template |
757 | _MoveConstructibleTuple<_UElements...>() |
758 | && !_TMC<_UElements...>::template |
759 | _ImplicitlyMoveConvertibleTuple<_UElements...>(), |
760 | bool>::type=false> |
761 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
762 | _UElements&&... __elements) |
763 | : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) |
764 | { } |
765 | |
766 | template<typename _Alloc> |
767 | tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) |
768 | : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } |
769 | |
770 | template<typename _Alloc> |
771 | tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) |
772 | : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } |
773 | |
774 | template<typename _Alloc, typename _Dummy = void, |
775 | typename... _UElements, typename |
776 | enable_if<_TMCT<_UElements...>::template |
777 | _ConstructibleTuple<_UElements...>() |
778 | && _TMCT<_UElements...>::template |
779 | _ImplicitlyConvertibleTuple<_UElements...>() |
780 | && _TNTC<_Dummy>::template |
781 | _NonNestedTuple<tuple<_UElements...>&&>(), |
782 | bool>::type=true> |
783 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
784 | const tuple<_UElements...>& __in) |
785 | : _Inherited(__tag, __a, |
786 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
787 | { } |
788 | |
789 | template<typename _Alloc, typename _Dummy = void, |
790 | typename... _UElements, typename |
791 | enable_if<_TMCT<_UElements...>::template |
792 | _ConstructibleTuple<_UElements...>() |
793 | && !_TMCT<_UElements...>::template |
794 | _ImplicitlyConvertibleTuple<_UElements...>() |
795 | && _TNTC<_Dummy>::template |
796 | _NonNestedTuple<tuple<_UElements...>&&>(), |
797 | bool>::type=false> |
798 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
799 | const tuple<_UElements...>& __in) |
800 | : _Inherited(__tag, __a, |
801 | static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
802 | { } |
803 | |
804 | template<typename _Alloc, typename _Dummy = void, |
805 | typename... _UElements, typename |
806 | enable_if<_TMCT<_UElements...>::template |
807 | _MoveConstructibleTuple<_UElements...>() |
808 | && _TMCT<_UElements...>::template |
809 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
810 | && _TNTC<_Dummy>::template |
811 | _NonNestedTuple<tuple<_UElements...>&&>(), |
812 | bool>::type=true> |
813 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
814 | tuple<_UElements...>&& __in) |
815 | : _Inherited(__tag, __a, |
816 | static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) |
817 | { } |
818 | |
819 | template<typename _Alloc, typename _Dummy = void, |
820 | typename... _UElements, typename |
821 | enable_if<_TMCT<_UElements...>::template |
822 | _MoveConstructibleTuple<_UElements...>() |
823 | && !_TMCT<_UElements...>::template |
824 | _ImplicitlyMoveConvertibleTuple<_UElements...>() |
825 | && _TNTC<_Dummy>::template |
826 | _NonNestedTuple<tuple<_UElements...>&&>(), |
827 | bool>::type=false> |
828 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
829 | tuple<_UElements...>&& __in) |
830 | : _Inherited(__tag, __a, |
831 | static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) |
832 | { } |
833 | |
834 | tuple& |
835 | operator=(const tuple& __in) |
836 | { |
837 | static_cast<_Inherited&>(*this) = __in; |
838 | return *this; |
839 | } |
840 | |
841 | tuple& |
842 | operator=(tuple&& __in) |
843 | noexcept(is_nothrow_move_assignable<_Inherited>::value) |
844 | { |
845 | static_cast<_Inherited&>(*this) = std::move(__in); |
846 | return *this; |
847 | } |
848 | |
849 | template<typename... _UElements> |
850 | typename |
851 | enable_if<sizeof...(_UElements) |
852 | == sizeof...(_Elements), tuple&>::type |
853 | operator=(const tuple<_UElements...>& __in) |
854 | { |
855 | static_cast<_Inherited&>(*this) = __in; |
856 | return *this; |
857 | } |
858 | |
859 | template<typename... _UElements> |
860 | typename |
861 | enable_if<sizeof...(_UElements) |
862 | == sizeof...(_Elements), tuple&>::type |
863 | operator=(tuple<_UElements...>&& __in) |
864 | { |
865 | static_cast<_Inherited&>(*this) = std::move(__in); |
866 | return *this; |
867 | } |
868 | |
869 | void |
870 | swap(tuple& __in) |
871 | noexcept(noexcept(__in._M_swap(__in))) |
872 | { _Inherited::_M_swap(__in); } |
873 | }; |
874 | |
875 | #if __cpp_deduction_guides >= 201606 |
876 | template<typename... _UTypes> |
877 | tuple(_UTypes...) -> tuple<_UTypes...>; |
878 | template<typename _T1, typename _T2> |
879 | tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; |
880 | template<typename _Alloc, typename... _UTypes> |
881 | tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; |
882 | template<typename _Alloc, typename _T1, typename _T2> |
883 | tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; |
884 | template<typename _Alloc, typename... _UTypes> |
885 | tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; |
886 | #endif |
887 | |
888 | // Explicit specialization, zero-element tuple. |
889 | template<> |
890 | class tuple<> |
891 | { |
892 | public: |
893 | void swap(tuple&) noexcept { /* no-op */ } |
894 | // We need the default since we're going to define no-op |
895 | // allocator constructors. |
896 | tuple() = default; |
897 | // No-op allocator constructors. |
898 | template<typename _Alloc> |
899 | tuple(allocator_arg_t, const _Alloc&) { } |
900 | template<typename _Alloc> |
901 | tuple(allocator_arg_t, const _Alloc&, const tuple&) { } |
902 | }; |
903 | |
904 | /// Partial specialization, 2-element tuple. |
905 | /// Includes construction and assignment from a pair. |
906 | template<typename _T1, typename _T2> |
907 | class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> |
908 | { |
909 | typedef _Tuple_impl<0, _T1, _T2> _Inherited; |
910 | |
911 | public: |
912 | template <typename _U1 = _T1, |
913 | typename _U2 = _T2, |
914 | typename enable_if<__and_< |
915 | __is_implicitly_default_constructible<_U1>, |
916 | __is_implicitly_default_constructible<_U2>> |
917 | ::value, bool>::type = true> |
918 | |
919 | constexpr tuple() |
920 | : _Inherited() { } |
921 | |
922 | template <typename _U1 = _T1, |
923 | typename _U2 = _T2, |
924 | typename enable_if< |
925 | __and_< |
926 | is_default_constructible<_U1>, |
927 | is_default_constructible<_U2>, |
928 | __not_< |
929 | __and_<__is_implicitly_default_constructible<_U1>, |
930 | __is_implicitly_default_constructible<_U2>>>> |
931 | ::value, bool>::type = false> |
932 | |
933 | explicit constexpr tuple() |
934 | : _Inherited() { } |
935 | |
936 | // Shortcut for the cases where constructors taking _T1, _T2 |
937 | // need to be constrained. |
938 | template<typename _Dummy> using _TCC = |
939 | _TC<is_same<_Dummy, void>::value, _T1, _T2>; |
940 | |
941 | template<typename _Dummy = void, typename |
942 | enable_if<_TCC<_Dummy>::template |
943 | _ConstructibleTuple<_T1, _T2>() |
944 | && _TCC<_Dummy>::template |
945 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
946 | bool>::type = true> |
947 | constexpr tuple(const _T1& __a1, const _T2& __a2) |
948 | : _Inherited(__a1, __a2) { } |
949 | |
950 | template<typename _Dummy = void, typename |
951 | enable_if<_TCC<_Dummy>::template |
952 | _ConstructibleTuple<_T1, _T2>() |
953 | && !_TCC<_Dummy>::template |
954 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
955 | bool>::type = false> |
956 | explicit constexpr tuple(const _T1& __a1, const _T2& __a2) |
957 | : _Inherited(__a1, __a2) { } |
958 | |
959 | // Shortcut for the cases where constructors taking _U1, _U2 |
960 | // need to be constrained. |
961 | using _TMC = _TC<true, _T1, _T2>; |
962 | |
963 | template<typename _U1, typename _U2, typename |
964 | enable_if<_TMC::template |
965 | _MoveConstructibleTuple<_U1, _U2>() |
966 | && _TMC::template |
967 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>() |
968 | && !is_same<typename decay<_U1>::type, |
969 | allocator_arg_t>::value, |
970 | bool>::type = true> |
971 | constexpr tuple(_U1&& __a1, _U2&& __a2) |
972 | : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } |
973 | |
974 | template<typename _U1, typename _U2, typename |
975 | enable_if<_TMC::template |
976 | _MoveConstructibleTuple<_U1, _U2>() |
977 | && !_TMC::template |
978 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>() |
979 | && !is_same<typename decay<_U1>::type, |
980 | allocator_arg_t>::value, |
981 | bool>::type = false> |
982 | explicit constexpr tuple(_U1&& __a1, _U2&& __a2) |
983 | : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } |
984 | |
985 | constexpr tuple(const tuple&) = default; |
986 | |
987 | constexpr tuple(tuple&&) = default; |
988 | |
989 | template<typename _U1, typename _U2, typename |
990 | enable_if<_TMC::template |
991 | _ConstructibleTuple<_U1, _U2>() |
992 | && _TMC::template |
993 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
994 | bool>::type = true> |
995 | constexpr tuple(const tuple<_U1, _U2>& __in) |
996 | : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } |
997 | |
998 | template<typename _U1, typename _U2, typename |
999 | enable_if<_TMC::template |
1000 | _ConstructibleTuple<_U1, _U2>() |
1001 | && !_TMC::template |
1002 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1003 | bool>::type = false> |
1004 | explicit constexpr tuple(const tuple<_U1, _U2>& __in) |
1005 | : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } |
1006 | |
1007 | template<typename _U1, typename _U2, typename |
1008 | enable_if<_TMC::template |
1009 | _MoveConstructibleTuple<_U1, _U2>() |
1010 | && _TMC::template |
1011 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1012 | bool>::type = true> |
1013 | constexpr tuple(tuple<_U1, _U2>&& __in) |
1014 | : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } |
1015 | |
1016 | template<typename _U1, typename _U2, typename |
1017 | enable_if<_TMC::template |
1018 | _MoveConstructibleTuple<_U1, _U2>() |
1019 | && !_TMC::template |
1020 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1021 | bool>::type = false> |
1022 | explicit constexpr tuple(tuple<_U1, _U2>&& __in) |
1023 | : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } |
1024 | |
1025 | template<typename _U1, typename _U2, typename |
1026 | enable_if<_TMC::template |
1027 | _ConstructibleTuple<_U1, _U2>() |
1028 | && _TMC::template |
1029 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1030 | bool>::type = true> |
1031 | constexpr tuple(const pair<_U1, _U2>& __in) |
1032 | : _Inherited(__in.first, __in.second) { } |
1033 | |
1034 | template<typename _U1, typename _U2, typename |
1035 | enable_if<_TMC::template |
1036 | _ConstructibleTuple<_U1, _U2>() |
1037 | && !_TMC::template |
1038 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1039 | bool>::type = false> |
1040 | explicit constexpr tuple(const pair<_U1, _U2>& __in) |
1041 | : _Inherited(__in.first, __in.second) { } |
1042 | |
1043 | template<typename _U1, typename _U2, typename |
1044 | enable_if<_TMC::template |
1045 | _MoveConstructibleTuple<_U1, _U2>() |
1046 | && _TMC::template |
1047 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1048 | bool>::type = true> |
1049 | constexpr tuple(pair<_U1, _U2>&& __in) |
1050 | : _Inherited(std::forward<_U1>(__in.first), |
1051 | std::forward<_U2>(__in.second)) { } |
1052 | |
1053 | template<typename _U1, typename _U2, typename |
1054 | enable_if<_TMC::template |
1055 | _MoveConstructibleTuple<_U1, _U2>() |
1056 | && !_TMC::template |
1057 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1058 | bool>::type = false> |
1059 | explicit constexpr tuple(pair<_U1, _U2>&& __in) |
1060 | : _Inherited(std::forward<_U1>(__in.first), |
1061 | std::forward<_U2>(__in.second)) { } |
1062 | |
1063 | // Allocator-extended constructors. |
1064 | |
1065 | template<typename _Alloc> |
1066 | tuple(allocator_arg_t __tag, const _Alloc& __a) |
1067 | : _Inherited(__tag, __a) { } |
1068 | |
1069 | template<typename _Alloc, typename _Dummy = void, |
1070 | typename enable_if< |
1071 | _TCC<_Dummy>::template |
1072 | _ConstructibleTuple<_T1, _T2>() |
1073 | && _TCC<_Dummy>::template |
1074 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
1075 | bool>::type=true> |
1076 | |
1077 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
1078 | const _T1& __a1, const _T2& __a2) |
1079 | : _Inherited(__tag, __a, __a1, __a2) { } |
1080 | |
1081 | template<typename _Alloc, typename _Dummy = void, |
1082 | typename enable_if< |
1083 | _TCC<_Dummy>::template |
1084 | _ConstructibleTuple<_T1, _T2>() |
1085 | && !_TCC<_Dummy>::template |
1086 | _ImplicitlyConvertibleTuple<_T1, _T2>(), |
1087 | bool>::type=false> |
1088 | |
1089 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1090 | const _T1& __a1, const _T2& __a2) |
1091 | : _Inherited(__tag, __a, __a1, __a2) { } |
1092 | |
1093 | template<typename _Alloc, typename _U1, typename _U2, typename |
1094 | enable_if<_TMC::template |
1095 | _MoveConstructibleTuple<_U1, _U2>() |
1096 | && _TMC::template |
1097 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1098 | bool>::type = true> |
1099 | tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) |
1100 | : _Inherited(__tag, __a, std::forward<_U1>(__a1), |
1101 | std::forward<_U2>(__a2)) { } |
1102 | |
1103 | template<typename _Alloc, typename _U1, typename _U2, typename |
1104 | enable_if<_TMC::template |
1105 | _MoveConstructibleTuple<_U1, _U2>() |
1106 | && !_TMC::template |
1107 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1108 | bool>::type = false> |
1109 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1110 | _U1&& __a1, _U2&& __a2) |
1111 | : _Inherited(__tag, __a, std::forward<_U1>(__a1), |
1112 | std::forward<_U2>(__a2)) { } |
1113 | |
1114 | template<typename _Alloc> |
1115 | tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) |
1116 | : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } |
1117 | |
1118 | template<typename _Alloc> |
1119 | tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) |
1120 | : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } |
1121 | |
1122 | template<typename _Alloc, typename _U1, typename _U2, typename |
1123 | enable_if<_TMC::template |
1124 | _ConstructibleTuple<_U1, _U2>() |
1125 | && _TMC::template |
1126 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1127 | bool>::type = true> |
1128 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
1129 | const tuple<_U1, _U2>& __in) |
1130 | : _Inherited(__tag, __a, |
1131 | static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) |
1132 | { } |
1133 | |
1134 | template<typename _Alloc, typename _U1, typename _U2, typename |
1135 | enable_if<_TMC::template |
1136 | _ConstructibleTuple<_U1, _U2>() |
1137 | && !_TMC::template |
1138 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1139 | bool>::type = false> |
1140 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1141 | const tuple<_U1, _U2>& __in) |
1142 | : _Inherited(__tag, __a, |
1143 | static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) |
1144 | { } |
1145 | |
1146 | template<typename _Alloc, typename _U1, typename _U2, typename |
1147 | enable_if<_TMC::template |
1148 | _MoveConstructibleTuple<_U1, _U2>() |
1149 | && _TMC::template |
1150 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1151 | bool>::type = true> |
1152 | tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) |
1153 | : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) |
1154 | { } |
1155 | |
1156 | template<typename _Alloc, typename _U1, typename _U2, typename |
1157 | enable_if<_TMC::template |
1158 | _MoveConstructibleTuple<_U1, _U2>() |
1159 | && !_TMC::template |
1160 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1161 | bool>::type = false> |
1162 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1163 | tuple<_U1, _U2>&& __in) |
1164 | : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) |
1165 | { } |
1166 | |
1167 | template<typename _Alloc, typename _U1, typename _U2, typename |
1168 | enable_if<_TMC::template |
1169 | _ConstructibleTuple<_U1, _U2>() |
1170 | && _TMC::template |
1171 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1172 | bool>::type = true> |
1173 | tuple(allocator_arg_t __tag, const _Alloc& __a, |
1174 | const pair<_U1, _U2>& __in) |
1175 | : _Inherited(__tag, __a, __in.first, __in.second) { } |
1176 | |
1177 | template<typename _Alloc, typename _U1, typename _U2, typename |
1178 | enable_if<_TMC::template |
1179 | _ConstructibleTuple<_U1, _U2>() |
1180 | && !_TMC::template |
1181 | _ImplicitlyConvertibleTuple<_U1, _U2>(), |
1182 | bool>::type = false> |
1183 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1184 | const pair<_U1, _U2>& __in) |
1185 | : _Inherited(__tag, __a, __in.first, __in.second) { } |
1186 | |
1187 | template<typename _Alloc, typename _U1, typename _U2, typename |
1188 | enable_if<_TMC::template |
1189 | _MoveConstructibleTuple<_U1, _U2>() |
1190 | && _TMC::template |
1191 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1192 | bool>::type = true> |
1193 | tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) |
1194 | : _Inherited(__tag, __a, std::forward<_U1>(__in.first), |
1195 | std::forward<_U2>(__in.second)) { } |
1196 | |
1197 | template<typename _Alloc, typename _U1, typename _U2, typename |
1198 | enable_if<_TMC::template |
1199 | _MoveConstructibleTuple<_U1, _U2>() |
1200 | && !_TMC::template |
1201 | _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), |
1202 | bool>::type = false> |
1203 | explicit tuple(allocator_arg_t __tag, const _Alloc& __a, |
1204 | pair<_U1, _U2>&& __in) |
1205 | : _Inherited(__tag, __a, std::forward<_U1>(__in.first), |
1206 | std::forward<_U2>(__in.second)) { } |
1207 | |
1208 | tuple& |
1209 | operator=(const tuple& __in) |
1210 | { |
1211 | static_cast<_Inherited&>(*this) = __in; |
1212 | return *this; |
1213 | } |
1214 | |
1215 | tuple& |
1216 | operator=(tuple&& __in) |
1217 | noexcept(is_nothrow_move_assignable<_Inherited>::value) |
1218 | { |
1219 | static_cast<_Inherited&>(*this) = std::move(__in); |
1220 | return *this; |
1221 | } |
1222 | |
1223 | template<typename _U1, typename _U2> |
1224 | tuple& |
1225 | operator=(const tuple<_U1, _U2>& __in) |
1226 | { |
1227 | static_cast<_Inherited&>(*this) = __in; |
1228 | return *this; |
1229 | } |
1230 | |
1231 | template<typename _U1, typename _U2> |
1232 | tuple& |
1233 | operator=(tuple<_U1, _U2>&& __in) |
1234 | { |
1235 | static_cast<_Inherited&>(*this) = std::move(__in); |
1236 | return *this; |
1237 | } |
1238 | |
1239 | template<typename _U1, typename _U2> |
1240 | tuple& |
1241 | operator=(const pair<_U1, _U2>& __in) |
1242 | { |
1243 | this->_M_head(*this) = __in.first; |
1244 | this->_M_tail(*this)._M_head(*this) = __in.second; |
1245 | return *this; |
1246 | } |
1247 | |
1248 | template<typename _U1, typename _U2> |
1249 | tuple& |
1250 | operator=(pair<_U1, _U2>&& __in) |
1251 | { |
1252 | this->_M_head(*this) = std::forward<_U1>(__in.first); |
1253 | this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); |
1254 | return *this; |
1255 | } |
1256 | |
1257 | void |
1258 | swap(tuple& __in) |
1259 | noexcept(noexcept(__in._M_swap(__in))) |
1260 | { _Inherited::_M_swap(__in); } |
1261 | }; |
1262 | |
1263 | |
1264 | /// class tuple_size |
1265 | template<typename... _Elements> |
1266 | struct tuple_size<tuple<_Elements...>> |
1267 | : public integral_constant<std::size_t, sizeof...(_Elements)> { }; |
1268 | |
1269 | #if __cplusplus201103L > 201402L |
1270 | template <typename _Tp> |
1271 | inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; |
1272 | #endif |
1273 | |
1274 | /** |
1275 | * Recursive case for tuple_element: strip off the first element in |
1276 | * the tuple and retrieve the (i-1)th element of the remaining tuple. |
1277 | */ |
1278 | template<std::size_t __i, typename _Head, typename... _Tail> |
1279 | struct tuple_element<__i, tuple<_Head, _Tail...> > |
1280 | : tuple_element<__i - 1, tuple<_Tail...> > { }; |
1281 | |
1282 | /** |
1283 | * Basis case for tuple_element: The first element is the one we're seeking. |
1284 | */ |
1285 | template<typename _Head, typename... _Tail> |
1286 | struct tuple_element<0, tuple<_Head, _Tail...> > |
1287 | { |
1288 | typedef _Head type; |
1289 | }; |
1290 | |
1291 | /** |
1292 | * Error case for tuple_element: invalid index. |
1293 | */ |
1294 | template<size_t __i> |
1295 | struct tuple_element<__i, tuple<>> |
1296 | { |
1297 | static_assert(__i < tuple_size<tuple<>>::value, |
1298 | "tuple index is in range"); |
1299 | }; |
1300 | |
1301 | template<std::size_t __i, typename _Head, typename... _Tail> |
1302 | constexpr _Head& |
1303 | __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1304 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1305 | |
1306 | template<std::size_t __i, typename _Head, typename... _Tail> |
1307 | constexpr const _Head& |
1308 | __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1309 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1310 | |
1311 | /// Return a reference to the ith element of a tuple. |
1312 | template<std::size_t __i, typename... _Elements> |
1313 | constexpr __tuple_element_t<__i, tuple<_Elements...>>& |
1314 | get(tuple<_Elements...>& __t) noexcept |
1315 | { return std::__get_helper<__i>(__t); } |
1316 | |
1317 | /// Return a const reference to the ith element of a const tuple. |
1318 | template<std::size_t __i, typename... _Elements> |
1319 | constexpr const __tuple_element_t<__i, tuple<_Elements...>>& |
1320 | get(const tuple<_Elements...>& __t) noexcept |
1321 | { return std::__get_helper<__i>(__t); } |
1322 | |
1323 | /// Return an rvalue reference to the ith element of a tuple rvalue. |
1324 | template<std::size_t __i, typename... _Elements> |
1325 | constexpr __tuple_element_t<__i, tuple<_Elements...>>&& |
1326 | get(tuple<_Elements...>&& __t) noexcept |
1327 | { |
1328 | typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; |
1329 | return std::forward<__element_type&&>(std::get<__i>(__t)); |
1330 | } |
1331 | |
1332 | #if __cplusplus201103L > 201103L |
1333 | |
1334 | #define __cpp_lib_tuples_by_type 201304 |
1335 | |
1336 | template<typename _Head, size_t __i, typename... _Tail> |
1337 | constexpr _Head& |
1338 | __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1339 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1340 | |
1341 | template<typename _Head, size_t __i, typename... _Tail> |
1342 | constexpr const _Head& |
1343 | __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept |
1344 | { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } |
1345 | |
1346 | /// Return a reference to the unique element of type _Tp of a tuple. |
1347 | template <typename _Tp, typename... _Types> |
1348 | constexpr _Tp& |
1349 | get(tuple<_Types...>& __t) noexcept |
1350 | { return std::__get_helper2<_Tp>(__t); } |
1351 | |
1352 | /// Return a reference to the unique element of type _Tp of a tuple rvalue. |
1353 | template <typename _Tp, typename... _Types> |
1354 | constexpr _Tp&& |
1355 | get(tuple<_Types...>&& __t) noexcept |
1356 | { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } |
1357 | |
1358 | /// Return a const reference to the unique element of type _Tp of a tuple. |
1359 | template <typename _Tp, typename... _Types> |
1360 | constexpr const _Tp& |
1361 | get(const tuple<_Types...>& __t) noexcept |
1362 | { return std::__get_helper2<_Tp>(__t); } |
1363 | #endif |
1364 | |
1365 | // This class performs the comparison operations on tuples |
1366 | template<typename _Tp, typename _Up, size_t __i, size_t __size> |
1367 | struct __tuple_compare |
1368 | { |
1369 | static constexpr bool |
1370 | __eq(const _Tp& __t, const _Up& __u) |
1371 | { |
1372 | return bool(std::get<__i>(__t) == std::get<__i>(__u)) |
1373 | && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); |
1374 | } |
1375 | |
1376 | static constexpr bool |
1377 | __less(const _Tp& __t, const _Up& __u) |
1378 | { |
1379 | return bool(std::get<__i>(__t) < std::get<__i>(__u)) |
1380 | || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) |
1381 | && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); |
1382 | } |
1383 | }; |
1384 | |
1385 | template<typename _Tp, typename _Up, size_t __size> |
1386 | struct __tuple_compare<_Tp, _Up, __size, __size> |
1387 | { |
1388 | static constexpr bool |
1389 | __eq(const _Tp&, const _Up&) { return true; } |
1390 | |
1391 | static constexpr bool |
1392 | __less(const _Tp&, const _Up&) { return false; } |
1393 | }; |
1394 | |
1395 | template<typename... _TElements, typename... _UElements> |
1396 | constexpr bool |
1397 | operator==(const tuple<_TElements...>& __t, |
1398 | const tuple<_UElements...>& __u) |
1399 | { |
1400 | static_assert(sizeof...(_TElements) == sizeof...(_UElements), |
1401 | "tuple objects can only be compared if they have equal sizes."); |
1402 | using __compare = __tuple_compare<tuple<_TElements...>, |
1403 | tuple<_UElements...>, |
1404 | 0, sizeof...(_TElements)>; |
1405 | return __compare::__eq(__t, __u); |
1406 | } |
1407 | |
1408 | template<typename... _TElements, typename... _UElements> |
1409 | constexpr bool |
1410 | operator<(const tuple<_TElements...>& __t, |
1411 | const tuple<_UElements...>& __u) |
1412 | { |
1413 | static_assert(sizeof...(_TElements) == sizeof...(_UElements), |
1414 | "tuple objects can only be compared if they have equal sizes."); |
1415 | using __compare = __tuple_compare<tuple<_TElements...>, |
1416 | tuple<_UElements...>, |
1417 | 0, sizeof...(_TElements)>; |
1418 | return __compare::__less(__t, __u); |
1419 | } |
1420 | |
1421 | template<typename... _TElements, typename... _UElements> |
1422 | constexpr bool |
1423 | operator!=(const tuple<_TElements...>& __t, |
1424 | const tuple<_UElements...>& __u) |
1425 | { return !(__t == __u); } |
1426 | |
1427 | template<typename... _TElements, typename... _UElements> |
1428 | constexpr bool |
1429 | operator>(const tuple<_TElements...>& __t, |
1430 | const tuple<_UElements...>& __u) |
1431 | { return __u < __t; } |
1432 | |
1433 | template<typename... _TElements, typename... _UElements> |
1434 | constexpr bool |
1435 | operator<=(const tuple<_TElements...>& __t, |
1436 | const tuple<_UElements...>& __u) |
1437 | { return !(__u < __t); } |
1438 | |
1439 | template<typename... _TElements, typename... _UElements> |
1440 | constexpr bool |
1441 | operator>=(const tuple<_TElements...>& __t, |
1442 | const tuple<_UElements...>& __u) |
1443 | { return !(__t < __u); } |
1444 | |
1445 | // NB: DR 705. |
1446 | template<typename... _Elements> |
1447 | constexpr tuple<typename __decay_and_strip<_Elements>::__type...> |
1448 | make_tuple(_Elements&&... __args) |
1449 | { |
1450 | typedef tuple<typename __decay_and_strip<_Elements>::__type...> |
1451 | __result_type; |
1452 | return __result_type(std::forward<_Elements>(__args)...); |
1453 | } |
1454 | |
1455 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1456 | // 2275. Why is forward_as_tuple not constexpr? |
1457 | template<typename... _Elements> |
1458 | constexpr tuple<_Elements&&...> |
1459 | forward_as_tuple(_Elements&&... __args) noexcept |
1460 | { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } |
1461 | |
1462 | template<size_t, typename, typename, size_t> |
1463 | struct __make_tuple_impl; |
1464 | |
1465 | template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> |
1466 | struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> |
1467 | : __make_tuple_impl<_Idx + 1, |
1468 | tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, |
1469 | _Tuple, _Nm> |
1470 | { }; |
1471 | |
1472 | template<std::size_t _Nm, typename _Tuple, typename... _Tp> |
1473 | struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> |
1474 | { |
1475 | typedef tuple<_Tp...> __type; |
1476 | }; |
1477 | |
1478 | template<typename _Tuple> |
1479 | struct __do_make_tuple |
1480 | : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> |
1481 | { }; |
1482 | |
1483 | // Returns the std::tuple equivalent of a tuple-like type. |
1484 | template<typename _Tuple> |
1485 | struct __make_tuple |
1486 | : public __do_make_tuple<typename std::remove_cv |
1487 | <typename std::remove_reference<_Tuple>::type>::type> |
1488 | { }; |
1489 | |
1490 | // Combines several std::tuple's into a single one. |
1491 | template<typename...> |
1492 | struct __combine_tuples; |
1493 | |
1494 | template<> |
1495 | struct __combine_tuples<> |
1496 | { |
1497 | typedef tuple<> __type; |
1498 | }; |
1499 | |
1500 | template<typename... _Ts> |
1501 | struct __combine_tuples<tuple<_Ts...>> |
1502 | { |
1503 | typedef tuple<_Ts...> __type; |
1504 | }; |
1505 | |
1506 | template<typename... _T1s, typename... _T2s, typename... _Rem> |
1507 | struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> |
1508 | { |
1509 | typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, |
1510 | _Rem...>::__type __type; |
1511 | }; |
1512 | |
1513 | // Computes the result type of tuple_cat given a set of tuple-like types. |
1514 | template<typename... _Tpls> |
1515 | struct __tuple_cat_result |
1516 | { |
1517 | typedef typename __combine_tuples |
1518 | <typename __make_tuple<_Tpls>::__type...>::__type __type; |
1519 | }; |
1520 | |
1521 | // Helper to determine the index set for the first tuple-like |
1522 | // type of a given set. |
1523 | template<typename...> |
1524 | struct __make_1st_indices; |
1525 | |
1526 | template<> |
1527 | struct __make_1st_indices<> |
1528 | { |
1529 | typedef std::_Index_tuple<> __type; |
1530 | }; |
1531 | |
1532 | template<typename _Tp, typename... _Tpls> |
1533 | struct __make_1st_indices<_Tp, _Tpls...> |
1534 | { |
1535 | typedef typename std::_Build_index_tuple<std::tuple_size< |
1536 | typename std::remove_reference<_Tp>::type>::value>::__type __type; |
1537 | }; |
1538 | |
1539 | // Performs the actual concatenation by step-wise expanding tuple-like |
1540 | // objects into the elements, which are finally forwarded into the |
1541 | // result tuple. |
1542 | template<typename _Ret, typename _Indices, typename... _Tpls> |
1543 | struct __tuple_concater; |
1544 | |
1545 | template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> |
1546 | struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> |
1547 | { |
1548 | template<typename... _Us> |
1549 | static constexpr _Ret |
1550 | _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) |
1551 | { |
1552 | typedef typename __make_1st_indices<_Tpls...>::__type __idx; |
1553 | typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; |
1554 | return __next::_S_do(std::forward<_Tpls>(__tps)..., |
1555 | std::forward<_Us>(__us)..., |
1556 | std::get<_Is>(std::forward<_Tp>(__tp))...); |
1557 | } |
1558 | }; |
1559 | |
1560 | template<typename _Ret> |
1561 | struct __tuple_concater<_Ret, std::_Index_tuple<>> |
1562 | { |
1563 | template<typename... _Us> |
1564 | static constexpr _Ret |
1565 | _S_do(_Us&&... __us) |
1566 | { |
1567 | return _Ret(std::forward<_Us>(__us)...); |
1568 | } |
1569 | }; |
1570 | |
1571 | /// tuple_cat |
1572 | template<typename... _Tpls, typename = typename |
1573 | enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> |
1574 | constexpr auto |
1575 | tuple_cat(_Tpls&&... __tpls) |
1576 | -> typename __tuple_cat_result<_Tpls...>::__type |
1577 | { |
1578 | typedef typename __tuple_cat_result<_Tpls...>::__type __ret; |
1579 | typedef typename __make_1st_indices<_Tpls...>::__type __idx; |
1580 | typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; |
1581 | return __concater::_S_do(std::forward<_Tpls>(__tpls)...); |
1582 | } |
1583 | |
1584 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1585 | // 2301. Why is tie not constexpr? |
1586 | /// tie |
1587 | template<typename... _Elements> |
1588 | constexpr tuple<_Elements&...> |
1589 | tie(_Elements&... __args) noexcept |
1590 | { return tuple<_Elements&...>(__args...); } |
1591 | |
1592 | /// swap |
1593 | template<typename... _Elements> |
1594 | inline |
1595 | #if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11 |
1596 | // Constrained free swap overload, see p0185r1 |
1597 | typename enable_if<__and_<__is_swappable<_Elements>...>::value |
1598 | >::type |
1599 | #else |
1600 | void |
1601 | #endif |
1602 | swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) |
1603 | noexcept(noexcept(__x.swap(__y))) |
1604 | { __x.swap(__y); } |
1605 | |
1606 | #if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11 |
1607 | template<typename... _Elements> |
1608 | typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type |
1609 | swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; |
1610 | #endif |
1611 | |
1612 | // A class (and instance) which can be used in 'tie' when an element |
1613 | // of a tuple is not required. |
1614 | // _GLIBCXX14_CONSTEXPR |
1615 | // 2933. PR for LWG 2773 could be clearer |
1616 | struct _Swallow_assign |
1617 | { |
1618 | template<class _Tp> |
1619 | _GLIBCXX14_CONSTEXPR const _Swallow_assign& |
1620 | operator=(const _Tp&) const |
1621 | { return *this; } |
1622 | }; |
1623 | |
1624 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1625 | // 2773. Making std::ignore constexpr |
1626 | _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; |
1627 | |
1628 | /// Partial specialization for tuples |
1629 | template<typename... _Types, typename _Alloc> |
1630 | struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; |
1631 | |
1632 | // See stl_pair.h... |
1633 | template<class _T1, class _T2> |
1634 | template<typename... _Args1, typename... _Args2> |
1635 | inline |
1636 | pair<_T1, _T2>:: |
1637 | pair(piecewise_construct_t, |
1638 | tuple<_Args1...> __first, tuple<_Args2...> __second) |
1639 | : pair(__first, __second, |
1640 | typename _Build_index_tuple<sizeof...(_Args1)>::__type(), |
1641 | typename _Build_index_tuple<sizeof...(_Args2)>::__type()) |
1642 | { } |
1643 | |
1644 | template<class _T1, class _T2> |
1645 | template<typename... _Args1, std::size_t... _Indexes1, |
1646 | typename... _Args2, std::size_t... _Indexes2> |
1647 | inline |
1648 | pair<_T1, _T2>:: |
1649 | pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, |
1650 | _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) |
1651 | : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), |
1652 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) |
1653 | { } |
1654 | |
1655 | #if __cplusplus201103L > 201402L |
1656 | # define __cpp_lib_apply 201603 |
1657 | |
1658 | template <typename _Fn, typename _Tuple, size_t... _Idx> |
1659 | constexpr decltype(auto) |
1660 | __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) |
1661 | { |
1662 | return std::__invoke(std::forward<_Fn>(__f), |
1663 | std::get<_Idx>(std::forward<_Tuple>(__t))...); |
1664 | } |
1665 | |
1666 | template <typename _Fn, typename _Tuple> |
1667 | constexpr decltype(auto) |
1668 | apply(_Fn&& __f, _Tuple&& __t) |
1669 | { |
1670 | using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>; |
1671 | return std::__apply_impl(std::forward<_Fn>(__f), |
1672 | std::forward<_Tuple>(__t), |
1673 | _Indices{}); |
1674 | } |
1675 | |
1676 | #define __cpp_lib_make_from_tuple 201606 |
1677 | |
1678 | template <typename _Tp, typename _Tuple, size_t... _Idx> |
1679 | constexpr _Tp |
1680 | __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) |
1681 | { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } |
1682 | |
1683 | template <typename _Tp, typename _Tuple> |
1684 | constexpr _Tp |
1685 | make_from_tuple(_Tuple&& __t) |
1686 | { |
1687 | return __make_from_tuple_impl<_Tp>( |
1688 | std::forward<_Tuple>(__t), |
1689 | make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{}); |
1690 | } |
1691 | #endif // C++17 |
1692 | |
1693 | /// @} |
1694 | |
1695 | _GLIBCXX_END_NAMESPACE_VERSION |
1696 | } // namespace std |
1697 | |
1698 | #endif // C++11 |
1699 | |
1700 | #endif // _GLIBCXX_TUPLE |
1 | //===- llvm/Support/Error.h - Recoverable error handling --------*- 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 defines an API used to report recoverable errors. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_ERROR_H |
15 | #define LLVM_SUPPORT_ERROR_H |
16 | |
17 | #include "llvm/ADT/SmallVector.h" |
18 | #include "llvm/ADT/STLExtras.h" |
19 | #include "llvm/ADT/StringExtras.h" |
20 | #include "llvm/ADT/Twine.h" |
21 | #include "llvm/Config/abi-breaking.h" |
22 | #include "llvm/Support/AlignOf.h" |
23 | #include "llvm/Support/Compiler.h" |
24 | #include "llvm/Support/Debug.h" |
25 | #include "llvm/Support/ErrorHandling.h" |
26 | #include "llvm/Support/ErrorOr.h" |
27 | #include "llvm/Support/raw_ostream.h" |
28 | #include <algorithm> |
29 | #include <cassert> |
30 | #include <cstdint> |
31 | #include <cstdlib> |
32 | #include <functional> |
33 | #include <memory> |
34 | #include <new> |
35 | #include <string> |
36 | #include <system_error> |
37 | #include <type_traits> |
38 | #include <utility> |
39 | #include <vector> |
40 | |
41 | namespace llvm { |
42 | |
43 | class ErrorSuccess; |
44 | |
45 | /// Base class for error info classes. Do not extend this directly: Extend |
46 | /// the ErrorInfo template subclass instead. |
47 | class ErrorInfoBase { |
48 | public: |
49 | virtual ~ErrorInfoBase() = default; |
50 | |
51 | /// Print an error message to an output stream. |
52 | virtual void log(raw_ostream &OS) const = 0; |
53 | |
54 | /// Return the error message as a string. |
55 | virtual std::string message() const { |
56 | std::string Msg; |
57 | raw_string_ostream OS(Msg); |
58 | log(OS); |
59 | return OS.str(); |
60 | } |
61 | |
62 | /// Convert this error to a std::error_code. |
63 | /// |
64 | /// This is a temporary crutch to enable interaction with code still |
65 | /// using std::error_code. It will be removed in the future. |
66 | virtual std::error_code convertToErrorCode() const = 0; |
67 | |
68 | // Returns the class ID for this type. |
69 | static const void *classID() { return &ID; } |
70 | |
71 | // Returns the class ID for the dynamic type of this ErrorInfoBase instance. |
72 | virtual const void *dynamicClassID() const = 0; |
73 | |
74 | // Check whether this instance is a subclass of the class identified by |
75 | // ClassID. |
76 | virtual bool isA(const void *const ClassID) const { |
77 | return ClassID == classID(); |
78 | } |
79 | |
80 | // Check whether this instance is a subclass of ErrorInfoT. |
81 | template <typename ErrorInfoT> bool isA() const { |
82 | return isA(ErrorInfoT::classID()); |
83 | } |
84 | |
85 | private: |
86 | virtual void anchor(); |
87 | |
88 | static char ID; |
89 | }; |
90 | |
91 | /// Lightweight error class with error context and mandatory checking. |
92 | /// |
93 | /// Instances of this class wrap a ErrorInfoBase pointer. Failure states |
94 | /// are represented by setting the pointer to a ErrorInfoBase subclass |
95 | /// instance containing information describing the failure. Success is |
96 | /// represented by a null pointer value. |
97 | /// |
98 | /// Instances of Error also contains a 'Checked' flag, which must be set |
99 | /// before the destructor is called, otherwise the destructor will trigger a |
100 | /// runtime error. This enforces at runtime the requirement that all Error |
101 | /// instances be checked or returned to the caller. |
102 | /// |
103 | /// There are two ways to set the checked flag, depending on what state the |
104 | /// Error instance is in. For Error instances indicating success, it |
105 | /// is sufficient to invoke the boolean conversion operator. E.g.: |
106 | /// |
107 | /// @code{.cpp} |
108 | /// Error foo(<...>); |
109 | /// |
110 | /// if (auto E = foo(<...>)) |
111 | /// return E; // <- Return E if it is in the error state. |
112 | /// // We have verified that E was in the success state. It can now be safely |
113 | /// // destroyed. |
114 | /// @endcode |
115 | /// |
116 | /// A success value *can not* be dropped. For example, just calling 'foo(<...>)' |
117 | /// without testing the return value will raise a runtime error, even if foo |
118 | /// returns success. |
119 | /// |
120 | /// For Error instances representing failure, you must use either the |
121 | /// handleErrors or handleAllErrors function with a typed handler. E.g.: |
122 | /// |
123 | /// @code{.cpp} |
124 | /// class MyErrorInfo : public ErrorInfo<MyErrorInfo> { |
125 | /// // Custom error info. |
126 | /// }; |
127 | /// |
128 | /// Error foo(<...>) { return make_error<MyErrorInfo>(...); } |
129 | /// |
130 | /// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo. |
131 | /// auto NewE = |
132 | /// handleErrors(E, |
133 | /// [](const MyErrorInfo &M) { |
134 | /// // Deal with the error. |
135 | /// }, |
136 | /// [](std::unique_ptr<OtherError> M) -> Error { |
137 | /// if (canHandle(*M)) { |
138 | /// // handle error. |
139 | /// return Error::success(); |
140 | /// } |
141 | /// // Couldn't handle this error instance. Pass it up the stack. |
142 | /// return Error(std::move(M)); |
143 | /// ); |
144 | /// // Note - we must check or return NewE in case any of the handlers |
145 | /// // returned a new error. |
146 | /// @endcode |
147 | /// |
148 | /// The handleAllErrors function is identical to handleErrors, except |
149 | /// that it has a void return type, and requires all errors to be handled and |
150 | /// no new errors be returned. It prevents errors (assuming they can all be |
151 | /// handled) from having to be bubbled all the way to the top-level. |
152 | /// |
153 | /// *All* Error instances must be checked before destruction, even if |
154 | /// they're moved-assigned or constructed from Success values that have already |
155 | /// been checked. This enforces checking through all levels of the call stack. |
156 | class LLVM_NODISCARD[[clang::warn_unused_result]] Error { |
157 | // ErrorList needs to be able to yank ErrorInfoBase pointers out of this |
158 | // class to add to the error list. |
159 | friend class ErrorList; |
160 | |
161 | // handleErrors needs to be able to set the Checked flag. |
162 | template <typename... HandlerTs> |
163 | friend Error handleErrors(Error E, HandlerTs &&... Handlers); |
164 | |
165 | // Expected<T> needs to be able to steal the payload when constructed from an |
166 | // error. |
167 | template <typename T> friend class Expected; |
168 | |
169 | protected: |
170 | /// Create a success value. Prefer using 'Error::success()' for readability |
171 | Error() { |
172 | setPtr(nullptr); |
173 | setChecked(false); |
174 | } |
175 | |
176 | public: |
177 | /// Create a success value. |
178 | static ErrorSuccess success(); |
179 | |
180 | // Errors are not copy-constructable. |
181 | Error(const Error &Other) = delete; |
182 | |
183 | /// Move-construct an error value. The newly constructed error is considered |
184 | /// unchecked, even if the source error had been checked. The original error |
185 | /// becomes a checked Success value, regardless of its original state. |
186 | Error(Error &&Other) { |
187 | setChecked(true); |
188 | *this = std::move(Other); |
189 | } |
190 | |
191 | /// Create an error value. Prefer using the 'make_error' function, but |
192 | /// this constructor can be useful when "re-throwing" errors from handlers. |
193 | Error(std::unique_ptr<ErrorInfoBase> Payload) { |
194 | setPtr(Payload.release()); |
195 | setChecked(false); |
196 | } |
197 | |
198 | // Errors are not copy-assignable. |
199 | Error &operator=(const Error &Other) = delete; |
200 | |
201 | /// Move-assign an error value. The current error must represent success, you |
202 | /// you cannot overwrite an unhandled error. The current error is then |
203 | /// considered unchecked. The source error becomes a checked success value, |
204 | /// regardless of its original state. |
205 | Error &operator=(Error &&Other) { |
206 | // Don't allow overwriting of unchecked values. |
207 | assertIsChecked(); |
208 | setPtr(Other.getPtr()); |
209 | |
210 | // This Error is unchecked, even if the source error was checked. |
211 | setChecked(false); |
212 | |
213 | // Null out Other's payload and set its checked bit. |
214 | Other.setPtr(nullptr); |
215 | Other.setChecked(true); |
216 | |
217 | return *this; |
218 | } |
219 | |
220 | /// Destroy a Error. Fails with a call to abort() if the error is |
221 | /// unchecked. |
222 | ~Error() { |
223 | assertIsChecked(); |
224 | delete getPtr(); |
225 | } |
226 | |
227 | /// Bool conversion. Returns true if this Error is in a failure state, |
228 | /// and false if it is in an accept state. If the error is in a Success state |
229 | /// it will be considered checked. |
230 | explicit operator bool() { |
231 | setChecked(getPtr() == nullptr); |
232 | return getPtr() != nullptr; |
233 | } |
234 | |
235 | /// Check whether one error is a subclass of another. |
236 | template <typename ErrT> bool isA() const { |
237 | return getPtr() && getPtr()->isA(ErrT::classID()); |
238 | } |
239 | |
240 | /// Returns the dynamic class id of this error, or null if this is a success |
241 | /// value. |
242 | const void* dynamicClassID() const { |
243 | if (!getPtr()) |
244 | return nullptr; |
245 | return getPtr()->dynamicClassID(); |
246 | } |
247 | |
248 | private: |
249 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
250 | // assertIsChecked() happens very frequently, but under normal circumstances |
251 | // is supposed to be a no-op. So we want it to be inlined, but having a bunch |
252 | // of debug prints can cause the function to be too large for inlining. So |
253 | // it's important that we define this function out of line so that it can't be |
254 | // inlined. |
255 | LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) |
256 | void fatalUncheckedError() const; |
257 | #endif |
258 | |
259 | void assertIsChecked() { |
260 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
261 | if (LLVM_UNLIKELY(!getChecked() || getPtr())__builtin_expect((bool)(!getChecked() || getPtr()), false)) |
262 | fatalUncheckedError(); |
263 | #endif |
264 | } |
265 | |
266 | ErrorInfoBase *getPtr() const { |
267 | return reinterpret_cast<ErrorInfoBase*>( |
268 | reinterpret_cast<uintptr_t>(Payload) & |
269 | ~static_cast<uintptr_t>(0x1)); |
270 | } |
271 | |
272 | void setPtr(ErrorInfoBase *EI) { |
273 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
274 | Payload = reinterpret_cast<ErrorInfoBase*>( |
275 | (reinterpret_cast<uintptr_t>(EI) & |
276 | ~static_cast<uintptr_t>(0x1)) | |
277 | (reinterpret_cast<uintptr_t>(Payload) & 0x1)); |
278 | #else |
279 | Payload = EI; |
280 | #endif |
281 | } |
282 | |
283 | bool getChecked() const { |
284 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
285 | return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0; |
286 | #else |
287 | return true; |
288 | #endif |
289 | } |
290 | |
291 | void setChecked(bool V) { |
292 | Payload = reinterpret_cast<ErrorInfoBase*>( |
293 | (reinterpret_cast<uintptr_t>(Payload) & |
294 | ~static_cast<uintptr_t>(0x1)) | |
295 | (V ? 0 : 1)); |
296 | } |
297 | |
298 | std::unique_ptr<ErrorInfoBase> takePayload() { |
299 | std::unique_ptr<ErrorInfoBase> Tmp(getPtr()); |
300 | setPtr(nullptr); |
301 | setChecked(true); |
302 | return Tmp; |
303 | } |
304 | |
305 | ErrorInfoBase *Payload = nullptr; |
306 | }; |
307 | |
308 | /// Subclass of Error for the sole purpose of identifying the success path in |
309 | /// the type system. This allows to catch invalid conversion to Expected<T> at |
310 | /// compile time. |
311 | class ErrorSuccess : public Error {}; |
312 | |
313 | inline ErrorSuccess Error::success() { return ErrorSuccess(); } |
314 | |
315 | /// Make a Error instance representing failure using the given error info |
316 | /// type. |
317 | template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) { |
318 | return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...)); |
319 | } |
320 | |
321 | /// Base class for user error types. Users should declare their error types |
322 | /// like: |
323 | /// |
324 | /// class MyError : public ErrorInfo<MyError> { |
325 | /// .... |
326 | /// }; |
327 | /// |
328 | /// This class provides an implementation of the ErrorInfoBase::kind |
329 | /// method, which is used by the Error RTTI system. |
330 | template <typename ThisErrT, typename ParentErrT = ErrorInfoBase> |
331 | class ErrorInfo : public ParentErrT { |
332 | public: |
333 | static const void *classID() { return &ThisErrT::ID; } |
334 | |
335 | const void *dynamicClassID() const override { return &ThisErrT::ID; } |
336 | |
337 | bool isA(const void *const ClassID) const override { |
338 | return ClassID == classID() || ParentErrT::isA(ClassID); |
339 | } |
340 | }; |
341 | |
342 | /// Special ErrorInfo subclass representing a list of ErrorInfos. |
343 | /// Instances of this class are constructed by joinError. |
344 | class ErrorList final : public ErrorInfo<ErrorList> { |
345 | // handleErrors needs to be able to iterate the payload list of an |
346 | // ErrorList. |
347 | template <typename... HandlerTs> |
348 | friend Error handleErrors(Error E, HandlerTs &&... Handlers); |
349 | |
350 | // joinErrors is implemented in terms of join. |
351 | friend Error joinErrors(Error, Error); |
352 | |
353 | public: |
354 | void log(raw_ostream &OS) const override { |
355 | OS << "Multiple errors:\n"; |
356 | for (auto &ErrPayload : Payloads) { |
357 | ErrPayload->log(OS); |
358 | OS << "\n"; |
359 | } |
360 | } |
361 | |
362 | std::error_code convertToErrorCode() const override; |
363 | |
364 | // Used by ErrorInfo::classID. |
365 | static char ID; |
366 | |
367 | private: |
368 | ErrorList(std::unique_ptr<ErrorInfoBase> Payload1, |
369 | std::unique_ptr<ErrorInfoBase> Payload2) { |
370 | assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&(static_cast <bool> (!Payload1->isA<ErrorList> () && !Payload2->isA<ErrorList>() && "ErrorList constructor payloads should be singleton errors") ? void (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 371, __extension__ __PRETTY_FUNCTION__)) |
371 | "ErrorList constructor payloads should be singleton errors")(static_cast <bool> (!Payload1->isA<ErrorList> () && !Payload2->isA<ErrorList>() && "ErrorList constructor payloads should be singleton errors") ? void (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 371, __extension__ __PRETTY_FUNCTION__)); |
372 | Payloads.push_back(std::move(Payload1)); |
373 | Payloads.push_back(std::move(Payload2)); |
374 | } |
375 | |
376 | static Error join(Error E1, Error E2) { |
377 | if (!E1) |
378 | return E2; |
379 | if (!E2) |
380 | return E1; |
381 | if (E1.isA<ErrorList>()) { |
382 | auto &E1List = static_cast<ErrorList &>(*E1.getPtr()); |
383 | if (E2.isA<ErrorList>()) { |
384 | auto E2Payload = E2.takePayload(); |
385 | auto &E2List = static_cast<ErrorList &>(*E2Payload); |
386 | for (auto &Payload : E2List.Payloads) |
387 | E1List.Payloads.push_back(std::move(Payload)); |
388 | } else |
389 | E1List.Payloads.push_back(E2.takePayload()); |
390 | |
391 | return E1; |
392 | } |
393 | if (E2.isA<ErrorList>()) { |
394 | auto &E2List = static_cast<ErrorList &>(*E2.getPtr()); |
395 | E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload()); |
396 | return E2; |
397 | } |
398 | return Error(std::unique_ptr<ErrorList>( |
399 | new ErrorList(E1.takePayload(), E2.takePayload()))); |
400 | } |
401 | |
402 | std::vector<std::unique_ptr<ErrorInfoBase>> Payloads; |
403 | }; |
404 | |
405 | /// Concatenate errors. The resulting Error is unchecked, and contains the |
406 | /// ErrorInfo(s), if any, contained in E1, followed by the |
407 | /// ErrorInfo(s), if any, contained in E2. |
408 | inline Error joinErrors(Error E1, Error E2) { |
409 | return ErrorList::join(std::move(E1), std::move(E2)); |
410 | } |
411 | |
412 | /// Tagged union holding either a T or a Error. |
413 | /// |
414 | /// This class parallels ErrorOr, but replaces error_code with Error. Since |
415 | /// Error cannot be copied, this class replaces getError() with |
416 | /// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the |
417 | /// error class type. |
418 | template <class T> class LLVM_NODISCARD[[clang::warn_unused_result]] Expected { |
419 | template <class T1> friend class ExpectedAsOutParameter; |
420 | template <class OtherT> friend class Expected; |
421 | |
422 | static const bool isRef = std::is_reference<T>::value; |
423 | |
424 | using wrap = ReferenceStorage<typename std::remove_reference<T>::type>; |
425 | |
426 | using error_type = std::unique_ptr<ErrorInfoBase>; |
427 | |
428 | public: |
429 | using storage_type = typename std::conditional<isRef, wrap, T>::type; |
430 | using value_type = T; |
431 | |
432 | private: |
433 | using reference = typename std::remove_reference<T>::type &; |
434 | using const_reference = const typename std::remove_reference<T>::type &; |
435 | using pointer = typename std::remove_reference<T>::type *; |
436 | using const_pointer = const typename std::remove_reference<T>::type *; |
437 | |
438 | public: |
439 | /// Create an Expected<T> error value from the given Error. |
440 | Expected(Error Err) |
441 | : HasError(true) |
442 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
443 | // Expected is unchecked upon construction in Debug builds. |
444 | , Unchecked(true) |
445 | #endif |
446 | { |
447 | assert(Err && "Cannot create Expected<T> from Error success value.")(static_cast <bool> (Err && "Cannot create Expected<T> from Error success value." ) ? void (0) : __assert_fail ("Err && \"Cannot create Expected<T> from Error success value.\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 447, __extension__ __PRETTY_FUNCTION__)); |
448 | new (getErrorStorage()) error_type(Err.takePayload()); |
449 | } |
450 | |
451 | /// Forbid to convert from Error::success() implicitly, this avoids having |
452 | /// Expected<T> foo() { return Error::success(); } which compiles otherwise |
453 | /// but triggers the assertion above. |
454 | Expected(ErrorSuccess) = delete; |
455 | |
456 | /// Create an Expected<T> success value from the given OtherT value, which |
457 | /// must be convertible to T. |
458 | template <typename OtherT> |
459 | Expected(OtherT &&Val, |
460 | typename std::enable_if<std::is_convertible<OtherT, T>::value>::type |
461 | * = nullptr) |
462 | : HasError(false) |
463 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
464 | // Expected is unchecked upon construction in Debug builds. |
465 | , Unchecked(true) |
466 | #endif |
467 | { |
468 | new (getStorage()) storage_type(std::forward<OtherT>(Val)); |
469 | } |
470 | |
471 | /// Move construct an Expected<T> value. |
472 | Expected(Expected &&Other) { moveConstruct(std::move(Other)); } |
473 | |
474 | /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT |
475 | /// must be convertible to T. |
476 | template <class OtherT> |
477 | Expected(Expected<OtherT> &&Other, |
478 | typename std::enable_if<std::is_convertible<OtherT, T>::value>::type |
479 | * = nullptr) { |
480 | moveConstruct(std::move(Other)); |
481 | } |
482 | |
483 | /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT |
484 | /// isn't convertible to T. |
485 | template <class OtherT> |
486 | explicit Expected( |
487 | Expected<OtherT> &&Other, |
488 | typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * = |
489 | nullptr) { |
490 | moveConstruct(std::move(Other)); |
491 | } |
492 | |
493 | /// Move-assign from another Expected<T>. |
494 | Expected &operator=(Expected &&Other) { |
495 | moveAssign(std::move(Other)); |
496 | return *this; |
497 | } |
498 | |
499 | /// Destroy an Expected<T>. |
500 | ~Expected() { |
501 | assertIsChecked(); |
502 | if (!HasError) |
503 | getStorage()->~storage_type(); |
504 | else |
505 | getErrorStorage()->~error_type(); |
506 | } |
507 | |
508 | /// \brief Return false if there is an error. |
509 | explicit operator bool() { |
510 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
511 | Unchecked = HasError; |
512 | #endif |
513 | return !HasError; |
514 | } |
515 | |
516 | /// \brief Returns a reference to the stored T value. |
517 | reference get() { |
518 | assertIsChecked(); |
519 | return *getStorage(); |
520 | } |
521 | |
522 | /// \brief Returns a const reference to the stored T value. |
523 | const_reference get() const { |
524 | assertIsChecked(); |
525 | return const_cast<Expected<T> *>(this)->get(); |
526 | } |
527 | |
528 | /// \brief Check that this Expected<T> is an error of type ErrT. |
529 | template <typename ErrT> bool errorIsA() const { |
530 | return HasError && (*getErrorStorage())->template isA<ErrT>(); |
531 | } |
532 | |
533 | /// \brief Take ownership of the stored error. |
534 | /// After calling this the Expected<T> is in an indeterminate state that can |
535 | /// only be safely destructed. No further calls (beside the destructor) should |
536 | /// be made on the Expected<T> vaule. |
537 | Error takeError() { |
538 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
539 | Unchecked = false; |
540 | #endif |
541 | return HasError ? Error(std::move(*getErrorStorage())) : Error::success(); |
542 | } |
543 | |
544 | /// \brief Returns a pointer to the stored T value. |
545 | pointer operator->() { |
546 | assertIsChecked(); |
547 | return toPointer(getStorage()); |
548 | } |
549 | |
550 | /// \brief Returns a const pointer to the stored T value. |
551 | const_pointer operator->() const { |
552 | assertIsChecked(); |
553 | return toPointer(getStorage()); |
554 | } |
555 | |
556 | /// \brief Returns a reference to the stored T value. |
557 | reference operator*() { |
558 | assertIsChecked(); |
559 | return *getStorage(); |
560 | } |
561 | |
562 | /// \brief Returns a const reference to the stored T value. |
563 | const_reference operator*() const { |
564 | assertIsChecked(); |
565 | return *getStorage(); |
566 | } |
567 | |
568 | private: |
569 | template <class T1> |
570 | static bool compareThisIfSameType(const T1 &a, const T1 &b) { |
571 | return &a == &b; |
572 | } |
573 | |
574 | template <class T1, class T2> |
575 | static bool compareThisIfSameType(const T1 &a, const T2 &b) { |
576 | return false; |
577 | } |
578 | |
579 | template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) { |
580 | HasError = Other.HasError; |
581 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
582 | Unchecked = true; |
583 | Other.Unchecked = false; |
584 | #endif |
585 | |
586 | if (!HasError) |
587 | new (getStorage()) storage_type(std::move(*Other.getStorage())); |
588 | else |
589 | new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage())); |
590 | } |
591 | |
592 | template <class OtherT> void moveAssign(Expected<OtherT> &&Other) { |
593 | assertIsChecked(); |
594 | |
595 | if (compareThisIfSameType(*this, Other)) |
596 | return; |
597 | |
598 | this->~Expected(); |
599 | new (this) Expected(std::move(Other)); |
600 | } |
601 | |
602 | pointer toPointer(pointer Val) { return Val; } |
603 | |
604 | const_pointer toPointer(const_pointer Val) const { return Val; } |
605 | |
606 | pointer toPointer(wrap *Val) { return &Val->get(); } |
607 | |
608 | const_pointer toPointer(const wrap *Val) const { return &Val->get(); } |
609 | |
610 | storage_type *getStorage() { |
611 | assert(!HasError && "Cannot get value when an error exists!")(static_cast <bool> (!HasError && "Cannot get value when an error exists!" ) ? void (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 611, __extension__ __PRETTY_FUNCTION__)); |
612 | return reinterpret_cast<storage_type *>(TStorage.buffer); |
613 | } |
614 | |
615 | const storage_type *getStorage() const { |
616 | assert(!HasError && "Cannot get value when an error exists!")(static_cast <bool> (!HasError && "Cannot get value when an error exists!" ) ? void (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 616, __extension__ __PRETTY_FUNCTION__)); |
617 | return reinterpret_cast<const storage_type *>(TStorage.buffer); |
618 | } |
619 | |
620 | error_type *getErrorStorage() { |
621 | assert(HasError && "Cannot get error when a value exists!")(static_cast <bool> (HasError && "Cannot get error when a value exists!" ) ? void (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 621, __extension__ __PRETTY_FUNCTION__)); |
622 | return reinterpret_cast<error_type *>(ErrorStorage.buffer); |
623 | } |
624 | |
625 | const error_type *getErrorStorage() const { |
626 | assert(HasError && "Cannot get error when a value exists!")(static_cast <bool> (HasError && "Cannot get error when a value exists!" ) ? void (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 626, __extension__ __PRETTY_FUNCTION__)); |
627 | return reinterpret_cast<const error_type *>(ErrorStorage.buffer); |
628 | } |
629 | |
630 | // Used by ExpectedAsOutParameter to reset the checked flag. |
631 | void setUnchecked() { |
632 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
633 | Unchecked = true; |
634 | #endif |
635 | } |
636 | |
637 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
638 | LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) |
639 | LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline)) |
640 | void fatalUncheckedExpected() const { |
641 | dbgs() << "Expected<T> must be checked before access or destruction.\n"; |
642 | if (HasError) { |
643 | dbgs() << "Unchecked Expected<T> contained error:\n"; |
644 | (*getErrorStorage())->log(dbgs()); |
645 | } else |
646 | dbgs() << "Expected<T> value was in success state. (Note: Expected<T> " |
647 | "values in success mode must still be checked prior to being " |
648 | "destroyed).\n"; |
649 | abort(); |
650 | } |
651 | #endif |
652 | |
653 | void assertIsChecked() { |
654 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
655 | if (LLVM_UNLIKELY(Unchecked)__builtin_expect((bool)(Unchecked), false)) |
656 | fatalUncheckedExpected(); |
657 | #endif |
658 | } |
659 | |
660 | union { |
661 | AlignedCharArrayUnion<storage_type> TStorage; |
662 | AlignedCharArrayUnion<error_type> ErrorStorage; |
663 | }; |
664 | bool HasError : 1; |
665 | #if LLVM_ENABLE_ABI_BREAKING_CHECKS1 |
666 | bool Unchecked : 1; |
667 | #endif |
668 | }; |
669 | |
670 | /// Report a serious error, calling any installed error handler. See |
671 | /// ErrorHandling.h. |
672 | LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) void report_fatal_error(Error Err, |
673 | bool gen_crash_diag = true); |
674 | |
675 | /// Report a fatal error if Err is a failure value. |
676 | /// |
677 | /// This function can be used to wrap calls to fallible functions ONLY when it |
678 | /// is known that the Error will always be a success value. E.g. |
679 | /// |
680 | /// @code{.cpp} |
681 | /// // foo only attempts the fallible operation if DoFallibleOperation is |
682 | /// // true. If DoFallibleOperation is false then foo always returns |
683 | /// // Error::success(). |
684 | /// Error foo(bool DoFallibleOperation); |
685 | /// |
686 | /// cantFail(foo(false)); |
687 | /// @endcode |
688 | inline void cantFail(Error Err, const char *Msg = nullptr) { |
689 | if (Err) { |
690 | if (!Msg) |
691 | Msg = "Failure value returned from cantFail wrapped call"; |
692 | llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 692); |
693 | } |
694 | } |
695 | |
696 | /// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and |
697 | /// returns the contained value. |
698 | /// |
699 | /// This function can be used to wrap calls to fallible functions ONLY when it |
700 | /// is known that the Error will always be a success value. E.g. |
701 | /// |
702 | /// @code{.cpp} |
703 | /// // foo only attempts the fallible operation if DoFallibleOperation is |
704 | /// // true. If DoFallibleOperation is false then foo always returns an int. |
705 | /// Expected<int> foo(bool DoFallibleOperation); |
706 | /// |
707 | /// int X = cantFail(foo(false)); |
708 | /// @endcode |
709 | template <typename T> |
710 | T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) { |
711 | if (ValOrErr) |
712 | return std::move(*ValOrErr); |
713 | else { |
714 | if (!Msg) |
715 | Msg = "Failure value returned from cantFail wrapped call"; |
716 | llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 716); |
717 | } |
718 | } |
719 | |
720 | /// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and |
721 | /// returns the contained reference. |
722 | /// |
723 | /// This function can be used to wrap calls to fallible functions ONLY when it |
724 | /// is known that the Error will always be a success value. E.g. |
725 | /// |
726 | /// @code{.cpp} |
727 | /// // foo only attempts the fallible operation if DoFallibleOperation is |
728 | /// // true. If DoFallibleOperation is false then foo always returns a Bar&. |
729 | /// Expected<Bar&> foo(bool DoFallibleOperation); |
730 | /// |
731 | /// Bar &X = cantFail(foo(false)); |
732 | /// @endcode |
733 | template <typename T> |
734 | T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) { |
735 | if (ValOrErr) |
736 | return *ValOrErr; |
737 | else { |
738 | if (!Msg) |
739 | Msg = "Failure value returned from cantFail wrapped call"; |
740 | llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 740); |
741 | } |
742 | } |
743 | |
744 | /// Helper for testing applicability of, and applying, handlers for |
745 | /// ErrorInfo types. |
746 | template <typename HandlerT> |
747 | class ErrorHandlerTraits |
748 | : public ErrorHandlerTraits<decltype( |
749 | &std::remove_reference<HandlerT>::type::operator())> {}; |
750 | |
751 | // Specialization functions of the form 'Error (const ErrT&)'. |
752 | template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> { |
753 | public: |
754 | static bool appliesTo(const ErrorInfoBase &E) { |
755 | return E.template isA<ErrT>(); |
756 | } |
757 | |
758 | template <typename HandlerT> |
759 | static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { |
760 | assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler" ) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 760, __extension__ __PRETTY_FUNCTION__)); |
761 | return H(static_cast<ErrT &>(*E)); |
762 | } |
763 | }; |
764 | |
765 | // Specialization functions of the form 'void (const ErrT&)'. |
766 | template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> { |
767 | public: |
768 | static bool appliesTo(const ErrorInfoBase &E) { |
769 | return E.template isA<ErrT>(); |
770 | } |
771 | |
772 | template <typename HandlerT> |
773 | static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { |
774 | assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler" ) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 774, __extension__ __PRETTY_FUNCTION__)); |
775 | H(static_cast<ErrT &>(*E)); |
776 | return Error::success(); |
777 | } |
778 | }; |
779 | |
780 | /// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'. |
781 | template <typename ErrT> |
782 | class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> { |
783 | public: |
784 | static bool appliesTo(const ErrorInfoBase &E) { |
785 | return E.template isA<ErrT>(); |
786 | } |
787 | |
788 | template <typename HandlerT> |
789 | static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { |
790 | assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler" ) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 790, __extension__ __PRETTY_FUNCTION__)); |
791 | std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release())); |
792 | return H(std::move(SubE)); |
793 | } |
794 | }; |
795 | |
796 | /// Specialization for functions of the form 'void (std::unique_ptr<ErrT>)'. |
797 | template <typename ErrT> |
798 | class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> { |
799 | public: |
800 | static bool appliesTo(const ErrorInfoBase &E) { |
801 | return E.template isA<ErrT>(); |
802 | } |
803 | |
804 | template <typename HandlerT> |
805 | static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { |
806 | assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler" ) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\"" , "/build/llvm-toolchain-snapshot-7~svn325118/include/llvm/Support/Error.h" , 806, __extension__ __PRETTY_FUNCTION__)); |
807 | std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release())); |
808 | H(std::move(SubE)); |
809 | return Error::success(); |
810 | } |
811 | }; |
812 | |
813 | // Specialization for member functions of the form 'RetT (const ErrT&)'. |
814 | template <typename C, typename RetT, typename ErrT> |
815 | class ErrorHandlerTraits<RetT (C::*)(ErrT &)> |
816 | : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; |
817 | |
818 | // Specialization for member functions of the form 'RetT (const ErrT&) const'. |
819 | template <typename C, typename RetT, typename ErrT> |
820 | class ErrorHandlerTraits<RetT (C::*)(ErrT &) const> |
821 | : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; |
822 | |
823 | // Specialization for member functions of the form 'RetT (const ErrT&)'. |
824 | template <typename C, typename RetT, typename ErrT> |
825 | class ErrorHandlerTraits<RetT (C::*)(const ErrT &)> |
826 | : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; |
827 | |
828 | // Specialization for member functions of the form 'RetT (const ErrT&) const'. |
829 | template <typename C, typename RetT, typename ErrT> |
830 | class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const> |
831 | : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; |
832 | |
833 | /// Specialization for member functions of the form |
834 | /// 'RetT (std::unique_ptr<ErrT>)'. |
835 | template <typename C, typename RetT, typename ErrT> |
836 | class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)> |
837 | : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {}; |
838 | |
839 | /// Specialization for member functions of the form |
840 | /// 'RetT (std::unique_ptr<ErrT>) const'. |
841 | template <typename C, typename RetT, typename ErrT> |
842 | class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const> |
843 | : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {}; |
844 | |
845 | inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) { |
846 | return Error(std::move(Payload)); |
847 | } |
848 | |
849 | template <typename HandlerT, typename... HandlerTs> |
850 | Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload, |
851 | HandlerT &&Handler, HandlerTs &&... Handlers) { |
852 | if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload)) |
853 | return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler), |
854 | std::move(Payload)); |
855 | return handleErrorImpl(std::move(Payload), |
856 | std::forward<HandlerTs>(Handlers)...); |
857 | } |
858 | |
859 | /// Pass the ErrorInfo(s) contained in E to their respective handlers. Any |
860 | /// unhandled errors (or Errors returned by handlers) are re-concatenated and |
861 | /// returned. |
862 | /// Because this function returns an error, its result must also be checked |
863 | /// or returned. If you intend to handle all errors use handleAllErrors |
864 | /// (which returns void, and will abort() on unhandled errors) instead. |
865 | template <typename... HandlerTs> |
866 | Error handleErrors(Error E, HandlerTs &&... Hs) { |
867 | if (!E) |
868 | return Error::success(); |
869 | |
870 | std::unique_ptr<ErrorInfoBase> Payload = E.takePayload(); |
871 | |
872 | if (Payload->isA<ErrorList>()) { |
873 | ErrorList &List = static_cast<ErrorList &>(*Payload); |
874 | Error R; |
875 | for (auto &P : List.Payloads) |
876 | R = ErrorList::join( |
877 | std::move(R), |
878 | handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...)); |
879 | return R; |
880 | } |
881 | |
882 | return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...); |
883 | } |
884 | |
885 | /// Behaves the same as handleErrors, except that it requires that all |
886 | /// errors be handled by the given handlers. If any unhandled error remains |
887 | /// after the handlers have run, report_fatal_error() will be called. |
888 | template <typename... HandlerTs> |
889 | void handleAllErrors(Error E, HandlerTs &&... Handlers) { |
890 | cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...)); |
891 | } |
892 | |
893 | /// Check that E is a non-error, then drop it. |
894 | /// If E is an error report_fatal_error will be called. |
895 | inline void handleAllErrors(Error E) { |
896 | cantFail(std::move(E)); |
897 | } |
898 | |
899 | /// Handle any errors (if present) in an Expected<T>, then try a recovery path. |
900 | /// |
901 | /// If the incoming value is a success value it is returned unmodified. If it |
902 | /// is a failure value then it the contained error is passed to handleErrors. |
903 | /// If handleErrors is able to handle the error then the RecoveryPath functor |
904 | /// is called to supply the final result. If handleErrors is not able to |
905 | /// handle all errors then the unhandled errors are returned. |
906 | /// |
907 | /// This utility enables the follow pattern: |
908 | /// |
909 | /// @code{.cpp} |
910 | /// enum FooStrategy { Aggressive, Conservative }; |
911 | /// Expected<Foo> foo(FooStrategy S); |
912 | /// |
913 | /// auto ResultOrErr = |
914 | /// handleExpected( |
915 | /// foo(Aggressive), |
916 | /// []() { return foo(Conservative); }, |
917 | /// [](AggressiveStrategyError&) { |
918 | /// // Implicitly conusme this - we'll recover by using a conservative |
919 | /// // strategy. |
920 | /// }); |
921 | /// |
922 | /// @endcode |
923 | template <typename T, typename RecoveryFtor, typename... HandlerTs> |
924 | Expected<T> handleExpected(Expected<T> ValOrErr, RecoveryFtor &&RecoveryPath, |
925 | HandlerTs &&... Handlers) { |
926 | if (ValOrErr) |
927 | return ValOrErr; |
928 | |
929 | if (auto Err = handleErrors(ValOrErr.takeError(), |
930 | std::forward<HandlerTs>(Handlers)...)) |
931 | return std::move(Err); |
932 | |
933 | return RecoveryPath(); |
934 | } |
935 | |
936 | /// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner |
937 | /// will be printed before the first one is logged. A newline will be printed |
938 | /// after each error. |
939 | /// |
940 | /// This is useful in the base level of your program to allow clean termination |
941 | /// (allowing clean deallocation of resources, etc.), while reporting error |
942 | /// information to the user. |
943 | void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner); |
944 | |
945 | /// Write all error messages (if any) in E to a string. The newline character |
946 | /// is used to separate error messages. |
947 | inline std::string toString(Error E) { |
948 | SmallVector<std::string, 2> Errors; |
949 | handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) { |
950 | Errors.push_back(EI.message()); |
951 | }); |
952 | return join(Errors.begin(), Errors.end(), "\n"); |
953 | } |
954 | |
955 | /// Consume a Error without doing anything. This method should be used |
956 | /// only where an error can be considered a reasonable and expected return |
957 | /// value. |
958 | /// |
959 | /// Uses of this method are potentially indicative of design problems: If it's |
960 | /// legitimate to do nothing while processing an "error", the error-producer |
961 | /// might be more clearly refactored to return an Optional<T>. |
962 | inline void consumeError(Error Err) { |
963 | handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {}); |
964 | } |
965 | |
966 | /// Helper for converting an Error to a bool. |
967 | /// |
968 | /// This method returns true if Err is in an error state, or false if it is |
969 | /// in a success state. Puts Err in a checked state in both cases (unlike |
970 | /// Error::operator bool(), which only does this for success states). |
971 | inline bool errorToBool(Error Err) { |
972 | bool IsError = static_cast<bool>(Err); |
973 | if (IsError) |
974 | consumeError(std::move(Err)); |
975 | return IsError; |
976 | } |
977 | |
978 | /// Helper for Errors used as out-parameters. |
979 | /// |
980 | /// This helper is for use with the Error-as-out-parameter idiom, where an error |
981 | /// is passed to a function or method by reference, rather than being returned. |
982 | /// In such cases it is helpful to set the checked bit on entry to the function |
983 | /// so that the error can be written to (unchecked Errors abort on assignment) |
984 | /// and clear the checked bit on exit so that clients cannot accidentally forget |
985 | /// to check the result. This helper performs these actions automatically using |
986 | /// RAII: |
987 | /// |
988 | /// @code{.cpp} |
989 | /// Result foo(Error &Err) { |
990 | /// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set |
991 | /// // <body of foo> |
992 | /// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed. |
993 | /// } |
994 | /// @endcode |
995 | /// |
996 | /// ErrorAsOutParameter takes an Error* rather than Error& so that it can be |
997 | /// used with optional Errors (Error pointers that are allowed to be null). If |
998 | /// ErrorAsOutParameter took an Error reference, an instance would have to be |
999 | /// created inside every condition that verified that Error was non-null. By |
1000 | /// taking an Error pointer we can just create one instance at the top of the |
1001 | /// function. |
1002 | class ErrorAsOutParameter { |
1003 | public: |
1004 | ErrorAsOutParameter(Error *Err) : Err(Err) { |
1005 | // Raise the checked bit if Err is success. |
1006 | if (Err) |
1007 | (void)!!*Err; |
1008 | } |
1009 | |
1010 | ~ErrorAsOutParameter() { |
1011 | // Clear the checked bit. |
1012 | if (Err && !*Err) |
1013 | *Err = Error::success(); |
1014 | } |
1015 | |
1016 | private: |
1017 | Error *Err; |
1018 | }; |
1019 | |
1020 | /// Helper for Expected<T>s used as out-parameters. |
1021 | /// |
1022 | /// See ErrorAsOutParameter. |
1023 | template <typename T> |
1024 | class ExpectedAsOutParameter { |
1025 | public: |
1026 | ExpectedAsOutParameter(Expected<T> *ValOrErr) |
1027 | : ValOrErr(ValOrErr) { |
1028 | if (ValOrErr) |
1029 | (void)!!*ValOrErr; |
1030 | } |
1031 | |
1032 | ~ExpectedAsOutParameter() { |
1033 | if (ValOrErr) |
1034 | ValOrErr->setUnchecked(); |
1035 | } |
1036 | |
1037 | private: |
1038 | Expected<T> *ValOrErr; |
1039 | }; |
1040 | |
1041 | /// This class wraps a std::error_code in a Error. |
1042 | /// |
1043 | /// This is useful if you're writing an interface that returns a Error |
1044 | /// (or Expected) and you want to call code that still returns |
1045 | /// std::error_codes. |
1046 | class ECError : public ErrorInfo<ECError> { |
1047 | friend Error errorCodeToError(std::error_code); |
1048 | |
1049 | public: |
1050 | void setErrorCode(std::error_code EC) { this->EC = EC; } |
1051 | std::error_code convertToErrorCode() const override { return EC; } |
1052 | void log(raw_ostream &OS) const override { OS << EC.message(); } |
1053 | |
1054 | // Used by ErrorInfo::classID. |
1055 | static char ID; |
1056 | |
1057 | protected: |
1058 | ECError() = default; |
1059 | ECError(std::error_code EC) : EC(EC) {} |
1060 | |
1061 | std::error_code EC; |
1062 | }; |
1063 | |
1064 | /// The value returned by this function can be returned from convertToErrorCode |
1065 | /// for Error values where no sensible translation to std::error_code exists. |
1066 | /// It should only be used in this situation, and should never be used where a |
1067 | /// sensible conversion to std::error_code is available, as attempts to convert |
1068 | /// to/from this error will result in a fatal error. (i.e. it is a programmatic |
1069 | ///error to try to convert such a value). |
1070 | std::error_code inconvertibleErrorCode(); |
1071 | |
1072 | /// Helper for converting an std::error_code to a Error. |
1073 | Error errorCodeToError(std::error_code EC); |
1074 | |
1075 | /// Helper for converting an ECError to a std::error_code. |
1076 | /// |
1077 | /// This method requires that Err be Error() or an ECError, otherwise it |
1078 | /// will trigger a call to abort(). |
1079 | std::error_code errorToErrorCode(Error Err); |
1080 | |
1081 | /// Convert an ErrorOr<T> to an Expected<T>. |
1082 | template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) { |
1083 | if (auto EC = EO.getError()) |
1084 | return errorCodeToError(EC); |
1085 | return std::move(*EO); |
1086 | } |
1087 | |
1088 | /// Convert an Expected<T> to an ErrorOr<T>. |
1089 | template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) { |
1090 | if (auto Err = E.takeError()) |
1091 | return errorToErrorCode(std::move(Err)); |
1092 | return std::move(*E); |
1093 | } |
1094 | |
1095 | /// This class wraps a string in an Error. |
1096 | /// |
1097 | /// StringError is useful in cases where the client is not expected to be able |
1098 | /// to consume the specific error message programmatically (for example, if the |
1099 | /// error message is to be presented to the user). |
1100 | class StringError : public ErrorInfo<StringError> { |
1101 | public: |
1102 | static char ID; |
1103 | |
1104 | StringError(const Twine &S, std::error_code EC); |
1105 | |
1106 | void log(raw_ostream &OS) const override; |
1107 | std::error_code convertToErrorCode() const override; |
1108 | |
1109 | const std::string &getMessage() const { return Msg; } |
1110 | |
1111 | private: |
1112 | std::string Msg; |
1113 | std::error_code EC; |
1114 | }; |
1115 | |
1116 | /// Helper for check-and-exit error handling. |
1117 | /// |
1118 | /// For tool use only. NOT FOR USE IN LIBRARY CODE. |
1119 | /// |
1120 | class ExitOnError { |
1121 | public: |
1122 | /// Create an error on exit helper. |
1123 | ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1) |
1124 | : Banner(std::move(Banner)), |
1125 | GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {} |
1126 | |
1127 | /// Set the banner string for any errors caught by operator(). |
1128 | void setBanner(std::string Banner) { this->Banner = std::move(Banner); } |
1129 | |
1130 | /// Set the exit-code mapper function. |
1131 | void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) { |
1132 | this->GetExitCode = std::move(GetExitCode); |
1133 | } |
1134 | |
1135 | /// Check Err. If it's in a failure state log the error(s) and exit. |
1136 | void operator()(Error Err) const { checkError(std::move(Err)); } |
1137 | |
1138 | /// Check E. If it's in a success state then return the contained value. If |
1139 | /// it's in a failure state log the error(s) and exit. |
1140 | template <typename T> T operator()(Expected<T> &&E) const { |
1141 | checkError(E.takeError()); |
1142 | return std::move(*E); |
1143 | } |
1144 | |
1145 | /// Check E. If it's in a success state then return the contained reference. If |
1146 | /// it's in a failure state log the error(s) and exit. |
1147 | template <typename T> T& operator()(Expected<T&> &&E) const { |
1148 | checkError(E.takeError()); |
1149 | return *E; |
1150 | } |
1151 | |
1152 | private: |
1153 | void checkError(Error Err) const { |
1154 | if (Err) { |
1155 | int ExitCode = GetExitCode(Err); |
1156 | logAllUnhandledErrors(std::move(Err), errs(), Banner); |
1157 | exit(ExitCode); |
1158 | } |
1159 | } |
1160 | |
1161 | std::string Banner; |
1162 | std::function<int(const Error &)> GetExitCode; |
1163 | }; |
1164 | |
1165 | } // end namespace llvm |
1166 | |
1167 | #endif // LLVM_SUPPORT_ERROR_H |