Bug Summary

File:tools/lli/lli.cpp
Warning:line 945, column 33
2nd function call argument is an uninitialized value

Annotated Source Code

/build/llvm-toolchain-snapshot-6.0~svn319013/tools/lli/lli.cpp

1//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===//
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 utility provides a simple wrapper around the LLVM Execution Engines,
11// which allow the direct execution of LLVM programs through a Just-In-Time
12// compiler, or through an interpreter if no JIT is available for this platform.
13//
14//===----------------------------------------------------------------------===//
15
16#include "OrcLazyJIT.h"
17#include "RemoteJITUtils.h"
18#include "llvm/ADT/StringExtras.h"
19#include "llvm/ADT/Triple.h"
20#include "llvm/Bitcode/BitcodeReader.h"
21#include "llvm/CodeGen/CommandFlags.h"
22#include "llvm/CodeGen/LinkAllCodegenComponents.h"
23#include "llvm/ExecutionEngine/GenericValue.h"
24#include "llvm/ExecutionEngine/Interpreter.h"
25#include "llvm/ExecutionEngine/JITEventListener.h"
26#include "llvm/ExecutionEngine/MCJIT.h"
27#include "llvm/ExecutionEngine/ObjectCache.h"
28#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
29#include "llvm/ExecutionEngine/OrcMCJITReplacement.h"
30#include "llvm/ExecutionEngine/SectionMemoryManager.h"
31#include "llvm/IR/IRBuilder.h"
32#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/Type.h"
35#include "llvm/IR/TypeBuilder.h"
36#include "llvm/IRReader/IRReader.h"
37#include "llvm/Object/Archive.h"
38#include "llvm/Object/ObjectFile.h"
39#include "llvm/Support/CommandLine.h"
40#include "llvm/Support/Debug.h"
41#include "llvm/Support/DynamicLibrary.h"
42#include "llvm/Support/Format.h"
43#include "llvm/Support/ManagedStatic.h"
44#include "llvm/Support/MathExtras.h"
45#include "llvm/Support/Memory.h"
46#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/PluginLoader.h"
49#include "llvm/Support/PrettyStackTrace.h"
50#include "llvm/Support/Process.h"
51#include "llvm/Support/Program.h"
52#include "llvm/Support/Signals.h"
53#include "llvm/Support/SourceMgr.h"
54#include "llvm/Support/TargetSelect.h"
55#include "llvm/Support/raw_ostream.h"
56#include "llvm/Transforms/Instrumentation.h"
57#include <cerrno>
58
59#ifdef __CYGWIN__
60#include <cygwin/version.h>
61#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
62#define DO_NOTHING_ATEXIT 1
63#endif
64#endif
65
66using namespace llvm;
67
68#define DEBUG_TYPE"lli" "lli"
69
70namespace {
71
72 enum class JITKind { MCJIT, OrcMCJITReplacement, OrcLazy };
73
74 cl::opt<std::string>
75 InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-"));
76
77 cl::list<std::string>
78 InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>..."));
79
80 cl::opt<bool> ForceInterpreter("force-interpreter",
81 cl::desc("Force interpretation: disable JIT"),
82 cl::init(false));
83
84 cl::opt<JITKind> UseJITKind("jit-kind",
85 cl::desc("Choose underlying JIT kind."),
86 cl::init(JITKind::MCJIT),
87 cl::values(
88 clEnumValN(JITKind::MCJIT, "mcjit",llvm::cl::OptionEnumValue { "mcjit", int(JITKind::MCJIT), "MCJIT"
}
89 "MCJIT")llvm::cl::OptionEnumValue { "mcjit", int(JITKind::MCJIT), "MCJIT"
}
,
90 clEnumValN(JITKind::OrcMCJITReplacement,llvm::cl::OptionEnumValue { "orc-mcjit", int(JITKind::OrcMCJITReplacement
), "Orc-based MCJIT replacement" }
91 "orc-mcjit",llvm::cl::OptionEnumValue { "orc-mcjit", int(JITKind::OrcMCJITReplacement
), "Orc-based MCJIT replacement" }
92 "Orc-based MCJIT replacement")llvm::cl::OptionEnumValue { "orc-mcjit", int(JITKind::OrcMCJITReplacement
), "Orc-based MCJIT replacement" }
,
93 clEnumValN(JITKind::OrcLazy,llvm::cl::OptionEnumValue { "orc-lazy", int(JITKind::OrcLazy)
, "Orc-based lazy JIT." }
94 "orc-lazy",llvm::cl::OptionEnumValue { "orc-lazy", int(JITKind::OrcLazy)
, "Orc-based lazy JIT." }
95 "Orc-based lazy JIT.")llvm::cl::OptionEnumValue { "orc-lazy", int(JITKind::OrcLazy)
, "Orc-based lazy JIT." }
));
96
97 // The MCJIT supports building for a target address space separate from
98 // the JIT compilation process. Use a forked process and a copying
99 // memory manager with IPC to execute using this functionality.
100 cl::opt<bool> RemoteMCJIT("remote-mcjit",
101 cl::desc("Execute MCJIT'ed code in a separate process."),
102 cl::init(false));
103
104 // Manually specify the child process for remote execution. This overrides
105 // the simulated remote execution that allocates address space for child
106 // execution. The child process will be executed and will communicate with
107 // lli via stdin/stdout pipes.
108 cl::opt<std::string>
109 ChildExecPath("mcjit-remote-process",
110 cl::desc("Specify the filename of the process to launch "
111 "for remote MCJIT execution. If none is specified,"
112 "\n\tremote execution will be simulated in-process."),
113 cl::value_desc("filename"), cl::init(""));
114
115 // Determine optimization level.
116 cl::opt<char>
117 OptLevel("O",
118 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
119 "(default = '-O2')"),
120 cl::Prefix,
121 cl::ZeroOrMore,
122 cl::init(' '));
123
124 cl::opt<std::string>
125 TargetTriple("mtriple", cl::desc("Override target triple for module"));
126
127 cl::opt<std::string>
128 EntryFunc("entry-function",
129 cl::desc("Specify the entry function (default = 'main') "
130 "of the executable"),
131 cl::value_desc("function"),
132 cl::init("main"));
133
134 cl::list<std::string>
135 ExtraModules("extra-module",
136 cl::desc("Extra modules to be loaded"),
137 cl::value_desc("input bitcode"));
138
139 cl::list<std::string>
140 ExtraObjects("extra-object",
141 cl::desc("Extra object files to be loaded"),
142 cl::value_desc("input object"));
143
144 cl::list<std::string>
145 ExtraArchives("extra-archive",
146 cl::desc("Extra archive files to be loaded"),
147 cl::value_desc("input archive"));
148
149 cl::opt<bool>
150 EnableCacheManager("enable-cache-manager",
151 cl::desc("Use cache manager to save/load mdoules"),
152 cl::init(false));
153
154 cl::opt<std::string>
155 ObjectCacheDir("object-cache-dir",
156 cl::desc("Directory to store cached object files "
157 "(must be user writable)"),
158 cl::init(""));
159
160 cl::opt<std::string>
161 FakeArgv0("fake-argv0",
162 cl::desc("Override the 'argv[0]' value passed into the executing"
163 " program"), cl::value_desc("executable"));
164
165 cl::opt<bool>
166 DisableCoreFiles("disable-core-files", cl::Hidden,
167 cl::desc("Disable emission of core files if possible"));
168
169 cl::opt<bool>
170 NoLazyCompilation("disable-lazy-compilation",
171 cl::desc("Disable JIT lazy compilation"),
172 cl::init(false));
173
174 cl::opt<bool>
175 GenerateSoftFloatCalls("soft-float",
176 cl::desc("Generate software floating point library calls"),
177 cl::init(false));
178
179 ExitOnError ExitOnErr;
180}
181
182//===----------------------------------------------------------------------===//
183// Object cache
184//
185// This object cache implementation writes cached objects to disk to the
186// directory specified by CacheDir, using a filename provided in the module
187// descriptor. The cache tries to load a saved object using that path if the
188// file exists. CacheDir defaults to "", in which case objects are cached
189// alongside their originating bitcodes.
190//
191class LLIObjectCache : public ObjectCache {
192public:
193 LLIObjectCache(const std::string& CacheDir) : CacheDir(CacheDir) {
194 // Add trailing '/' to cache dir if necessary.
195 if (!this->CacheDir.empty() &&
196 this->CacheDir[this->CacheDir.size() - 1] != '/')
197 this->CacheDir += '/';
198 }
199 ~LLIObjectCache() override {}
200
201 void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
202 const std::string &ModuleID = M->getModuleIdentifier();
203 std::string CacheName;
204 if (!getCacheFilename(ModuleID, CacheName))
205 return;
206 if (!CacheDir.empty()) { // Create user-defined cache dir.
207 SmallString<128> dir(sys::path::parent_path(CacheName));
208 sys::fs::create_directories(Twine(dir));
209 }
210 std::error_code EC;
211 raw_fd_ostream outfile(CacheName, EC, sys::fs::F_None);
212 outfile.write(Obj.getBufferStart(), Obj.getBufferSize());
213 outfile.close();
214 }
215
216 std::unique_ptr<MemoryBuffer> getObject(const Module* M) override {
217 const std::string &ModuleID = M->getModuleIdentifier();
218 std::string CacheName;
219 if (!getCacheFilename(ModuleID, CacheName))
220 return nullptr;
221 // Load the object from the cache filename
222 ErrorOr<std::unique_ptr<MemoryBuffer>> IRObjectBuffer =
223 MemoryBuffer::getFile(CacheName, -1, false);
224 // If the file isn't there, that's OK.
225 if (!IRObjectBuffer)
226 return nullptr;
227 // MCJIT will want to write into this buffer, and we don't want that
228 // because the file has probably just been mmapped. Instead we make
229 // a copy. The filed-based buffer will be released when it goes
230 // out of scope.
231 return MemoryBuffer::getMemBufferCopy(IRObjectBuffer.get()->getBuffer());
232 }
233
234private:
235 std::string CacheDir;
236
237 bool getCacheFilename(const std::string &ModID, std::string &CacheName) {
238 std::string Prefix("file:");
239 size_t PrefixLength = Prefix.length();
240 if (ModID.substr(0, PrefixLength) != Prefix)
241 return false;
242 std::string CacheSubdir = ModID.substr(PrefixLength);
243#if defined(_WIN32)
244 // Transform "X:\foo" => "/X\foo" for convenience.
245 if (isalpha(CacheSubdir[0]) && CacheSubdir[1] == ':') {
246 CacheSubdir[1] = CacheSubdir[0];
247 CacheSubdir[0] = '/';
248 }
249#endif
250 CacheName = CacheDir + CacheSubdir;
251 size_t pos = CacheName.rfind('.');
252 CacheName.replace(pos, CacheName.length() - pos, ".o");
253 return true;
254 }
255};
256
257// On Mingw and Cygwin, an external symbol named '__main' is called from the
258// generated 'main' function to allow static initialization. To avoid linking
259// problems with remote targets (because lli's remote target support does not
260// currently handle external linking) we add a secondary module which defines
261// an empty '__main' function.
262static void addCygMingExtraModule(ExecutionEngine &EE, LLVMContext &Context,
263 StringRef TargetTripleStr) {
264 IRBuilder<> Builder(Context);
265 Triple TargetTriple(TargetTripleStr);
266
267 // Create a new module.
268 std::unique_ptr<Module> M = make_unique<Module>("CygMingHelper", Context);
269 M->setTargetTriple(TargetTripleStr);
270
271 // Create an empty function named "__main".
272 Function *Result;
273 if (TargetTriple.isArch64Bit()) {
274 Result = Function::Create(
275 TypeBuilder<int64_t(void), false>::get(Context),
276 GlobalValue::ExternalLinkage, "__main", M.get());
277 } else {
278 Result = Function::Create(
279 TypeBuilder<int32_t(void), false>::get(Context),
280 GlobalValue::ExternalLinkage, "__main", M.get());
281 }
282 BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
283 Builder.SetInsertPoint(BB);
284 Value *ReturnVal;
285 if (TargetTriple.isArch64Bit())
286 ReturnVal = ConstantInt::get(Context, APInt(64, 0));
287 else
288 ReturnVal = ConstantInt::get(Context, APInt(32, 0));
289 Builder.CreateRet(ReturnVal);
290
291 // Add this new module to the ExecutionEngine.
292 EE.addModule(std::move(M));
293}
294
295CodeGenOpt::Level getOptLevel() {
296 switch (OptLevel) {
297 default:
298 errs() << "lli: Invalid optimization level.\n";
299 exit(1);
300 case '0': return CodeGenOpt::None;
301 case '1': return CodeGenOpt::Less;
302 case ' ':
303 case '2': return CodeGenOpt::Default;
304 case '3': return CodeGenOpt::Aggressive;
305 }
306 llvm_unreachable("Unrecognized opt level.")::llvm::llvm_unreachable_internal("Unrecognized opt level.", "/build/llvm-toolchain-snapshot-6.0~svn319013/tools/lli/lli.cpp"
, 306)
;
307}
308
309LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
310static void reportError(SMDiagnostic Err, const char *ProgName) {
311 Err.print(ProgName, errs());
312 exit(1);
313}
314
315//===----------------------------------------------------------------------===//
316// main Driver function
317//
318int main(int argc, char **argv, char * const *envp) {
319 sys::PrintStackTraceOnErrorSignal(argv[0]);
320 PrettyStackTraceProgram X(argc, argv);
321
322 atexit(llvm_shutdown); // Call llvm_shutdown() on exit.
323
324 if (argc > 1)
1
Assuming 'argc' is <= 1
2
Taking false branch
325 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
326
327 // If we have a native target, initialize it to ensure it is linked in and
328 // usable by the JIT.
329 InitializeNativeTarget();
330 InitializeNativeTargetAsmPrinter();
331 InitializeNativeTargetAsmParser();
332
333 cl::ParseCommandLineOptions(argc, argv,
334 "llvm interpreter & dynamic compiler\n");
335
336 // If the user doesn't want core files, disable them.
337 if (DisableCoreFiles)
3
Assuming the condition is false
4
Taking false branch
338 sys::Process::PreventCoreFiles();
339
340 LLVMContext Context;
341
342 // Load the bitcode...
343 SMDiagnostic Err;
344 std::unique_ptr<Module> Owner = parseIRFile(InputFile, Err, Context);
345 Module *Mod = Owner.get();
346 if (!Mod)
5
Assuming 'Mod' is non-null
6
Taking false branch
347 reportError(Err, argv[0]);
348
349 if (UseJITKind == JITKind::OrcLazy) {
7
Assuming the condition is false
8
Taking false branch
350 std::vector<std::unique_ptr<Module>> Ms;
351 Ms.push_back(std::move(Owner));
352 for (auto &ExtraMod : ExtraModules) {
353 Ms.push_back(parseIRFile(ExtraMod, Err, Context));
354 if (!Ms.back())
355 reportError(Err, argv[0]);
356 }
357 std::vector<std::string> Args;
358 Args.push_back(InputFile);
359 for (auto &Arg : InputArgv)
360 Args.push_back(Arg);
361 return runOrcLazyJIT(std::move(Ms), Args);
362 }
363
364 if (EnableCacheManager) {
9
Assuming the condition is false
10
Taking false branch
365 std::string CacheName("file:");
366 CacheName.append(InputFile);
367 Mod->setModuleIdentifier(CacheName);
368 }
369
370 // If not jitting lazily, load the whole bitcode file eagerly too.
371 if (NoLazyCompilation) {
11
Assuming the condition is false
12
Taking false branch
372 // Use *argv instead of argv[0] to work around a wrong GCC warning.
373 ExitOnError ExitOnErr(std::string(*argv) +
374 ": bitcode didn't read correctly: ");
375 ExitOnErr(Mod->materializeAll());
376 }
377
378 std::string ErrorMsg;
379 EngineBuilder builder(std::move(Owner));
380 builder.setMArch(MArch);
381 builder.setMCPU(MCPU);
382 builder.setMAttrs(MAttrs);
383 if (RelocModel.getNumOccurrences())
13
Assuming the condition is false
14
Taking false branch
384 builder.setRelocationModel(RelocModel);
385 if (CMModel.getNumOccurrences())
15
Assuming the condition is false
16
Taking false branch
386 builder.setCodeModel(CMModel);
387 builder.setErrorStr(&ErrorMsg);
388 builder.setEngineKind(ForceInterpreter
17
Assuming the condition is false
18
'?' condition is false
389 ? EngineKind::Interpreter
390 : EngineKind::JIT);
391 builder.setUseOrcMCJITReplacement(UseJITKind == JITKind::OrcMCJITReplacement);
19
Assuming the condition is false
392
393 // If we are supposed to override the target triple, do so now.
394 if (!TargetTriple.empty())
20
Assuming the condition is false
21
Taking false branch
395 Mod->setTargetTriple(Triple::normalize(TargetTriple));
396
397 // Enable MCJIT if desired.
398 RTDyldMemoryManager *RTDyldMM = nullptr;
399 if (!ForceInterpreter) {
22
Taking true branch
400 if (RemoteMCJIT)
23
Assuming the condition is false
24
Taking false branch
401 RTDyldMM = new ForwardingMemoryManager();
402 else
403 RTDyldMM = new SectionMemoryManager();
404
405 // Deliberately construct a temp std::unique_ptr to pass in. Do not null out
406 // RTDyldMM: We still use it below, even though we don't own it.
407 builder.setMCJITMemoryManager(
408 std::unique_ptr<RTDyldMemoryManager>(RTDyldMM));
409 } else if (RemoteMCJIT) {
410 errs() << "error: Remote process execution does not work with the "
411 "interpreter.\n";
412 exit(1);
413 }
414
415 builder.setOptLevel(getOptLevel());
416
417 TargetOptions Options;
418 if (FloatABIForCalls != FloatABI::Default)
25
Assuming the condition is false
26
Taking false branch
419 Options.FloatABIType = FloatABIForCalls;
420
421 builder.setTargetOptions(Options);
422
423 std::unique_ptr<ExecutionEngine> EE(builder.create());
424 if (!EE) {
27
Taking false branch
425 if (!ErrorMsg.empty())
426 errs() << argv[0] << ": error creating EE: " << ErrorMsg << "\n";
427 else
428 errs() << argv[0] << ": unknown error creating EE!\n";
429 exit(1);
430 }
431
432 std::unique_ptr<LLIObjectCache> CacheManager;
433 if (EnableCacheManager) {
28
Assuming the condition is false
29
Taking false branch
434 CacheManager.reset(new LLIObjectCache(ObjectCacheDir));
435 EE->setObjectCache(CacheManager.get());
436 }
437
438 // Load any additional modules specified on the command line.
439 for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) {
30
Assuming 'i' is equal to 'e'
31
Loop condition is false. Execution continues on line 451
440 std::unique_ptr<Module> XMod = parseIRFile(ExtraModules[i], Err, Context);
441 if (!XMod)
442 reportError(Err, argv[0]);
443 if (EnableCacheManager) {
444 std::string CacheName("file:");
445 CacheName.append(ExtraModules[i]);
446 XMod->setModuleIdentifier(CacheName);
447 }
448 EE->addModule(std::move(XMod));
449 }
450
451 for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) {
32
Assuming 'i' is equal to 'e'
33
Loop condition is false. Execution continues on line 463
452 Expected<object::OwningBinary<object::ObjectFile>> Obj =
453 object::ObjectFile::createObjectFile(ExtraObjects[i]);
454 if (!Obj) {
455 // TODO: Actually report errors helpfully.
456 consumeError(Obj.takeError());
457 reportError(Err, argv[0]);
458 }
459 object::OwningBinary<object::ObjectFile> &O = Obj.get();
460 EE->addObjectFile(std::move(O));
461 }
462
463 for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) {
34
Assuming 'i' is equal to 'e'
35
Loop condition is false. Execution continues on line 489
464 ErrorOr<std::unique_ptr<MemoryBuffer>> ArBufOrErr =
465 MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]);
466 if (!ArBufOrErr)
467 reportError(Err, argv[0]);
468 std::unique_ptr<MemoryBuffer> &ArBuf = ArBufOrErr.get();
469
470 Expected<std::unique_ptr<object::Archive>> ArOrErr =
471 object::Archive::create(ArBuf->getMemBufferRef());
472 if (!ArOrErr) {
473 std::string Buf;
474 raw_string_ostream OS(Buf);
475 logAllUnhandledErrors(ArOrErr.takeError(), OS, "");
476 OS.flush();
477 errs() << Buf;
478 exit(1);
479 }
480 std::unique_ptr<object::Archive> &Ar = ArOrErr.get();
481
482 object::OwningBinary<object::Archive> OB(std::move(Ar), std::move(ArBuf));
483
484 EE->addArchive(std::move(OB));
485 }
486
487 // If the target is Cygwin/MingW and we are generating remote code, we
488 // need an extra module to help out with linking.
489 if (RemoteMCJIT && Triple(Mod->getTargetTriple()).isOSCygMing()) {
36
Assuming the condition is false
37
Taking false branch
490 addCygMingExtraModule(*EE, Context, Mod->getTargetTriple());
491 }
492
493 // The following functions have no effect if their respective profiling
494 // support wasn't enabled in the build configuration.
495 EE->RegisterJITEventListener(
496 JITEventListener::createOProfileJITEventListener());
497 EE->RegisterJITEventListener(
498 JITEventListener::createIntelJITEventListener());
499
500 if (!NoLazyCompilation && RemoteMCJIT) {
38
Assuming the condition is false
501 errs() << "warning: remote mcjit does not support lazy compilation\n";
502 NoLazyCompilation = true;
503 }
504 EE->DisableLazyCompilation(NoLazyCompilation);
505
506 // If the user specifically requested an argv[0] to pass into the program,
507 // do it now.
508 if (!FakeArgv0.empty()) {
39
Assuming the condition is false
40
Taking false branch
509 InputFile = static_cast<std::string>(FakeArgv0);
510 } else {
511 // Otherwise, if there is a .bc suffix on the executable strip it off, it
512 // might confuse the program.
513 if (StringRef(InputFile).endswith(".bc"))
41
Assuming the condition is false
42
Taking false branch
514 InputFile.erase(InputFile.length() - 3);
515 }
516
517 // Add the module's name to the start of the vector of arguments to main().
518 InputArgv.insert(InputArgv.begin(), InputFile);
519
520 // Call the main function from M as if its signature were:
521 // int main (int argc, char **argv, const char **envp)
522 // using the contents of Args to determine argc & argv, and the contents of
523 // EnvVars to determine envp.
524 //
525 Function *EntryFn = Mod->getFunction(EntryFunc);
526 if (!EntryFn) {
43
Assuming 'EntryFn' is non-null
44
Taking false branch
527 errs() << '\'' << EntryFunc << "\' function not found in module.\n";
528 return -1;
529 }
530
531 // Reset errno to zero on entry to main.
532 errno(*__errno_location ()) = 0;
533
534 int Result = -1;
535
536 // Sanity check use of remote-jit: LLI currently only supports use of the
537 // remote JIT on Unix platforms.
538 if (RemoteMCJIT) {
45
Assuming the condition is true
46
Taking true branch
539#ifndef LLVM_ON_UNIX1
540 errs() << "Warning: host does not support external remote targets.\n"
541 << " Defaulting to local execution\n";
542 return -1;
543#else
544 if (ChildExecPath.empty()) {
47
Assuming the condition is false
48
Taking false branch
545 errs() << "-remote-mcjit requires -mcjit-remote-process.\n";
546 exit(1);
547 } else if (!sys::fs::can_execute(ChildExecPath)) {
49
Assuming the condition is false
50
Taking false branch
548 errs() << "Unable to find usable child executable: '" << ChildExecPath
549 << "'\n";
550 return -1;
551 }
552#endif
553 }
554
555 if (!RemoteMCJIT) {
51
Assuming the condition is false
52
Taking false branch
556 // If the program doesn't explicitly call exit, we will need the Exit
557 // function later on to make an explicit call, so get the function now.
558 Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context),
559 Type::getInt32Ty(Context));
560
561 // Run static constructors.
562 if (!ForceInterpreter) {
563 // Give MCJIT a chance to apply relocations and set page permissions.
564 EE->finalizeObject();
565 }
566 EE->runStaticConstructorsDestructors(false);
567
568 // Trigger compilation separately so code regions that need to be
569 // invalidated will be known.
570 (void)EE->getPointerToFunction(EntryFn);
571 // Clear instruction cache before code will be executed.
572 if (RTDyldMM)
573 static_cast<SectionMemoryManager*>(RTDyldMM)->invalidateInstructionCache();
574
575 // Run main.
576 Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);
577
578 // Run static destructors.
579 EE->runStaticConstructorsDestructors(true);
580
581 // If the program didn't call exit explicitly, we should call it now.
582 // This ensures that any atexit handlers get called correctly.
583 if (Function *ExitF = dyn_cast<Function>(Exit)) {
584 std::vector<GenericValue> Args;
585 GenericValue ResultGV;
586 ResultGV.IntVal = APInt(32, Result);
587 Args.push_back(ResultGV);
588 EE->runFunction(ExitF, Args);
589 errs() << "ERROR: exit(" << Result << ") returned!\n";
590 abort();
591 } else {
592 errs() << "ERROR: exit defined with wrong prototype!\n";
593 abort();
594 }
595 } else {
596 // else == "if (RemoteMCJIT)"
597
598 // Remote target MCJIT doesn't (yet) support static constructors. No reason
599 // it couldn't. This is a limitation of the LLI implementation, not the
600 // MCJIT itself. FIXME.
601
602 // Lanch the remote process and get a channel to it.
603 std::unique_ptr<FDRawChannel> C = launchRemote();
604 if (!C) {
53
Taking false branch
605 errs() << "Failed to launch remote JIT.\n";
606 exit(1);
607 }
608
609 // Create a remote target client running over the channel.
610 typedef orc::remote::OrcRemoteTargetClient MyRemote;
611 auto R = ExitOnErr(MyRemote::Create(*C, ExitOnErr));
612
613 // Create a remote memory manager.
614 auto RemoteMM = ExitOnErr(R->createRemoteMemoryManager());
615
616 // Forward MCJIT's memory manager calls to the remote memory manager.
617 static_cast<ForwardingMemoryManager*>(RTDyldMM)->setMemMgr(
618 std::move(RemoteMM));
619
620 // Forward MCJIT's symbol resolution calls to the remote.
621 static_cast<ForwardingMemoryManager *>(RTDyldMM)->setResolver(
622 orc::createLambdaResolver(
623 [](const std::string &Name) { return nullptr; },
624 [&](const std::string &Name) {
625 if (auto Addr = ExitOnErr(R->getSymbolAddress(Name)))
626 return JITSymbol(Addr, JITSymbolFlags::Exported);
627 return JITSymbol(nullptr);
628 }));
629
630 // Grab the target address of the JIT'd main function on the remote and call
631 // it.
632 // FIXME: argv and envp handling.
633 JITTargetAddress Entry = EE->getFunctionAddress(EntryFn->getName().str());
634 EE->finalizeObject();
635 DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Executing '" << EntryFn->
getName() << "' at 0x" << format("%llx", Entry) <<
"\n"; } } while (false)
636 << format("%llx", Entry) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Executing '" << EntryFn->
getName() << "' at 0x" << format("%llx", Entry) <<
"\n"; } } while (false)
;
637 Result = ExitOnErr(R->callIntVoid(Entry));
638
639 // Like static constructors, the remote target MCJIT support doesn't handle
640 // this yet. It could. FIXME.
641
642 // Delete the EE - we need to tear it down *before* we terminate the session
643 // with the remote, otherwise it'll crash when it tries to release resources
644 // on a remote that has already been disconnected.
645 EE.reset();
646
647 // Signal the remote target that we're done JITing.
648 ExitOnErr(R->terminateSession());
54
Calling 'OrcRemoteTargetClient::terminateSession'
649 }
650
651 return Result;
652}
653
654std::unique_ptr<FDRawChannel> launchRemote() {
655#ifndef LLVM_ON_UNIX1
656 llvm_unreachable("launchRemote not supported on non-Unix platforms")::llvm::llvm_unreachable_internal("launchRemote not supported on non-Unix platforms"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/tools/lli/lli.cpp"
, 656)
;
657#else
658 int PipeFD[2][2];
659 pid_t ChildPID;
660
661 // Create two pipes.
662 if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0)
663 perror("Error creating pipe: ");
664
665 ChildPID = fork();
666
667 if (ChildPID == 0) {
668 // In the child...
669
670 // Close the parent ends of the pipes
671 close(PipeFD[0][1]);
672 close(PipeFD[1][0]);
673
674
675 // Execute the child process.
676 std::unique_ptr<char[]> ChildPath, ChildIn, ChildOut;
677 {
678 ChildPath.reset(new char[ChildExecPath.size() + 1]);
679 std::copy(ChildExecPath.begin(), ChildExecPath.end(), &ChildPath[0]);
680 ChildPath[ChildExecPath.size()] = '\0';
681 std::string ChildInStr = utostr(PipeFD[0][0]);
682 ChildIn.reset(new char[ChildInStr.size() + 1]);
683 std::copy(ChildInStr.begin(), ChildInStr.end(), &ChildIn[0]);
684 ChildIn[ChildInStr.size()] = '\0';
685 std::string ChildOutStr = utostr(PipeFD[1][1]);
686 ChildOut.reset(new char[ChildOutStr.size() + 1]);
687 std::copy(ChildOutStr.begin(), ChildOutStr.end(), &ChildOut[0]);
688 ChildOut[ChildOutStr.size()] = '\0';
689 }
690
691 char * const args[] = { &ChildPath[0], &ChildIn[0], &ChildOut[0], nullptr };
692 int rc = execv(ChildExecPath.c_str(), args);
693 if (rc != 0)
694 perror("Error executing child process: ");
695 llvm_unreachable("Error executing child process")::llvm::llvm_unreachable_internal("Error executing child process"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/tools/lli/lli.cpp"
, 695)
;
696 }
697 // else we're the parent...
698
699 // Close the child ends of the pipes
700 close(PipeFD[0][0]);
701 close(PipeFD[1][1]);
702
703 // Return an RPC channel connected to our end of the pipes.
704 return llvm::make_unique<FDRawChannel>(PipeFD[1][0], PipeFD[0][1]);
705#endif
706}

/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h

1//===- OrcRemoteTargetClient.h - Orc Remote-target Client -------*- 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 the OrcRemoteTargetClient class and helpers. This class
11// can be used to communicate over an RawByteChannel with an
12// OrcRemoteTargetServer instance to support remote-JITing.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
17#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
18
19#include "llvm/ADT/Optional.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/StringMap.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/ExecutionEngine/JITSymbol.h"
24#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
25#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
26#include "llvm/ExecutionEngine/RuntimeDyld.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Support/Error.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Support/Format.h"
31#include "llvm/Support/MathExtras.h"
32#include "llvm/Support/Memory.h"
33#include "llvm/Support/raw_ostream.h"
34#include <algorithm>
35#include <cassert>
36#include <cstdint>
37#include <memory>
38#include <string>
39#include <tuple>
40#include <utility>
41#include <vector>
42
43#define DEBUG_TYPE"lli" "orc-remote"
44
45namespace llvm {
46namespace orc {
47namespace remote {
48
49/// This class provides utilities (including memory manager, indirect stubs
50/// manager, and compile callback manager types) that support remote JITing
51/// in ORC.
52///
53/// Each of the utility classes talks to a JIT server (an instance of the
54/// OrcRemoteTargetServer class) via an RPC system (see RPCUtils.h) to carry out
55/// its actions.
56class OrcRemoteTargetClient
57 : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
58public:
59 /// Remote-mapped RuntimeDyld-compatible memory manager.
60 class RemoteRTDyldMemoryManager : public RuntimeDyld::MemoryManager {
61 friend class OrcRemoteTargetClient;
62
63 public:
64 ~RemoteRTDyldMemoryManager() {
65 Client.destroyRemoteAllocator(Id);
66 DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Destroyed remote allocator " <<
Id << "\n"; } } while (false)
;
67 }
68
69 RemoteRTDyldMemoryManager(const RemoteRTDyldMemoryManager &) = delete;
70 RemoteRTDyldMemoryManager &
71 operator=(const RemoteRTDyldMemoryManager &) = delete;
72 RemoteRTDyldMemoryManager(RemoteRTDyldMemoryManager &&) = default;
73 RemoteRTDyldMemoryManager &
74 operator=(RemoteRTDyldMemoryManager &&) = default;
75
76 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
77 unsigned SectionID,
78 StringRef SectionName) override {
79 Unmapped.back().CodeAllocs.emplace_back(Size, Alignment);
80 uint8_t *Alloc = reinterpret_cast<uint8_t *>(
81 Unmapped.back().CodeAllocs.back().getLocalAddress());
82 DEBUG(dbgs() << "Allocator " << Id << " allocated code for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated code for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
83 << SectionName << ": " << Alloc << " (" << Sizedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated code for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
84 << " bytes, alignment " << Alignment << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated code for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
;
85 return Alloc;
86 }
87
88 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
89 unsigned SectionID, StringRef SectionName,
90 bool IsReadOnly) override {
91 if (IsReadOnly) {
92 Unmapped.back().RODataAllocs.emplace_back(Size, Alignment);
93 uint8_t *Alloc = reinterpret_cast<uint8_t *>(
94 Unmapped.back().RODataAllocs.back().getLocalAddress());
95 DEBUG(dbgs() << "Allocator " << Id << " allocated ro-data for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated ro-data for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
96 << SectionName << ": " << Alloc << " (" << Sizedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated ro-data for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
97 << " bytes, alignment " << Alignment << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated ro-data for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
;
98 return Alloc;
99 } // else...
100
101 Unmapped.back().RWDataAllocs.emplace_back(Size, Alignment);
102 uint8_t *Alloc = reinterpret_cast<uint8_t *>(
103 Unmapped.back().RWDataAllocs.back().getLocalAddress());
104 DEBUG(dbgs() << "Allocator " << Id << " allocated rw-data for "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated rw-data for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
105 << SectionName << ": " << Alloc << " (" << Sizedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated rw-data for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
106 << " bytes, alignment " << Alignment << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " allocated rw-data for "
<< SectionName << ": " << Alloc << " ("
<< Size << " bytes, alignment " << Alignment
<< ")\n"; } } while (false)
;
107 return Alloc;
108 }
109
110 void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
111 uintptr_t RODataSize, uint32_t RODataAlign,
112 uintptr_t RWDataSize,
113 uint32_t RWDataAlign) override {
114 Unmapped.push_back(ObjectAllocs());
115
116 DEBUG(dbgs() << "Allocator " << Id << " reserved:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " reserved:\n"
; } } while (false)
;
117
118 if (CodeSize != 0) {
119 Unmapped.back().RemoteCodeAddr =
120 Client.reserveMem(Id, CodeSize, CodeAlign);
121
122 DEBUG(dbgs() << " code: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " code: " << format("0x%016x"
, Unmapped.back().RemoteCodeAddr) << " (" << CodeSize
<< " bytes, alignment " << CodeAlign << ")\n"
; } } while (false)
123 << format("0x%016x", Unmapped.back().RemoteCodeAddr)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " code: " << format("0x%016x"
, Unmapped.back().RemoteCodeAddr) << " (" << CodeSize
<< " bytes, alignment " << CodeAlign << ")\n"
; } } while (false)
124 << " (" << CodeSize << " bytes, alignment " << CodeAligndo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " code: " << format("0x%016x"
, Unmapped.back().RemoteCodeAddr) << " (" << CodeSize
<< " bytes, alignment " << CodeAlign << ")\n"
; } } while (false)
125 << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " code: " << format("0x%016x"
, Unmapped.back().RemoteCodeAddr) << " (" << CodeSize
<< " bytes, alignment " << CodeAlign << ")\n"
; } } while (false)
;
126 }
127
128 if (RODataSize != 0) {
129 Unmapped.back().RemoteRODataAddr =
130 Client.reserveMem(Id, RODataSize, RODataAlign);
131
132 DEBUG(dbgs() << " ro-data: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " ro-data: " << format("0x%016x"
, Unmapped.back().RemoteRODataAddr) << " (" << RODataSize
<< " bytes, alignment " << RODataAlign << ")\n"
; } } while (false)
133 << format("0x%016x", Unmapped.back().RemoteRODataAddr)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " ro-data: " << format("0x%016x"
, Unmapped.back().RemoteRODataAddr) << " (" << RODataSize
<< " bytes, alignment " << RODataAlign << ")\n"
; } } while (false)
134 << " (" << RODataSize << " bytes, alignment "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " ro-data: " << format("0x%016x"
, Unmapped.back().RemoteRODataAddr) << " (" << RODataSize
<< " bytes, alignment " << RODataAlign << ")\n"
; } } while (false)
135 << RODataAlign << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " ro-data: " << format("0x%016x"
, Unmapped.back().RemoteRODataAddr) << " (" << RODataSize
<< " bytes, alignment " << RODataAlign << ")\n"
; } } while (false)
;
136 }
137
138 if (RWDataSize != 0) {
139 Unmapped.back().RemoteRWDataAddr =
140 Client.reserveMem(Id, RWDataSize, RWDataAlign);
141
142 DEBUG(dbgs() << " rw-data: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " rw-data: " << format("0x%016x"
, Unmapped.back().RemoteRWDataAddr) << " (" << RWDataSize
<< " bytes, alignment " << RWDataAlign << ")\n"
; } } while (false)
143 << format("0x%016x", Unmapped.back().RemoteRWDataAddr)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " rw-data: " << format("0x%016x"
, Unmapped.back().RemoteRWDataAddr) << " (" << RWDataSize
<< " bytes, alignment " << RWDataAlign << ")\n"
; } } while (false)
144 << " (" << RWDataSize << " bytes, alignment "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " rw-data: " << format("0x%016x"
, Unmapped.back().RemoteRWDataAddr) << " (" << RWDataSize
<< " bytes, alignment " << RWDataAlign << ")\n"
; } } while (false)
145 << RWDataAlign << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " rw-data: " << format("0x%016x"
, Unmapped.back().RemoteRWDataAddr) << " (" << RWDataSize
<< " bytes, alignment " << RWDataAlign << ")\n"
; } } while (false)
;
146 }
147 }
148
149 bool needsToReserveAllocationSpace() override { return true; }
150
151 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
152 size_t Size) override {
153 UnfinalizedEHFrames.push_back({LoadAddr, Size});
154 }
155
156 void deregisterEHFrames() override {
157 for (auto &Frame : RegisteredEHFrames) {
158 // FIXME: Add error poll.
159 Client.deregisterEHFrames(Frame.Addr, Frame.Size);
160 }
161 }
162
163 void notifyObjectLoaded(RuntimeDyld &Dyld,
164 const object::ObjectFile &Obj) override {
165 DEBUG(dbgs() << "Allocator " << Id << " applied mappings:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " applied mappings:\n"
; } } while (false)
;
166 for (auto &ObjAllocs : Unmapped) {
167 mapAllocsToRemoteAddrs(Dyld, ObjAllocs.CodeAllocs,
168 ObjAllocs.RemoteCodeAddr);
169 mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RODataAllocs,
170 ObjAllocs.RemoteRODataAddr);
171 mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RWDataAllocs,
172 ObjAllocs.RemoteRWDataAddr);
173 Unfinalized.push_back(std::move(ObjAllocs));
174 }
175 Unmapped.clear();
176 }
177
178 bool finalizeMemory(std::string *ErrMsg = nullptr) override {
179 DEBUG(dbgs() << "Allocator " << Id << " finalizing:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Allocator " << Id << " finalizing:\n"
; } } while (false)
;
180
181 for (auto &ObjAllocs : Unfinalized) {
182 if (copyAndProtect(ObjAllocs.CodeAllocs, ObjAllocs.RemoteCodeAddr,
183 sys::Memory::MF_READ | sys::Memory::MF_EXEC))
184 return true;
185
186 if (copyAndProtect(ObjAllocs.RODataAllocs, ObjAllocs.RemoteRODataAddr,
187 sys::Memory::MF_READ))
188 return true;
189
190 if (copyAndProtect(ObjAllocs.RWDataAllocs, ObjAllocs.RemoteRWDataAddr,
191 sys::Memory::MF_READ | sys::Memory::MF_WRITE))
192 return true;
193 }
194 Unfinalized.clear();
195
196 for (auto &EHFrame : UnfinalizedEHFrames) {
197 if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) {
198 // FIXME: Replace this once finalizeMemory can return an Error.
199 handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
200 if (ErrMsg) {
201 raw_string_ostream ErrOut(*ErrMsg);
202 EIB.log(ErrOut);
203 }
204 });
205 return false;
206 }
207 }
208 RegisteredEHFrames = std::move(UnfinalizedEHFrames);
209 UnfinalizedEHFrames = {};
210
211 return false;
212 }
213
214 private:
215 class Alloc {
216 public:
217 Alloc(uint64_t Size, unsigned Align)
218 : Size(Size), Align(Align), Contents(new char[Size + Align - 1]) {}
219
220 Alloc(const Alloc &) = delete;
221 Alloc &operator=(const Alloc &) = delete;
222 Alloc(Alloc &&) = default;
223 Alloc &operator=(Alloc &&) = default;
224
225 uint64_t getSize() const { return Size; }
226
227 unsigned getAlign() const { return Align; }
228
229 char *getLocalAddress() const {
230 uintptr_t LocalAddr = reinterpret_cast<uintptr_t>(Contents.get());
231 LocalAddr = alignTo(LocalAddr, Align);
232 return reinterpret_cast<char *>(LocalAddr);
233 }
234
235 void setRemoteAddress(JITTargetAddress RemoteAddr) {
236 this->RemoteAddr = RemoteAddr;
237 }
238
239 JITTargetAddress getRemoteAddress() const { return RemoteAddr; }
240
241 private:
242 uint64_t Size;
243 unsigned Align;
244 std::unique_ptr<char[]> Contents;
245 JITTargetAddress RemoteAddr = 0;
246 };
247
248 struct ObjectAllocs {
249 ObjectAllocs() = default;
250 ObjectAllocs(const ObjectAllocs &) = delete;
251 ObjectAllocs &operator=(const ObjectAllocs &) = delete;
252 ObjectAllocs(ObjectAllocs &&) = default;
253 ObjectAllocs &operator=(ObjectAllocs &&) = default;
254
255 JITTargetAddress RemoteCodeAddr = 0;
256 JITTargetAddress RemoteRODataAddr = 0;
257 JITTargetAddress RemoteRWDataAddr = 0;
258 std::vector<Alloc> CodeAllocs, RODataAllocs, RWDataAllocs;
259 };
260
261 RemoteRTDyldMemoryManager(OrcRemoteTargetClient &Client,
262 ResourceIdMgr::ResourceId Id)
263 : Client(Client), Id(Id) {
264 DEBUG(dbgs() << "Created remote allocator " << Id << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Created remote allocator " <<
Id << "\n"; } } while (false)
;
265 }
266
267 // Maps all allocations in Allocs to aligned blocks
268 void mapAllocsToRemoteAddrs(RuntimeDyld &Dyld, std::vector<Alloc> &Allocs,
269 JITTargetAddress NextAddr) {
270 for (auto &Alloc : Allocs) {
271 NextAddr = alignTo(NextAddr, Alloc.getAlign());
272 Dyld.mapSectionAddress(Alloc.getLocalAddress(), NextAddr);
273 DEBUG(dbgs() << " " << static_cast<void *>(Alloc.getLocalAddress())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " " << static_cast<void
*>(Alloc.getLocalAddress()) << " -> " << format
("0x%016x", NextAddr) << "\n"; } } while (false)
274 << " -> " << format("0x%016x", NextAddr) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " " << static_cast<void
*>(Alloc.getLocalAddress()) << " -> " << format
("0x%016x", NextAddr) << "\n"; } } while (false)
;
275 Alloc.setRemoteAddress(NextAddr);
276
277 // Only advance NextAddr if it was non-null to begin with,
278 // otherwise leave it as null.
279 if (NextAddr)
280 NextAddr += Alloc.getSize();
281 }
282 }
283
284 // Copies data for each alloc in the list, then set permissions on the
285 // segment.
286 bool copyAndProtect(const std::vector<Alloc> &Allocs,
287 JITTargetAddress RemoteSegmentAddr,
288 unsigned Permissions) {
289 if (RemoteSegmentAddr) {
290 assert(!Allocs.empty() && "No sections in allocated segment")(static_cast <bool> (!Allocs.empty() && "No sections in allocated segment"
) ? void (0) : __assert_fail ("!Allocs.empty() && \"No sections in allocated segment\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 290, __extension__ __PRETTY_FUNCTION__))
;
291
292 for (auto &Alloc : Allocs) {
293 DEBUG(dbgs() << " copying section: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " copying section: " << static_cast
<void *>(Alloc.getLocalAddress()) << " -> " <<
format("0x%016x", Alloc.getRemoteAddress()) << " (" <<
Alloc.getSize() << " bytes)\n";; } } while (false)
294 << static_cast<void *>(Alloc.getLocalAddress()) << " -> "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " copying section: " << static_cast
<void *>(Alloc.getLocalAddress()) << " -> " <<
format("0x%016x", Alloc.getRemoteAddress()) << " (" <<
Alloc.getSize() << " bytes)\n";; } } while (false)
295 << format("0x%016x", Alloc.getRemoteAddress()) << " ("do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " copying section: " << static_cast
<void *>(Alloc.getLocalAddress()) << " -> " <<
format("0x%016x", Alloc.getRemoteAddress()) << " (" <<
Alloc.getSize() << " bytes)\n";; } } while (false)
296 << Alloc.getSize() << " bytes)\n";)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " copying section: " << static_cast
<void *>(Alloc.getLocalAddress()) << " -> " <<
format("0x%016x", Alloc.getRemoteAddress()) << " (" <<
Alloc.getSize() << " bytes)\n";; } } while (false)
;
297
298 if (Client.writeMem(Alloc.getRemoteAddress(), Alloc.getLocalAddress(),
299 Alloc.getSize()))
300 return true;
301 }
302
303 DEBUG(dbgs() << " setting "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " setting " << (Permissions
& sys::Memory::MF_READ ? 'R' : '-') << (Permissions
& sys::Memory::MF_WRITE ? 'W' : '-') << (Permissions
& sys::Memory::MF_EXEC ? 'X' : '-') << " permissions on block: "
<< format("0x%016x", RemoteSegmentAddr) << "\n";
} } while (false)
304 << (Permissions & sys::Memory::MF_READ ? 'R' : '-')do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " setting " << (Permissions
& sys::Memory::MF_READ ? 'R' : '-') << (Permissions
& sys::Memory::MF_WRITE ? 'W' : '-') << (Permissions
& sys::Memory::MF_EXEC ? 'X' : '-') << " permissions on block: "
<< format("0x%016x", RemoteSegmentAddr) << "\n";
} } while (false)
305 << (Permissions & sys::Memory::MF_WRITE ? 'W' : '-')do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " setting " << (Permissions
& sys::Memory::MF_READ ? 'R' : '-') << (Permissions
& sys::Memory::MF_WRITE ? 'W' : '-') << (Permissions
& sys::Memory::MF_EXEC ? 'X' : '-') << " permissions on block: "
<< format("0x%016x", RemoteSegmentAddr) << "\n";
} } while (false)
306 << (Permissions & sys::Memory::MF_EXEC ? 'X' : '-')do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " setting " << (Permissions
& sys::Memory::MF_READ ? 'R' : '-') << (Permissions
& sys::Memory::MF_WRITE ? 'W' : '-') << (Permissions
& sys::Memory::MF_EXEC ? 'X' : '-') << " permissions on block: "
<< format("0x%016x", RemoteSegmentAddr) << "\n";
} } while (false)
307 << " permissions on block: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " setting " << (Permissions
& sys::Memory::MF_READ ? 'R' : '-') << (Permissions
& sys::Memory::MF_WRITE ? 'W' : '-') << (Permissions
& sys::Memory::MF_EXEC ? 'X' : '-') << " permissions on block: "
<< format("0x%016x", RemoteSegmentAddr) << "\n";
} } while (false)
308 << format("0x%016x", RemoteSegmentAddr) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << " setting " << (Permissions
& sys::Memory::MF_READ ? 'R' : '-') << (Permissions
& sys::Memory::MF_WRITE ? 'W' : '-') << (Permissions
& sys::Memory::MF_EXEC ? 'X' : '-') << " permissions on block: "
<< format("0x%016x", RemoteSegmentAddr) << "\n";
} } while (false)
;
309 if (Client.setProtections(Id, RemoteSegmentAddr, Permissions))
310 return true;
311 }
312 return false;
313 }
314
315 OrcRemoteTargetClient &Client;
316 ResourceIdMgr::ResourceId Id;
317 std::vector<ObjectAllocs> Unmapped;
318 std::vector<ObjectAllocs> Unfinalized;
319
320 struct EHFrame {
321 JITTargetAddress Addr;
322 uint64_t Size;
323 };
324 std::vector<EHFrame> UnfinalizedEHFrames;
325 std::vector<EHFrame> RegisteredEHFrames;
326 };
327
328 /// Remote indirect stubs manager.
329 class RemoteIndirectStubsManager : public IndirectStubsManager {
330 public:
331 RemoteIndirectStubsManager(OrcRemoteTargetClient &Client,
332 ResourceIdMgr::ResourceId Id)
333 : Client(Client), Id(Id) {}
334
335 ~RemoteIndirectStubsManager() override {
336 Client.destroyIndirectStubsManager(Id);
337 }
338
339 Error createStub(StringRef StubName, JITTargetAddress StubAddr,
340 JITSymbolFlags StubFlags) override {
341 if (auto Err = reserveStubs(1))
342 return Err;
343
344 return createStubInternal(StubName, StubAddr, StubFlags);
345 }
346
347 Error createStubs(const StubInitsMap &StubInits) override {
348 if (auto Err = reserveStubs(StubInits.size()))
349 return Err;
350
351 for (auto &Entry : StubInits)
352 if (auto Err = createStubInternal(Entry.first(), Entry.second.first,
353 Entry.second.second))
354 return Err;
355
356 return Error::success();
357 }
358
359 JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override {
360 auto I = StubIndexes.find(Name);
361 if (I == StubIndexes.end())
362 return nullptr;
363 auto Key = I->second.first;
364 auto Flags = I->second.second;
365 auto StubSymbol = JITSymbol(getStubAddr(Key), Flags);
366 if (ExportedStubsOnly && !StubSymbol.getFlags().isExported())
367 return nullptr;
368 return StubSymbol;
369 }
370
371 JITSymbol findPointer(StringRef Name) override {
372 auto I = StubIndexes.find(Name);
373 if (I == StubIndexes.end())
374 return nullptr;
375 auto Key = I->second.first;
376 auto Flags = I->second.second;
377 return JITSymbol(getPtrAddr(Key), Flags);
378 }
379
380 Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override {
381 auto I = StubIndexes.find(Name);
382 assert(I != StubIndexes.end() && "No stub pointer for symbol")(static_cast <bool> (I != StubIndexes.end() && "No stub pointer for symbol"
) ? void (0) : __assert_fail ("I != StubIndexes.end() && \"No stub pointer for symbol\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 382, __extension__ __PRETTY_FUNCTION__))
;
383 auto Key = I->second.first;
384 return Client.writePointer(getPtrAddr(Key), NewAddr);
385 }
386
387 private:
388 struct RemoteIndirectStubsInfo {
389 JITTargetAddress StubBase;
390 JITTargetAddress PtrBase;
391 unsigned NumStubs;
392 };
393
394 using StubKey = std::pair<uint16_t, uint16_t>;
395
396 Error reserveStubs(unsigned NumStubs) {
397 if (NumStubs <= FreeStubs.size())
398 return Error::success();
399
400 unsigned NewStubsRequired = NumStubs - FreeStubs.size();
401 JITTargetAddress StubBase;
402 JITTargetAddress PtrBase;
403 unsigned NumStubsEmitted;
404
405 if (auto StubInfoOrErr = Client.emitIndirectStubs(Id, NewStubsRequired))
406 std::tie(StubBase, PtrBase, NumStubsEmitted) = *StubInfoOrErr;
407 else
408 return StubInfoOrErr.takeError();
409
410 unsigned NewBlockId = RemoteIndirectStubsInfos.size();
411 RemoteIndirectStubsInfos.push_back({StubBase, PtrBase, NumStubsEmitted});
412
413 for (unsigned I = 0; I < NumStubsEmitted; ++I)
414 FreeStubs.push_back(std::make_pair(NewBlockId, I));
415
416 return Error::success();
417 }
418
419 Error createStubInternal(StringRef StubName, JITTargetAddress InitAddr,
420 JITSymbolFlags StubFlags) {
421 auto Key = FreeStubs.back();
422 FreeStubs.pop_back();
423 StubIndexes[StubName] = std::make_pair(Key, StubFlags);
424 return Client.writePointer(getPtrAddr(Key), InitAddr);
425 }
426
427 JITTargetAddress getStubAddr(StubKey K) {
428 assert(RemoteIndirectStubsInfos[K.first].StubBase != 0 &&(static_cast <bool> (RemoteIndirectStubsInfos[K.first].
StubBase != 0 && "Missing stub address") ? void (0) :
__assert_fail ("RemoteIndirectStubsInfos[K.first].StubBase != 0 && \"Missing stub address\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 429, __extension__ __PRETTY_FUNCTION__))
429 "Missing stub address")(static_cast <bool> (RemoteIndirectStubsInfos[K.first].
StubBase != 0 && "Missing stub address") ? void (0) :
__assert_fail ("RemoteIndirectStubsInfos[K.first].StubBase != 0 && \"Missing stub address\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 429, __extension__ __PRETTY_FUNCTION__))
;
430 return RemoteIndirectStubsInfos[K.first].StubBase +
431 K.second * Client.getIndirectStubSize();
432 }
433
434 JITTargetAddress getPtrAddr(StubKey K) {
435 assert(RemoteIndirectStubsInfos[K.first].PtrBase != 0 &&(static_cast <bool> (RemoteIndirectStubsInfos[K.first].
PtrBase != 0 && "Missing pointer address") ? void (0)
: __assert_fail ("RemoteIndirectStubsInfos[K.first].PtrBase != 0 && \"Missing pointer address\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 436, __extension__ __PRETTY_FUNCTION__))
436 "Missing pointer address")(static_cast <bool> (RemoteIndirectStubsInfos[K.first].
PtrBase != 0 && "Missing pointer address") ? void (0)
: __assert_fail ("RemoteIndirectStubsInfos[K.first].PtrBase != 0 && \"Missing pointer address\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 436, __extension__ __PRETTY_FUNCTION__))
;
437 return RemoteIndirectStubsInfos[K.first].PtrBase +
438 K.second * Client.getPointerSize();
439 }
440
441 OrcRemoteTargetClient &Client;
442 ResourceIdMgr::ResourceId Id;
443 std::vector<RemoteIndirectStubsInfo> RemoteIndirectStubsInfos;
444 std::vector<StubKey> FreeStubs;
445 StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
446 };
447
448 /// Remote compile callback manager.
449 class RemoteCompileCallbackManager : public JITCompileCallbackManager {
450 public:
451 RemoteCompileCallbackManager(OrcRemoteTargetClient &Client,
452 JITTargetAddress ErrorHandlerAddress)
453 : JITCompileCallbackManager(ErrorHandlerAddress), Client(Client) {}
454
455 private:
456 Error grow() override {
457 JITTargetAddress BlockAddr = 0;
458 uint32_t NumTrampolines = 0;
459 if (auto TrampolineInfoOrErr = Client.emitTrampolineBlock())
460 std::tie(BlockAddr, NumTrampolines) = *TrampolineInfoOrErr;
461 else
462 return TrampolineInfoOrErr.takeError();
463
464 uint32_t TrampolineSize = Client.getTrampolineSize();
465 for (unsigned I = 0; I < NumTrampolines; ++I)
466 this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
467
468 return Error::success();
469 }
470
471 OrcRemoteTargetClient &Client;
472 };
473
474 /// Create an OrcRemoteTargetClient.
475 /// Channel is the ChannelT instance to communicate on. It is assumed that
476 /// the channel is ready to be read from and written to.
477 static Expected<std::unique_ptr<OrcRemoteTargetClient>>
478 Create(rpc::RawByteChannel &Channel, std::function<void(Error)> ReportError) {
479 Error Err = Error::success();
480 auto Client = std::unique_ptr<OrcRemoteTargetClient>(
481 new OrcRemoteTargetClient(Channel, std::move(ReportError), Err));
482 if (Err)
483 return std::move(Err);
484 return std::move(Client);
485 }
486
487 /// Call the int(void) function at the given address in the target and return
488 /// its result.
489 Expected<int> callIntVoid(JITTargetAddress Addr) {
490 DEBUG(dbgs() << "Calling int(*)(void) " << format("0x%016x", Addr) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Calling int(*)(void) " << format
("0x%016x", Addr) << "\n"; } } while (false)
;
491 return callB<exec::CallIntVoid>(Addr);
492 }
493
494 /// Call the int(int, char*[]) function at the given address in the target and
495 /// return its result.
496 Expected<int> callMain(JITTargetAddress Addr,
497 const std::vector<std::string> &Args) {
498 DEBUG(dbgs() << "Calling int(*)(int, char*[]) " << format("0x%016x", Addr)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Calling int(*)(int, char*[]) " <<
format("0x%016x", Addr) << "\n"; } } while (false)
499 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Calling int(*)(int, char*[]) " <<
format("0x%016x", Addr) << "\n"; } } while (false)
;
500 return callB<exec::CallMain>(Addr, Args);
501 }
502
503 /// Call the void() function at the given address in the target and wait for
504 /// it to finish.
505 Error callVoidVoid(JITTargetAddress Addr) {
506 DEBUG(dbgs() << "Calling void(*)(void) " << format("0x%016x", Addr)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Calling void(*)(void) " << format
("0x%016x", Addr) << "\n"; } } while (false)
507 << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("lli")) { dbgs() << "Calling void(*)(void) " << format
("0x%016x", Addr) << "\n"; } } while (false)
;
508 return callB<exec::CallVoidVoid>(Addr);
509 }
510
511 /// Create an RCMemoryManager which will allocate its memory on the remote
512 /// target.
513 Expected<std::unique_ptr<RemoteRTDyldMemoryManager>>
514 createRemoteMemoryManager() {
515 auto Id = AllocatorIds.getNext();
516 if (auto Err = callB<mem::CreateRemoteAllocator>(Id))
517 return std::move(Err);
518 return std::unique_ptr<RemoteRTDyldMemoryManager>(
519 new RemoteRTDyldMemoryManager(*this, Id));
520 }
521
522 /// Create an RCIndirectStubsManager that will allocate stubs on the remote
523 /// target.
524 Expected<std::unique_ptr<RemoteIndirectStubsManager>>
525 createIndirectStubsManager() {
526 auto Id = IndirectStubOwnerIds.getNext();
527 if (auto Err = callB<stubs::CreateIndirectStubsOwner>(Id))
528 return std::move(Err);
529 return llvm::make_unique<RemoteIndirectStubsManager>(*this, Id);
530 }
531
532 Expected<RemoteCompileCallbackManager &>
533 enableCompileCallbacks(JITTargetAddress ErrorHandlerAddress) {
534 // Emit the resolver block on the JIT server.
535 if (auto Err = callB<stubs::EmitResolverBlock>())
536 return std::move(Err);
537
538 // Create the callback manager.
539 CallbackManager.emplace(*this, ErrorHandlerAddress);
540 RemoteCompileCallbackManager &Mgr = *CallbackManager;
541 return Mgr;
542 }
543
544 /// Search for symbols in the remote process. Note: This should be used by
545 /// symbol resolvers *after* they've searched the local symbol table in the
546 /// JIT stack.
547 Expected<JITTargetAddress> getSymbolAddress(StringRef Name) {
548 return callB<utils::GetSymbolAddress>(Name);
549 }
550
551 /// Get the triple for the remote target.
552 const std::string &getTargetTriple() const { return RemoteTargetTriple; }
553
554 Error terminateSession() { return callB<utils::TerminateSession>(); }
55
Calling 'SingleThreadedRPCEndpoint::callB'
555
556private:
557 OrcRemoteTargetClient(rpc::RawByteChannel &Channel,
558 std::function<void(Error)> ReportError, Error &Err)
559 : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(Channel, true),
560 ReportError(std::move(ReportError)) {
561 ErrorAsOutParameter EAO(&Err);
562
563 addHandler<utils::RequestCompile>(
564 [this](JITTargetAddress Addr) -> JITTargetAddress {
565 if (CallbackManager)
566 return CallbackManager->executeCompileCallback(Addr);
567 return 0;
568 });
569
570 if (auto RIOrErr = callB<utils::GetRemoteInfo>()) {
571 std::tie(RemoteTargetTriple, RemotePointerSize, RemotePageSize,
572 RemoteTrampolineSize, RemoteIndirectStubSize) = *RIOrErr;
573 Err = Error::success();
574 } else
575 Err = RIOrErr.takeError();
576 }
577
578 void deregisterEHFrames(JITTargetAddress Addr, uint32_t Size) {
579 if (auto Err = callB<eh::RegisterEHFrames>(Addr, Size))
580 ReportError(std::move(Err));
581 }
582
583 void destroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {
584 if (auto Err = callB<mem::DestroyRemoteAllocator>(Id)) {
585 // FIXME: This will be triggered by a removeModuleSet call: Propagate
586 // error return up through that.
587 llvm_unreachable("Failed to destroy remote allocator.")::llvm::llvm_unreachable_internal("Failed to destroy remote allocator."
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
, 587)
;
588 AllocatorIds.release(Id);
589 }
590 }
591
592 void destroyIndirectStubsManager(ResourceIdMgr::ResourceId Id) {
593 IndirectStubOwnerIds.release(Id);
594 if (auto Err = callB<stubs::DestroyIndirectStubsOwner>(Id))
595 ReportError(std::move(Err));
596 }
597
598 Expected<std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>>
599 emitIndirectStubs(ResourceIdMgr::ResourceId Id, uint32_t NumStubsRequired) {
600 return callB<stubs::EmitIndirectStubs>(Id, NumStubsRequired);
601 }
602
603 Expected<std::tuple<JITTargetAddress, uint32_t>> emitTrampolineBlock() {
604 return callB<stubs::EmitTrampolineBlock>();
605 }
606
607 uint32_t getIndirectStubSize() const { return RemoteIndirectStubSize; }
608 uint32_t getPageSize() const { return RemotePageSize; }
609 uint32_t getPointerSize() const { return RemotePointerSize; }
610
611 uint32_t getTrampolineSize() const { return RemoteTrampolineSize; }
612
613 Expected<std::vector<uint8_t>> readMem(char *Dst, JITTargetAddress Src,
614 uint64_t Size) {
615 return callB<mem::ReadMem>(Src, Size);
616 }
617
618 Error registerEHFrames(JITTargetAddress &RAddr, uint32_t Size) {
619 // FIXME: Duplicate error and report it via ReportError too?
620 return callB<eh::RegisterEHFrames>(RAddr, Size);
621 }
622
623 JITTargetAddress reserveMem(ResourceIdMgr::ResourceId Id, uint64_t Size,
624 uint32_t Align) {
625 if (auto AddrOrErr = callB<mem::ReserveMem>(Id, Size, Align))
626 return *AddrOrErr;
627 else {
628 ReportError(AddrOrErr.takeError());
629 return 0;
630 }
631 }
632
633 bool setProtections(ResourceIdMgr::ResourceId Id,
634 JITTargetAddress RemoteSegAddr, unsigned ProtFlags) {
635 if (auto Err = callB<mem::SetProtections>(Id, RemoteSegAddr, ProtFlags)) {
636 ReportError(std::move(Err));
637 return true;
638 } else
639 return false;
640 }
641
642 bool writeMem(JITTargetAddress Addr, const char *Src, uint64_t Size) {
643 if (auto Err = callB<mem::WriteMem>(DirectBufferWriter(Src, Addr, Size))) {
644 ReportError(std::move(Err));
645 return true;
646 } else
647 return false;
648 }
649
650 Error writePointer(JITTargetAddress Addr, JITTargetAddress PtrVal) {
651 return callB<mem::WritePtr>(Addr, PtrVal);
652 }
653
654 static Error doNothing() { return Error::success(); }
655
656 std::function<void(Error)> ReportError;
657 std::string RemoteTargetTriple;
658 uint32_t RemotePointerSize = 0;
659 uint32_t RemotePageSize = 0;
660 uint32_t RemoteTrampolineSize = 0;
661 uint32_t RemoteIndirectStubSize = 0;
662 ResourceIdMgr AllocatorIds, IndirectStubOwnerIds;
663 Optional<RemoteCompileCallbackManager> CallbackManager;
664};
665
666} // end namespace remote
667} // end namespace orc
668} // end namespace llvm
669
670#undef DEBUG_TYPE"lli"
671
672#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H

/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h

1//===------- RPCUTils.h - Utilities for building RPC APIs -------*- 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// Utilities to support construction of simple RPC APIs.
11//
12// The RPC utilities aim for ease of use (minimal conceptual overhead) for C++
13// programmers, high performance, low memory overhead, and efficient use of the
14// communications channel.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
19#define LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
20
21#include <map>
22#include <thread>
23#include <vector>
24
25#include "llvm/ADT/STLExtras.h"
26#include "llvm/ExecutionEngine/Orc/OrcError.h"
27#include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
28
29#include <future>
30
31namespace llvm {
32namespace orc {
33namespace rpc {
34
35/// Base class of all fatal RPC errors (those that necessarily result in the
36/// termination of the RPC session).
37class RPCFatalError : public ErrorInfo<RPCFatalError> {
38public:
39 static char ID;
40};
41
42/// RPCConnectionClosed is returned from RPC operations if the RPC connection
43/// has already been closed due to either an error or graceful disconnection.
44class ConnectionClosed : public ErrorInfo<ConnectionClosed> {
45public:
46 static char ID;
47 std::error_code convertToErrorCode() const override;
48 void log(raw_ostream &OS) const override;
49};
50
51/// BadFunctionCall is returned from handleOne when the remote makes a call with
52/// an unrecognized function id.
53///
54/// This error is fatal because Orc RPC needs to know how to parse a function
55/// call to know where the next call starts, and if it doesn't recognize the
56/// function id it cannot parse the call.
57template <typename FnIdT, typename SeqNoT>
58class BadFunctionCall
59 : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
60public:
61 static char ID;
62
63 BadFunctionCall(FnIdT FnId, SeqNoT SeqNo)
64 : FnId(std::move(FnId)), SeqNo(std::move(SeqNo)) {}
65
66 std::error_code convertToErrorCode() const override {
67 return orcError(OrcErrorCode::UnexpectedRPCCall);
68 }
69
70 void log(raw_ostream &OS) const override {
71 OS << "Call to invalid RPC function id '" << FnId << "' with "
72 "sequence number " << SeqNo;
73 }
74
75private:
76 FnIdT FnId;
77 SeqNoT SeqNo;
78};
79
80template <typename FnIdT, typename SeqNoT>
81char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
82
83/// InvalidSequenceNumberForResponse is returned from handleOne when a response
84/// call arrives with a sequence number that doesn't correspond to any in-flight
85/// function call.
86///
87/// This error is fatal because Orc RPC needs to know how to parse the rest of
88/// the response call to know where the next call starts, and if it doesn't have
89/// a result parser for this sequence number it can't do that.
90template <typename SeqNoT>
91class InvalidSequenceNumberForResponse
92 : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>, RPCFatalError> {
93public:
94 static char ID;
95
96 InvalidSequenceNumberForResponse(SeqNoT SeqNo)
97 : SeqNo(std::move(SeqNo)) {}
98
99 std::error_code convertToErrorCode() const override {
100 return orcError(OrcErrorCode::UnexpectedRPCCall);
101 };
102
103 void log(raw_ostream &OS) const override {
104 OS << "Response has unknown sequence number " << SeqNo;
105 }
106private:
107 SeqNoT SeqNo;
108};
109
110template <typename SeqNoT>
111char InvalidSequenceNumberForResponse<SeqNoT>::ID = 0;
112
113/// This non-fatal error will be passed to asynchronous result handlers in place
114/// of a result if the connection goes down before a result returns, or if the
115/// function to be called cannot be negotiated with the remote.
116class ResponseAbandoned : public ErrorInfo<ResponseAbandoned> {
117public:
118 static char ID;
119
120 std::error_code convertToErrorCode() const override;
121 void log(raw_ostream &OS) const override;
122};
123
124/// This error is returned if the remote does not have a handler installed for
125/// the given RPC function.
126class CouldNotNegotiate : public ErrorInfo<CouldNotNegotiate> {
127public:
128 static char ID;
129
130 CouldNotNegotiate(std::string Signature);
131 std::error_code convertToErrorCode() const override;
132 void log(raw_ostream &OS) const override;
133 const std::string &getSignature() const { return Signature; }
134private:
135 std::string Signature;
136};
137
138template <typename DerivedFunc, typename FnT> class Function;
139
140// RPC Function class.
141// DerivedFunc should be a user defined class with a static 'getName()' method
142// returning a const char* representing the function's name.
143template <typename DerivedFunc, typename RetT, typename... ArgTs>
144class Function<DerivedFunc, RetT(ArgTs...)> {
145public:
146 /// User defined function type.
147 using Type = RetT(ArgTs...);
148
149 /// Return type.
150 using ReturnType = RetT;
151
152 /// Returns the full function prototype as a string.
153 static const char *getPrototype() {
154 std::lock_guard<std::mutex> Lock(NameMutex);
155 if (Name.empty())
156 raw_string_ostream(Name)
157 << RPCTypeName<RetT>::getName() << " " << DerivedFunc::getName()
158 << "(" << llvm::orc::rpc::RPCTypeNameSequence<ArgTs...>() << ")";
159 return Name.data();
160 }
161
162private:
163 static std::mutex NameMutex;
164 static std::string Name;
165};
166
167template <typename DerivedFunc, typename RetT, typename... ArgTs>
168std::mutex Function<DerivedFunc, RetT(ArgTs...)>::NameMutex;
169
170template <typename DerivedFunc, typename RetT, typename... ArgTs>
171std::string Function<DerivedFunc, RetT(ArgTs...)>::Name;
172
173/// Allocates RPC function ids during autonegotiation.
174/// Specializations of this class must provide four members:
175///
176/// static T getInvalidId():
177/// Should return a reserved id that will be used to represent missing
178/// functions during autonegotiation.
179///
180/// static T getResponseId():
181/// Should return a reserved id that will be used to send function responses
182/// (return values).
183///
184/// static T getNegotiateId():
185/// Should return a reserved id for the negotiate function, which will be used
186/// to negotiate ids for user defined functions.
187///
188/// template <typename Func> T allocate():
189/// Allocate a unique id for function Func.
190template <typename T, typename = void> class RPCFunctionIdAllocator;
191
192/// This specialization of RPCFunctionIdAllocator provides a default
193/// implementation for integral types.
194template <typename T>
195class RPCFunctionIdAllocator<
196 T, typename std::enable_if<std::is_integral<T>::value>::type> {
197public:
198 static T getInvalidId() { return T(0); }
199 static T getResponseId() { return T(1); }
200 static T getNegotiateId() { return T(2); }
201
202 template <typename Func> T allocate() { return NextId++; }
203
204private:
205 T NextId = 3;
206};
207
208namespace detail {
209
210// FIXME: Remove MSVCPError/MSVCPExpected once MSVC's future implementation
211// supports classes without default constructors.
212#ifdef _MSC_VER
213
214namespace msvc_hacks {
215
216// Work around MSVC's future implementation's use of default constructors:
217// A default constructed value in the promise will be overwritten when the
218// real error is set - so the default constructed Error has to be checked
219// already.
220class MSVCPError : public Error {
221public:
222 MSVCPError() { (void)!!*this; }
223
224 MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {}
225
226 MSVCPError &operator=(MSVCPError Other) {
227 Error::operator=(std::move(Other));
228 return *this;
229 }
230
231 MSVCPError(Error Err) : Error(std::move(Err)) {}
232};
233
234// Work around MSVC's future implementation, similar to MSVCPError.
235template <typename T> class MSVCPExpected : public Expected<T> {
236public:
237 MSVCPExpected()
238 : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) {
239 consumeError(this->takeError());
240 }
241
242 MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {}
243
244 MSVCPExpected &operator=(MSVCPExpected &&Other) {
245 Expected<T>::operator=(std::move(Other));
246 return *this;
247 }
248
249 MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {}
250
251 template <typename OtherT>
252 MSVCPExpected(
253 OtherT &&Val,
254 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
255 nullptr)
256 : Expected<T>(std::move(Val)) {}
257
258 template <class OtherT>
259 MSVCPExpected(
260 Expected<OtherT> &&Other,
261 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
262 nullptr)
263 : Expected<T>(std::move(Other)) {}
264
265 template <class OtherT>
266 explicit MSVCPExpected(
267 Expected<OtherT> &&Other,
268 typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
269 nullptr)
270 : Expected<T>(std::move(Other)) {}
271};
272
273} // end namespace msvc_hacks
274
275#endif // _MSC_VER
276
277/// Provides a typedef for a tuple containing the decayed argument types.
278template <typename T> class FunctionArgsTuple;
279
280template <typename RetT, typename... ArgTs>
281class FunctionArgsTuple<RetT(ArgTs...)> {
282public:
283 using Type = std::tuple<typename std::decay<
284 typename std::remove_reference<ArgTs>::type>::type...>;
285};
286
287// ResultTraits provides typedefs and utilities specific to the return type
288// of functions.
289template <typename RetT> class ResultTraits {
290public:
291 // The return type wrapped in llvm::Expected.
292 using ErrorReturnType = Expected<RetT>;
293
294#ifdef _MSC_VER
295 // The ErrorReturnType wrapped in a std::promise.
296 using ReturnPromiseType = std::promise<msvc_hacks::MSVCPExpected<RetT>>;
297
298 // The ErrorReturnType wrapped in a std::future.
299 using ReturnFutureType = std::future<msvc_hacks::MSVCPExpected<RetT>>;
300#else
301 // The ErrorReturnType wrapped in a std::promise.
302 using ReturnPromiseType = std::promise<ErrorReturnType>;
303
304 // The ErrorReturnType wrapped in a std::future.
305 using ReturnFutureType = std::future<ErrorReturnType>;
306#endif
307
308 // Create a 'blank' value of the ErrorReturnType, ready and safe to
309 // overwrite.
310 static ErrorReturnType createBlankErrorReturnValue() {
311 return ErrorReturnType(RetT());
312 }
313
314 // Consume an abandoned ErrorReturnType.
315 static void consumeAbandoned(ErrorReturnType RetOrErr) {
316 consumeError(RetOrErr.takeError());
317 }
318};
319
320// ResultTraits specialization for void functions.
321template <> class ResultTraits<void> {
322public:
323 // For void functions, ErrorReturnType is llvm::Error.
324 using ErrorReturnType = Error;
325
326#ifdef _MSC_VER
327 // The ErrorReturnType wrapped in a std::promise.
328 using ReturnPromiseType = std::promise<msvc_hacks::MSVCPError>;
329
330 // The ErrorReturnType wrapped in a std::future.
331 using ReturnFutureType = std::future<msvc_hacks::MSVCPError>;
332#else
333 // The ErrorReturnType wrapped in a std::promise.
334 using ReturnPromiseType = std::promise<ErrorReturnType>;
335
336 // The ErrorReturnType wrapped in a std::future.
337 using ReturnFutureType = std::future<ErrorReturnType>;
338#endif
339
340 // Create a 'blank' value of the ErrorReturnType, ready and safe to
341 // overwrite.
342 static ErrorReturnType createBlankErrorReturnValue() {
343 return ErrorReturnType::success();
344 }
345
346 // Consume an abandoned ErrorReturnType.
347 static void consumeAbandoned(ErrorReturnType Err) {
348 consumeError(std::move(Err));
349 }
350};
351
352// ResultTraits<Error> is equivalent to ResultTraits<void>. This allows
353// handlers for void RPC functions to return either void (in which case they
354// implicitly succeed) or Error (in which case their error return is
355// propagated). See usage in HandlerTraits::runHandlerHelper.
356template <> class ResultTraits<Error> : public ResultTraits<void> {};
357
358// ResultTraits<Expected<T>> is equivalent to ResultTraits<T>. This allows
359// handlers for RPC functions returning a T to return either a T (in which
360// case they implicitly succeed) or Expected<T> (in which case their error
361// return is propagated). See usage in HandlerTraits::runHandlerHelper.
362template <typename RetT>
363class ResultTraits<Expected<RetT>> : public ResultTraits<RetT> {};
364
365// Determines whether an RPC function's defined error return type supports
366// error return value.
367template <typename T>
368class SupportsErrorReturn {
369public:
370 static const bool value = false;
371};
372
373template <>
374class SupportsErrorReturn<Error> {
375public:
376 static const bool value = true;
377};
378
379template <typename T>
380class SupportsErrorReturn<Expected<T>> {
381public:
382 static const bool value = true;
383};
384
385// RespondHelper packages return values based on whether or not the declared
386// RPC function return type supports error returns.
387template <bool FuncSupportsErrorReturn>
388class RespondHelper;
389
390// RespondHelper specialization for functions that support error returns.
391template <>
392class RespondHelper<true> {
393public:
394
395 // Send Expected<T>.
396 template <typename WireRetT, typename HandlerRetT, typename ChannelT,
397 typename FunctionIdT, typename SequenceNumberT>
398 static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
399 SequenceNumberT SeqNo,
400 Expected<HandlerRetT> ResultOrErr) {
401 if (!ResultOrErr && ResultOrErr.template errorIsA<RPCFatalError>())
402 return ResultOrErr.takeError();
403
404 // Open the response message.
405 if (auto Err = C.startSendMessage(ResponseId, SeqNo))
406 return Err;
407
408 // Serialize the result.
409 if (auto Err =
410 SerializationTraits<ChannelT, WireRetT,
411 Expected<HandlerRetT>>::serialize(
412 C, std::move(ResultOrErr)))
413 return Err;
414
415 // Close the response message.
416 return C.endSendMessage();
417 }
418
419 template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
420 static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
421 SequenceNumberT SeqNo, Error Err) {
422 if (Err && Err.isA<RPCFatalError>())
423 return Err;
424 if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
425 return Err2;
426 if (auto Err2 = serializeSeq(C, std::move(Err)))
427 return Err2;
428 return C.endSendMessage();
429 }
430
431};
432
433// RespondHelper specialization for functions that do not support error returns.
434template <>
435class RespondHelper<false> {
436public:
437
438 template <typename WireRetT, typename HandlerRetT, typename ChannelT,
439 typename FunctionIdT, typename SequenceNumberT>
440 static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
441 SequenceNumberT SeqNo,
442 Expected<HandlerRetT> ResultOrErr) {
443 if (auto Err = ResultOrErr.takeError())
444 return Err;
445
446 // Open the response message.
447 if (auto Err = C.startSendMessage(ResponseId, SeqNo))
448 return Err;
449
450 // Serialize the result.
451 if (auto Err =
452 SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
453 C, *ResultOrErr))
454 return Err;
455
456 // Close the response message.
457 return C.endSendMessage();
458 }
459
460 template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
461 static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
462 SequenceNumberT SeqNo, Error Err) {
463 if (Err)
464 return Err;
465 if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
466 return Err2;
467 return C.endSendMessage();
468 }
469
470};
471
472
473// Send a response of the given wire return type (WireRetT) over the
474// channel, with the given sequence number.
475template <typename WireRetT, typename HandlerRetT, typename ChannelT,
476 typename FunctionIdT, typename SequenceNumberT>
477Error respond(ChannelT &C, const FunctionIdT &ResponseId,
478 SequenceNumberT SeqNo, Expected<HandlerRetT> ResultOrErr) {
479 return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
480 template sendResult<WireRetT>(C, ResponseId, SeqNo, std::move(ResultOrErr));
481}
482
483// Send an empty response message on the given channel to indicate that
484// the handler ran.
485template <typename WireRetT, typename ChannelT, typename FunctionIdT,
486 typename SequenceNumberT>
487Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
488 Error Err) {
489 return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
490 sendResult(C, ResponseId, SeqNo, std::move(Err));
491}
492
493// Converts a given type to the equivalent error return type.
494template <typename T> class WrappedHandlerReturn {
495public:
496 using Type = Expected<T>;
497};
498
499template <typename T> class WrappedHandlerReturn<Expected<T>> {
500public:
501 using Type = Expected<T>;
502};
503
504template <> class WrappedHandlerReturn<void> {
505public:
506 using Type = Error;
507};
508
509template <> class WrappedHandlerReturn<Error> {
510public:
511 using Type = Error;
512};
513
514template <> class WrappedHandlerReturn<ErrorSuccess> {
515public:
516 using Type = Error;
517};
518
519// Traits class that strips the response function from the list of handler
520// arguments.
521template <typename FnT> class AsyncHandlerTraits;
522
523template <typename ResultT, typename... ArgTs>
524class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>, ArgTs...)> {
525public:
526 using Type = Error(ArgTs...);
527 using ResultType = Expected<ResultT>;
528};
529
530template <typename... ArgTs>
531class AsyncHandlerTraits<Error(std::function<Error(Error)>, ArgTs...)> {
532public:
533 using Type = Error(ArgTs...);
534 using ResultType = Error;
535};
536
537template <typename... ArgTs>
538class AsyncHandlerTraits<ErrorSuccess(std::function<Error(Error)>, ArgTs...)> {
539public:
540 using Type = Error(ArgTs...);
541 using ResultType = Error;
542};
543
544template <typename... ArgTs>
545class AsyncHandlerTraits<void(std::function<Error(Error)>, ArgTs...)> {
546public:
547 using Type = Error(ArgTs...);
548 using ResultType = Error;
549};
550
551template <typename ResponseHandlerT, typename... ArgTs>
552class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)> :
553 public AsyncHandlerTraits<Error(typename std::decay<ResponseHandlerT>::type,
554 ArgTs...)> {};
555
556// This template class provides utilities related to RPC function handlers.
557// The base case applies to non-function types (the template class is
558// specialized for function types) and inherits from the appropriate
559// speciilization for the given non-function type's call operator.
560template <typename HandlerT>
561class HandlerTraits : public HandlerTraits<decltype(
562 &std::remove_reference<HandlerT>::type::operator())> {
563};
564
565// Traits for handlers with a given function type.
566template <typename RetT, typename... ArgTs>
567class HandlerTraits<RetT(ArgTs...)> {
568public:
569 // Function type of the handler.
570 using Type = RetT(ArgTs...);
571
572 // Return type of the handler.
573 using ReturnType = RetT;
574
575 // Call the given handler with the given arguments.
576 template <typename HandlerT, typename... TArgTs>
577 static typename WrappedHandlerReturn<RetT>::Type
578 unpackAndRun(HandlerT &Handler, std::tuple<TArgTs...> &Args) {
579 return unpackAndRunHelper(Handler, Args,
580 llvm::index_sequence_for<TArgTs...>());
581 }
582
583 // Call the given handler with the given arguments.
584 template <typename HandlerT, typename ResponderT, typename... TArgTs>
585 static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
586 std::tuple<TArgTs...> &Args) {
587 return unpackAndRunAsyncHelper(Handler, Responder, Args,
588 llvm::index_sequence_for<TArgTs...>());
589 }
590
591 // Call the given handler with the given arguments.
592 template <typename HandlerT>
593 static typename std::enable_if<
594 std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
595 Error>::type
596 run(HandlerT &Handler, ArgTs &&... Args) {
597 Handler(std::move(Args)...);
598 return Error::success();
599 }
600
601 template <typename HandlerT, typename... TArgTs>
602 static typename std::enable_if<
603 !std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
604 typename HandlerTraits<HandlerT>::ReturnType>::type
605 run(HandlerT &Handler, TArgTs... Args) {
606 return Handler(std::move(Args)...);
607 }
608
609 // Serialize arguments to the channel.
610 template <typename ChannelT, typename... CArgTs>
611 static Error serializeArgs(ChannelT &C, const CArgTs... CArgs) {
612 return SequenceSerialization<ChannelT, ArgTs...>::serialize(C, CArgs...);
613 }
614
615 // Deserialize arguments from the channel.
616 template <typename ChannelT, typename... CArgTs>
617 static Error deserializeArgs(ChannelT &C, std::tuple<CArgTs...> &Args) {
618 return deserializeArgsHelper(C, Args,
619 llvm::index_sequence_for<CArgTs...>());
620 }
621
622private:
623 template <typename ChannelT, typename... CArgTs, size_t... Indexes>
624 static Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
625 llvm::index_sequence<Indexes...> _) {
626 return SequenceSerialization<ChannelT, ArgTs...>::deserialize(
627 C, std::get<Indexes>(Args)...);
628 }
629
630 template <typename HandlerT, typename ArgTuple, size_t... Indexes>
631 static typename WrappedHandlerReturn<
632 typename HandlerTraits<HandlerT>::ReturnType>::Type
633 unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
634 llvm::index_sequence<Indexes...>) {
635 return run(Handler, std::move(std::get<Indexes>(Args))...);
636 }
637
638
639 template <typename HandlerT, typename ResponderT, typename ArgTuple,
640 size_t... Indexes>
641 static typename WrappedHandlerReturn<
642 typename HandlerTraits<HandlerT>::ReturnType>::Type
643 unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
644 ArgTuple &Args,
645 llvm::index_sequence<Indexes...>) {
646 return run(Handler, Responder, std::move(std::get<Indexes>(Args))...);
647 }
648};
649
650// Handler traits for free functions.
651template <typename RetT, typename... ArgTs>
652class HandlerTraits<RetT(*)(ArgTs...)>
653 : public HandlerTraits<RetT(ArgTs...)> {};
654
655// Handler traits for class methods (especially call operators for lambdas).
656template <typename Class, typename RetT, typename... ArgTs>
657class HandlerTraits<RetT (Class::*)(ArgTs...)>
658 : public HandlerTraits<RetT(ArgTs...)> {};
659
660// Handler traits for const class methods (especially call operators for
661// lambdas).
662template <typename Class, typename RetT, typename... ArgTs>
663class HandlerTraits<RetT (Class::*)(ArgTs...) const>
664 : public HandlerTraits<RetT(ArgTs...)> {};
665
666// Utility to peel the Expected wrapper off a response handler error type.
667template <typename HandlerT> class ResponseHandlerArg;
668
669template <typename ArgT> class ResponseHandlerArg<Error(Expected<ArgT>)> {
670public:
671 using ArgType = Expected<ArgT>;
672 using UnwrappedArgType = ArgT;
673};
674
675template <typename ArgT>
676class ResponseHandlerArg<ErrorSuccess(Expected<ArgT>)> {
677public:
678 using ArgType = Expected<ArgT>;
679 using UnwrappedArgType = ArgT;
680};
681
682template <> class ResponseHandlerArg<Error(Error)> {
683public:
684 using ArgType = Error;
685};
686
687template <> class ResponseHandlerArg<ErrorSuccess(Error)> {
688public:
689 using ArgType = Error;
690};
691
692// ResponseHandler represents a handler for a not-yet-received function call
693// result.
694template <typename ChannelT> class ResponseHandler {
695public:
696 virtual ~ResponseHandler() {}
697
698 // Reads the function result off the wire and acts on it. The meaning of
699 // "act" will depend on how this method is implemented in any given
700 // ResponseHandler subclass but could, for example, mean running a
701 // user-specified handler or setting a promise value.
702 virtual Error handleResponse(ChannelT &C) = 0;
703
704 // Abandons this outstanding result.
705 virtual void abandon() = 0;
706
707 // Create an error instance representing an abandoned response.
708 static Error createAbandonedResponseError() {
709 return make_error<ResponseAbandoned>();
710 }
711};
712
713// ResponseHandler subclass for RPC functions with non-void returns.
714template <typename ChannelT, typename FuncRetT, typename HandlerT>
715class ResponseHandlerImpl : public ResponseHandler<ChannelT> {
716public:
717 ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
718
719 // Handle the result by deserializing it from the channel then passing it
720 // to the user defined handler.
721 Error handleResponse(ChannelT &C) override {
722 using UnwrappedArgType = typename ResponseHandlerArg<
723 typename HandlerTraits<HandlerT>::Type>::UnwrappedArgType;
724 UnwrappedArgType Result;
725 if (auto Err =
726 SerializationTraits<ChannelT, FuncRetT,
727 UnwrappedArgType>::deserialize(C, Result))
728 return Err;
729 if (auto Err = C.endReceiveMessage())
730 return Err;
731 return Handler(std::move(Result));
732 }
733
734 // Abandon this response by calling the handler with an 'abandoned response'
735 // error.
736 void abandon() override {
737 if (auto Err = Handler(this->createAbandonedResponseError())) {
738 // Handlers should not fail when passed an abandoned response error.
739 report_fatal_error(std::move(Err));
740 }
741 }
742
743private:
744 HandlerT Handler;
745};
746
747// ResponseHandler subclass for RPC functions with void returns.
748template <typename ChannelT, typename HandlerT>
749class ResponseHandlerImpl<ChannelT, void, HandlerT>
750 : public ResponseHandler<ChannelT> {
751public:
752 ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
753
754 // Handle the result (no actual value, just a notification that the function
755 // has completed on the remote end) by calling the user-defined handler with
756 // Error::success().
757 Error handleResponse(ChannelT &C) override {
758 if (auto Err = C.endReceiveMessage())
759 return Err;
760 return Handler(Error::success());
761 }
762
763 // Abandon this response by calling the handler with an 'abandoned response'
764 // error.
765 void abandon() override {
766 if (auto Err = Handler(this->createAbandonedResponseError())) {
767 // Handlers should not fail when passed an abandoned response error.
768 report_fatal_error(std::move(Err));
769 }
770 }
771
772private:
773 HandlerT Handler;
774};
775
776template <typename ChannelT, typename FuncRetT, typename HandlerT>
777class ResponseHandlerImpl<ChannelT, Expected<FuncRetT>, HandlerT>
778 : public ResponseHandler<ChannelT> {
779public:
780 ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
781
782 // Handle the result by deserializing it from the channel then passing it
783 // to the user defined handler.
784 Error handleResponse(ChannelT &C) override {
785 using HandlerArgType = typename ResponseHandlerArg<
786 typename HandlerTraits<HandlerT>::Type>::ArgType;
787 HandlerArgType Result((typename HandlerArgType::value_type()));
788
789 if (auto Err =
790 SerializationTraits<ChannelT, Expected<FuncRetT>,
791 HandlerArgType>::deserialize(C, Result))
792 return Err;
793 if (auto Err = C.endReceiveMessage())
794 return Err;
795 return Handler(std::move(Result));
796 }
797
798 // Abandon this response by calling the handler with an 'abandoned response'
799 // error.
800 void abandon() override {
801 if (auto Err = Handler(this->createAbandonedResponseError())) {
802 // Handlers should not fail when passed an abandoned response error.
803 report_fatal_error(std::move(Err));
804 }
805 }
806
807private:
808 HandlerT Handler;
809};
810
811template <typename ChannelT, typename HandlerT>
812class ResponseHandlerImpl<ChannelT, Error, HandlerT>
813 : public ResponseHandler<ChannelT> {
814public:
815 ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
816
817 // Handle the result by deserializing it from the channel then passing it
818 // to the user defined handler.
819 Error handleResponse(ChannelT &C) override {
820 Error Result = Error::success();
821 if (auto Err =
822 SerializationTraits<ChannelT, Error, Error>::deserialize(C, Result))
823 return Err;
824 if (auto Err = C.endReceiveMessage())
825 return Err;
826 return Handler(std::move(Result));
827 }
828
829 // Abandon this response by calling the handler with an 'abandoned response'
830 // error.
831 void abandon() override {
832 if (auto Err = Handler(this->createAbandonedResponseError())) {
833 // Handlers should not fail when passed an abandoned response error.
834 report_fatal_error(std::move(Err));
835 }
836 }
837
838private:
839 HandlerT Handler;
840};
841
842// Create a ResponseHandler from a given user handler.
843template <typename ChannelT, typename FuncRetT, typename HandlerT>
844std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
845 return llvm::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
846 std::move(H));
847}
848
849// Helper for wrapping member functions up as functors. This is useful for
850// installing methods as result handlers.
851template <typename ClassT, typename RetT, typename... ArgTs>
852class MemberFnWrapper {
853public:
854 using MethodT = RetT (ClassT::*)(ArgTs...);
855 MemberFnWrapper(ClassT &Instance, MethodT Method)
856 : Instance(Instance), Method(Method) {}
857 RetT operator()(ArgTs &&... Args) {
858 return (Instance.*Method)(std::move(Args)...);
859 }
860
861private:
862 ClassT &Instance;
863 MethodT Method;
864};
865
866// Helper that provides a Functor for deserializing arguments.
867template <typename... ArgTs> class ReadArgs {
868public:
869 Error operator()() { return Error::success(); }
870};
871
872template <typename ArgT, typename... ArgTs>
873class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {
874public:
875 ReadArgs(ArgT &Arg, ArgTs &... Args)
876 : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
877
878 Error operator()(ArgT &ArgVal, ArgTs &... ArgVals) {
879 this->Arg = std::move(ArgVal);
880 return ReadArgs<ArgTs...>::operator()(ArgVals...);
881 }
882
883private:
884 ArgT &Arg;
885};
886
887// Manage sequence numbers.
888template <typename SequenceNumberT> class SequenceNumberManager {
889public:
890 // Reset, making all sequence numbers available.
891 void reset() {
892 std::lock_guard<std::mutex> Lock(SeqNoLock);
893 NextSequenceNumber = 0;
894 FreeSequenceNumbers.clear();
895 }
896
897 // Get the next available sequence number. Will re-use numbers that have
898 // been released.
899 SequenceNumberT getSequenceNumber() {
900 std::lock_guard<std::mutex> Lock(SeqNoLock);
901 if (FreeSequenceNumbers.empty())
902 return NextSequenceNumber++;
903 auto SequenceNumber = FreeSequenceNumbers.back();
904 FreeSequenceNumbers.pop_back();
905 return SequenceNumber;
906 }
907
908 // Release a sequence number, making it available for re-use.
909 void releaseSequenceNumber(SequenceNumberT SequenceNumber) {
910 std::lock_guard<std::mutex> Lock(SeqNoLock);
911 FreeSequenceNumbers.push_back(SequenceNumber);
912 }
913
914private:
915 std::mutex SeqNoLock;
916 SequenceNumberT NextSequenceNumber = 0;
917 std::vector<SequenceNumberT> FreeSequenceNumbers;
918};
919
920// Checks that predicate P holds for each corresponding pair of type arguments
921// from T1 and T2 tuple.
922template <template <class, class> class P, typename T1Tuple, typename T2Tuple>
923class RPCArgTypeCheckHelper;
924
925template <template <class, class> class P>
926class RPCArgTypeCheckHelper<P, std::tuple<>, std::tuple<>> {
927public:
928 static const bool value = true;
929};
930
931template <template <class, class> class P, typename T, typename... Ts,
932 typename U, typename... Us>
933class RPCArgTypeCheckHelper<P, std::tuple<T, Ts...>, std::tuple<U, Us...>> {
934public:
935 static const bool value =
936 P<T, U>::value &&
937 RPCArgTypeCheckHelper<P, std::tuple<Ts...>, std::tuple<Us...>>::value;
938};
939
940template <template <class, class> class P, typename T1Sig, typename T2Sig>
941class RPCArgTypeCheck {
942public:
943 using T1Tuple = typename FunctionArgsTuple<T1Sig>::Type;
944 using T2Tuple = typename FunctionArgsTuple<T2Sig>::Type;
945
946 static_assert(std::tuple_size<T1Tuple>::value >=
947 std::tuple_size<T2Tuple>::value,
948 "Too many arguments to RPC call");
949 static_assert(std::tuple_size<T1Tuple>::value <=
950 std::tuple_size<T2Tuple>::value,
951 "Too few arguments to RPC call");
952
953 static const bool value = RPCArgTypeCheckHelper<P, T1Tuple, T2Tuple>::value;
954};
955
956template <typename ChannelT, typename WireT, typename ConcreteT>
957class CanSerialize {
958private:
959 using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
960
961 template <typename T>
962 static std::true_type
963 check(typename std::enable_if<
964 std::is_same<decltype(T::serialize(std::declval<ChannelT &>(),
965 std::declval<const ConcreteT &>())),
966 Error>::value,
967 void *>::type);
968
969 template <typename> static std::false_type check(...);
970
971public:
972 static const bool value = decltype(check<S>(0))::value;
973};
974
975template <typename ChannelT, typename WireT, typename ConcreteT>
976class CanDeserialize {
977private:
978 using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
979
980 template <typename T>
981 static std::true_type
982 check(typename std::enable_if<
983 std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
984 std::declval<ConcreteT &>())),
985 Error>::value,
986 void *>::type);
987
988 template <typename> static std::false_type check(...);
989
990public:
991 static const bool value = decltype(check<S>(0))::value;
992};
993
994/// Contains primitive utilities for defining, calling and handling calls to
995/// remote procedures. ChannelT is a bidirectional stream conforming to the
996/// RPCChannel interface (see RPCChannel.h), FunctionIdT is a procedure
997/// identifier type that must be serializable on ChannelT, and SequenceNumberT
998/// is an integral type that will be used to number in-flight function calls.
999///
1000/// These utilities support the construction of very primitive RPC utilities.
1001/// Their intent is to ensure correct serialization and deserialization of
1002/// procedure arguments, and to keep the client and server's view of the API in
1003/// sync.
1004template <typename ImplT, typename ChannelT, typename FunctionIdT,
1005 typename SequenceNumberT>
1006class RPCEndpointBase {
1007protected:
1008 class OrcRPCInvalid : public Function<OrcRPCInvalid, void()> {
1009 public:
1010 static const char *getName() { return "__orc_rpc$invalid"; }
1011 };
1012
1013 class OrcRPCResponse : public Function<OrcRPCResponse, void()> {
1014 public:
1015 static const char *getName() { return "__orc_rpc$response"; }
1016 };
1017
1018 class OrcRPCNegotiate
1019 : public Function<OrcRPCNegotiate, FunctionIdT(std::string)> {
1020 public:
1021 static const char *getName() { return "__orc_rpc$negotiate"; }
1022 };
1023
1024 // Helper predicate for testing for the presence of SerializeTraits
1025 // serializers.
1026 template <typename WireT, typename ConcreteT>
1027 class CanSerializeCheck : detail::CanSerialize<ChannelT, WireT, ConcreteT> {
1028 public:
1029 using detail::CanSerialize<ChannelT, WireT, ConcreteT>::value;
1030
1031 static_assert(value, "Missing serializer for argument (Can't serialize the "
1032 "first template type argument of CanSerializeCheck "
1033 "from the second)");
1034 };
1035
1036 // Helper predicate for testing for the presence of SerializeTraits
1037 // deserializers.
1038 template <typename WireT, typename ConcreteT>
1039 class CanDeserializeCheck
1040 : detail::CanDeserialize<ChannelT, WireT, ConcreteT> {
1041 public:
1042 using detail::CanDeserialize<ChannelT, WireT, ConcreteT>::value;
1043
1044 static_assert(value, "Missing deserializer for argument (Can't deserialize "
1045 "the second template type argument of "
1046 "CanDeserializeCheck from the first)");
1047 };
1048
1049public:
1050 /// Construct an RPC instance on a channel.
1051 RPCEndpointBase(ChannelT &C, bool LazyAutoNegotiation)
1052 : C(C), LazyAutoNegotiation(LazyAutoNegotiation) {
1053 // Hold ResponseId in a special variable, since we expect Response to be
1054 // called relatively frequently, and want to avoid the map lookup.
1055 ResponseId = FnIdAllocator.getResponseId();
1056 RemoteFunctionIds[OrcRPCResponse::getPrototype()] = ResponseId;
1057
1058 // Register the negotiate function id and handler.
1059 auto NegotiateId = FnIdAllocator.getNegotiateId();
1060 RemoteFunctionIds[OrcRPCNegotiate::getPrototype()] = NegotiateId;
1061 Handlers[NegotiateId] = wrapHandler<OrcRPCNegotiate>(
1062 [this](const std::string &Name) { return handleNegotiate(Name); });
1063 }
1064
1065
1066 /// Negotiate a function id for Func with the other end of the channel.
1067 template <typename Func> Error negotiateFunction(bool Retry = false) {
1068 return getRemoteFunctionId<Func>(true, Retry).takeError();
1069 }
1070
1071 /// Append a call Func, does not call send on the channel.
1072 /// The first argument specifies a user-defined handler to be run when the
1073 /// function returns. The handler should take an Expected<Func::ReturnType>,
1074 /// or an Error (if Func::ReturnType is void). The handler will be called
1075 /// with an error if the return value is abandoned due to a channel error.
1076 template <typename Func, typename HandlerT, typename... ArgTs>
1077 Error appendCallAsync(HandlerT Handler, const ArgTs &... Args) {
1078
1079 static_assert(
1080 detail::RPCArgTypeCheck<CanSerializeCheck, typename Func::Type,
1081 void(ArgTs...)>::value,
1082 "");
1083
1084 // Look up the function ID.
1085 FunctionIdT FnId;
1086 if (auto FnIdOrErr = getRemoteFunctionId<Func>(LazyAutoNegotiation, false))
1087 FnId = *FnIdOrErr;
1088 else {
1089 // Negotiation failed. Notify the handler then return the negotiate-failed
1090 // error.
1091 cantFail(Handler(make_error<ResponseAbandoned>()));
1092 return FnIdOrErr.takeError();
1093 }
1094
1095 SequenceNumberT SeqNo; // initialized in locked scope below.
1096 {
1097 // Lock the pending responses map and sequence number manager.
1098 std::lock_guard<std::mutex> Lock(ResponsesMutex);
1099
1100 // Allocate a sequence number.
1101 SeqNo = SequenceNumberMgr.getSequenceNumber();
1102 assert(!PendingResponses.count(SeqNo) &&(static_cast <bool> (!PendingResponses.count(SeqNo) &&
"Sequence number already allocated") ? void (0) : __assert_fail
("!PendingResponses.count(SeqNo) && \"Sequence number already allocated\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1103, __extension__ __PRETTY_FUNCTION__))
1103 "Sequence number already allocated")(static_cast <bool> (!PendingResponses.count(SeqNo) &&
"Sequence number already allocated") ? void (0) : __assert_fail
("!PendingResponses.count(SeqNo) && \"Sequence number already allocated\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1103, __extension__ __PRETTY_FUNCTION__))
;
1104
1105 // Install the user handler.
1106 PendingResponses[SeqNo] =
1107 detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
1108 std::move(Handler));
1109 }
1110
1111 // Open the function call message.
1112 if (auto Err = C.startSendMessage(FnId, SeqNo)) {
1113 abandonPendingResponses();
1114 return Err;
1115 }
1116
1117 // Serialize the call arguments.
1118 if (auto Err = detail::HandlerTraits<typename Func::Type>::serializeArgs(
1119 C, Args...)) {
1120 abandonPendingResponses();
1121 return Err;
1122 }
1123
1124 // Close the function call messagee.
1125 if (auto Err = C.endSendMessage()) {
1126 abandonPendingResponses();
1127 return Err;
1128 }
1129
1130 return Error::success();
1131 }
1132
1133 Error sendAppendedCalls() { return C.send(); };
1134
1135 template <typename Func, typename HandlerT, typename... ArgTs>
1136 Error callAsync(HandlerT Handler, const ArgTs &... Args) {
1137 if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
1138 return Err;
1139 return C.send();
1140 }
1141
1142 /// Handle one incoming call.
1143 Error handleOne() {
1144 FunctionIdT FnId;
1145 SequenceNumberT SeqNo;
1146 if (auto Err = C.startReceiveMessage(FnId, SeqNo)) {
60
Taking false branch
1147 abandonPendingResponses();
1148 return Err;
1149 }
1150 if (FnId == ResponseId)
61
Taking false branch
1151 return handleResponse(SeqNo);
1152 auto I = Handlers.find(FnId);
1153 if (I != Handlers.end())
62
Assuming the condition is false
63
Taking false branch
1154 return I->second(C, SeqNo);
1155
1156 // else: No handler found. Report error to client?
1157 return make_error<BadFunctionCall<FunctionIdT, SequenceNumberT>>(FnId,
64
Calling 'make_error'
1158 SeqNo);
1159 }
1160
1161 /// Helper for handling setter procedures - this method returns a functor that
1162 /// sets the variables referred to by Args... to values deserialized from the
1163 /// channel.
1164 /// E.g.
1165 ///
1166 /// typedef Function<0, bool, int> Func1;
1167 ///
1168 /// ...
1169 /// bool B;
1170 /// int I;
1171 /// if (auto Err = expect<Func1>(Channel, readArgs(B, I)))
1172 /// /* Handle Args */ ;
1173 ///
1174 template <typename... ArgTs>
1175 static detail::ReadArgs<ArgTs...> readArgs(ArgTs &... Args) {
1176 return detail::ReadArgs<ArgTs...>(Args...);
1177 }
1178
1179 /// Abandon all outstanding result handlers.
1180 ///
1181 /// This will call all currently registered result handlers to receive an
1182 /// "abandoned" error as their argument. This is used internally by the RPC
1183 /// in error situations, but can also be called directly by clients who are
1184 /// disconnecting from the remote and don't or can't expect responses to their
1185 /// outstanding calls. (Especially for outstanding blocking calls, calling
1186 /// this function may be necessary to avoid dead threads).
1187 void abandonPendingResponses() {
1188 // Lock the pending responses map and sequence number manager.
1189 std::lock_guard<std::mutex> Lock(ResponsesMutex);
1190
1191 for (auto &KV : PendingResponses)
1192 KV.second->abandon();
1193 PendingResponses.clear();
1194 SequenceNumberMgr.reset();
1195 }
1196
1197 /// Remove the handler for the given function.
1198 /// A handler must currently be registered for this function.
1199 template <typename Func>
1200 void removeHandler() {
1201 auto IdItr = LocalFunctionIds.find(Func::getPrototype());
1202 assert(IdItr != LocalFunctionIds.end() &&(static_cast <bool> (IdItr != LocalFunctionIds.end() &&
"Function does not have a registered handler") ? void (0) : __assert_fail
("IdItr != LocalFunctionIds.end() && \"Function does not have a registered handler\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1203, __extension__ __PRETTY_FUNCTION__))
1203 "Function does not have a registered handler")(static_cast <bool> (IdItr != LocalFunctionIds.end() &&
"Function does not have a registered handler") ? void (0) : __assert_fail
("IdItr != LocalFunctionIds.end() && \"Function does not have a registered handler\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1203, __extension__ __PRETTY_FUNCTION__))
;
1204 auto HandlerItr = Handlers.find(IdItr->second);
1205 assert(HandlerItr != Handlers.end() &&(static_cast <bool> (HandlerItr != Handlers.end() &&
"Function does not have a registered handler") ? void (0) : __assert_fail
("HandlerItr != Handlers.end() && \"Function does not have a registered handler\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1206, __extension__ __PRETTY_FUNCTION__))
1206 "Function does not have a registered handler")(static_cast <bool> (HandlerItr != Handlers.end() &&
"Function does not have a registered handler") ? void (0) : __assert_fail
("HandlerItr != Handlers.end() && \"Function does not have a registered handler\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1206, __extension__ __PRETTY_FUNCTION__))
;
1207 Handlers.erase(HandlerItr);
1208 }
1209
1210 /// Clear all handlers.
1211 void clearHandlers() {
1212 Handlers.clear();
1213 }
1214
1215protected:
1216
1217 FunctionIdT getInvalidFunctionId() const {
1218 return FnIdAllocator.getInvalidId();
1219 }
1220
1221 /// Add the given handler to the handler map and make it available for
1222 /// autonegotiation and execution.
1223 template <typename Func, typename HandlerT>
1224 void addHandlerImpl(HandlerT Handler) {
1225
1226 static_assert(detail::RPCArgTypeCheck<
1227 CanDeserializeCheck, typename Func::Type,
1228 typename detail::HandlerTraits<HandlerT>::Type>::value,
1229 "");
1230
1231 FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
1232 LocalFunctionIds[Func::getPrototype()] = NewFnId;
1233 Handlers[NewFnId] = wrapHandler<Func>(std::move(Handler));
1234 }
1235
1236 template <typename Func, typename HandlerT>
1237 void addAsyncHandlerImpl(HandlerT Handler) {
1238
1239 static_assert(detail::RPCArgTypeCheck<
1240 CanDeserializeCheck, typename Func::Type,
1241 typename detail::AsyncHandlerTraits<
1242 typename detail::HandlerTraits<HandlerT>::Type
1243 >::Type>::value,
1244 "");
1245
1246 FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
1247 LocalFunctionIds[Func::getPrototype()] = NewFnId;
1248 Handlers[NewFnId] = wrapAsyncHandler<Func>(std::move(Handler));
1249 }
1250
1251 Error handleResponse(SequenceNumberT SeqNo) {
1252 using Handler = typename decltype(PendingResponses)::mapped_type;
1253 Handler PRHandler;
1254
1255 {
1256 // Lock the pending responses map and sequence number manager.
1257 std::unique_lock<std::mutex> Lock(ResponsesMutex);
1258 auto I = PendingResponses.find(SeqNo);
1259
1260 if (I != PendingResponses.end()) {
1261 PRHandler = std::move(I->second);
1262 PendingResponses.erase(I);
1263 SequenceNumberMgr.releaseSequenceNumber(SeqNo);
1264 } else {
1265 // Unlock the pending results map to prevent recursive lock.
1266 Lock.unlock();
1267 abandonPendingResponses();
1268 return make_error<
1269 InvalidSequenceNumberForResponse<SequenceNumberT>>(SeqNo);
1270 }
1271 }
1272
1273 assert(PRHandler &&(static_cast <bool> (PRHandler && "If we didn't find a response handler we should have bailed out"
) ? void (0) : __assert_fail ("PRHandler && \"If we didn't find a response handler we should have bailed out\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1274, __extension__ __PRETTY_FUNCTION__))
1274 "If we didn't find a response handler we should have bailed out")(static_cast <bool> (PRHandler && "If we didn't find a response handler we should have bailed out"
) ? void (0) : __assert_fail ("PRHandler && \"If we didn't find a response handler we should have bailed out\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ExecutionEngine/Orc/RPCUtils.h"
, 1274, __extension__ __PRETTY_FUNCTION__))
;
1275
1276 if (auto Err = PRHandler->handleResponse(C)) {
1277 abandonPendingResponses();
1278 return Err;
1279 }
1280
1281 return Error::success();
1282 }
1283
1284 FunctionIdT handleNegotiate(const std::string &Name) {
1285 auto I = LocalFunctionIds.find(Name);
1286 if (I == LocalFunctionIds.end())
1287 return getInvalidFunctionId();
1288 return I->second;
1289 }
1290
1291 // Find the remote FunctionId for the given function.
1292 template <typename Func>
1293 Expected<FunctionIdT> getRemoteFunctionId(bool NegotiateIfNotInMap,
1294 bool NegotiateIfInvalid) {
1295 bool DoNegotiate;
1296
1297 // Check if we already have a function id...
1298 auto I = RemoteFunctionIds.find(Func::getPrototype());
1299 if (I != RemoteFunctionIds.end()) {
1300 // If it's valid there's nothing left to do.
1301 if (I->second != getInvalidFunctionId())
1302 return I->second;
1303 DoNegotiate = NegotiateIfInvalid;
1304 } else
1305 DoNegotiate = NegotiateIfNotInMap;
1306
1307 // We don't have a function id for Func yet, but we're allowed to try to
1308 // negotiate one.
1309 if (DoNegotiate) {
1310 auto &Impl = static_cast<ImplT &>(*this);
1311 if (auto RemoteIdOrErr =
1312 Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
1313 RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
1314 if (*RemoteIdOrErr == getInvalidFunctionId())
1315 return make_error<CouldNotNegotiate>(Func::getPrototype());
1316 return *RemoteIdOrErr;
1317 } else
1318 return RemoteIdOrErr.takeError();
1319 }
1320
1321 // No key was available in the map and we weren't allowed to try to
1322 // negotiate one, so return an unknown function error.
1323 return make_error<CouldNotNegotiate>(Func::getPrototype());
1324 }
1325
1326 using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
1327
1328 // Wrap the given user handler in the necessary argument-deserialization code,
1329 // result-serialization code, and call to the launch policy (if present).
1330 template <typename Func, typename HandlerT>
1331 WrappedHandlerFn wrapHandler(HandlerT Handler) {
1332 return [this, Handler](ChannelT &Channel,
1333 SequenceNumberT SeqNo) mutable -> Error {
1334 // Start by deserializing the arguments.
1335 using ArgsTuple =
1336 typename detail::FunctionArgsTuple<
1337 typename detail::HandlerTraits<HandlerT>::Type>::Type;
1338 auto Args = std::make_shared<ArgsTuple>();
1339
1340 if (auto Err =
1341 detail::HandlerTraits<typename Func::Type>::deserializeArgs(
1342 Channel, *Args))
1343 return Err;
1344
1345 // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
1346 // for RPCArgs. Void cast RPCArgs to work around this for now.
1347 // FIXME: Remove this workaround once we can assume a working GCC version.
1348 (void)Args;
1349
1350 // End receieve message, unlocking the channel for reading.
1351 if (auto Err = Channel.endReceiveMessage())
1352 return Err;
1353
1354 using HTraits = detail::HandlerTraits<HandlerT>;
1355 using FuncReturn = typename Func::ReturnType;
1356 return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
1357 HTraits::unpackAndRun(Handler, *Args));
1358 };
1359 }
1360
1361 // Wrap the given user handler in the necessary argument-deserialization code,
1362 // result-serialization code, and call to the launch policy (if present).
1363 template <typename Func, typename HandlerT>
1364 WrappedHandlerFn wrapAsyncHandler(HandlerT Handler) {
1365 return [this, Handler](ChannelT &Channel,
1366 SequenceNumberT SeqNo) mutable -> Error {
1367 // Start by deserializing the arguments.
1368 using AHTraits = detail::AsyncHandlerTraits<
1369 typename detail::HandlerTraits<HandlerT>::Type>;
1370 using ArgsTuple =
1371 typename detail::FunctionArgsTuple<typename AHTraits::Type>::Type;
1372 auto Args = std::make_shared<ArgsTuple>();
1373
1374 if (auto Err =
1375 detail::HandlerTraits<typename Func::Type>::deserializeArgs(
1376 Channel, *Args))
1377 return Err;
1378
1379 // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
1380 // for RPCArgs. Void cast RPCArgs to work around this for now.
1381 // FIXME: Remove this workaround once we can assume a working GCC version.
1382 (void)Args;
1383
1384 // End receieve message, unlocking the channel for reading.
1385 if (auto Err = Channel.endReceiveMessage())
1386 return Err;
1387
1388 using HTraits = detail::HandlerTraits<HandlerT>;
1389 using FuncReturn = typename Func::ReturnType;
1390 auto Responder =
1391 [this, SeqNo](typename AHTraits::ResultType RetVal) -> Error {
1392 return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
1393 std::move(RetVal));
1394 };
1395
1396 return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
1397 };
1398 }
1399
1400 ChannelT &C;
1401
1402 bool LazyAutoNegotiation;
1403
1404 RPCFunctionIdAllocator<FunctionIdT> FnIdAllocator;
1405
1406 FunctionIdT ResponseId;
1407 std::map<std::string, FunctionIdT> LocalFunctionIds;
1408 std::map<const char *, FunctionIdT> RemoteFunctionIds;
1409
1410 std::map<FunctionIdT, WrappedHandlerFn> Handlers;
1411
1412 std::mutex ResponsesMutex;
1413 detail::SequenceNumberManager<SequenceNumberT> SequenceNumberMgr;
1414 std::map<SequenceNumberT, std::unique_ptr<detail::ResponseHandler<ChannelT>>>
1415 PendingResponses;
1416};
1417
1418} // end namespace detail
1419
1420template <typename ChannelT, typename FunctionIdT = uint32_t,
1421 typename SequenceNumberT = uint32_t>
1422class MultiThreadedRPCEndpoint
1423 : public detail::RPCEndpointBase<
1424 MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
1425 ChannelT, FunctionIdT, SequenceNumberT> {
1426private:
1427 using BaseClass =
1428 detail::RPCEndpointBase<
1429 MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
1430 ChannelT, FunctionIdT, SequenceNumberT>;
1431
1432public:
1433 MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
1434 : BaseClass(C, LazyAutoNegotiation) {}
1435
1436 /// Add a handler for the given RPC function.
1437 /// This installs the given handler functor for the given RPC Function, and
1438 /// makes the RPC function available for negotiation/calling from the remote.
1439 template <typename Func, typename HandlerT>
1440 void addHandler(HandlerT Handler) {
1441 return this->template addHandlerImpl<Func>(std::move(Handler));
1442 }
1443
1444 /// Add a class-method as a handler.
1445 template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
1446 void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
1447 addHandler<Func>(
1448 detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
1449 }
1450
1451 template <typename Func, typename HandlerT>
1452 void addAsyncHandler(HandlerT Handler) {
1453 return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
1454 }
1455
1456 /// Add a class-method as a handler.
1457 template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
1458 void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
1459 addAsyncHandler<Func>(
1460 detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
1461 }
1462
1463 /// Return type for non-blocking call primitives.
1464 template <typename Func>
1465 using NonBlockingCallResult = typename detail::ResultTraits<
1466 typename Func::ReturnType>::ReturnFutureType;
1467
1468 /// Call Func on Channel C. Does not block, does not call send. Returns a pair
1469 /// of a future result and the sequence number assigned to the result.
1470 ///
1471 /// This utility function is primarily used for single-threaded mode support,
1472 /// where the sequence number can be used to wait for the corresponding
1473 /// result. In multi-threaded mode the appendCallNB method, which does not
1474 /// return the sequence numeber, should be preferred.
1475 template <typename Func, typename... ArgTs>
1476 Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &... Args) {
1477 using RTraits = detail::ResultTraits<typename Func::ReturnType>;
1478 using ErrorReturn = typename RTraits::ErrorReturnType;
1479 using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
1480
1481 // FIXME: Stack allocate and move this into the handler once LLVM builds
1482 // with C++14.
1483 auto Promise = std::make_shared<ErrorReturnPromise>();
1484 auto FutureResult = Promise->get_future();
1485
1486 if (auto Err = this->template appendCallAsync<Func>(
1487 [Promise](ErrorReturn RetOrErr) {
1488 Promise->set_value(std::move(RetOrErr));
1489 return Error::success();
1490 },
1491 Args...)) {
1492 RTraits::consumeAbandoned(FutureResult.get());
1493 return std::move(Err);
1494 }
1495 return std::move(FutureResult);
1496 }
1497
1498 /// The same as appendCallNBWithSeq, except that it calls C.send() to
1499 /// flush the channel after serializing the call.
1500 template <typename Func, typename... ArgTs>
1501 Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &... Args) {
1502 auto Result = appendCallNB<Func>(Args...);
1503 if (!Result)
1504 return Result;
1505 if (auto Err = this->C.send()) {
1506 this->abandonPendingResponses();
1507 detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
1508 std::move(Result->get()));
1509 return std::move(Err);
1510 }
1511 return Result;
1512 }
1513
1514 /// Call Func on Channel C. Blocks waiting for a result. Returns an Error
1515 /// for void functions or an Expected<T> for functions returning a T.
1516 ///
1517 /// This function is for use in threaded code where another thread is
1518 /// handling responses and incoming calls.
1519 template <typename Func, typename... ArgTs,
1520 typename AltRetT = typename Func::ReturnType>
1521 typename detail::ResultTraits<AltRetT>::ErrorReturnType
1522 callB(const ArgTs &... Args) {
1523 if (auto FutureResOrErr = callNB<Func>(Args...))
1524 return FutureResOrErr->get();
1525 else
1526 return FutureResOrErr.takeError();
1527 }
1528
1529 /// Handle incoming RPC calls.
1530 Error handlerLoop() {
1531 while (true)
1532 if (auto Err = this->handleOne())
1533 return Err;
1534 return Error::success();
1535 }
1536};
1537
1538template <typename ChannelT, typename FunctionIdT = uint32_t,
1539 typename SequenceNumberT = uint32_t>
1540class SingleThreadedRPCEndpoint
1541 : public detail::RPCEndpointBase<
1542 SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
1543 ChannelT, FunctionIdT, SequenceNumberT> {
1544private:
1545 using BaseClass =
1546 detail::RPCEndpointBase<
1547 SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
1548 ChannelT, FunctionIdT, SequenceNumberT>;
1549
1550public:
1551 SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
1552 : BaseClass(C, LazyAutoNegotiation) {}
1553
1554 template <typename Func, typename HandlerT>
1555 void addHandler(HandlerT Handler) {
1556 return this->template addHandlerImpl<Func>(std::move(Handler));
1557 }
1558
1559 template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
1560 void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
1561 addHandler<Func>(
1562 detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
1563 }
1564
1565 template <typename Func, typename HandlerT>
1566 void addAsyncHandler(HandlerT Handler) {
1567 return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
1568 }
1569
1570 /// Add a class-method as a handler.
1571 template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
1572 void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
1573 addAsyncHandler<Func>(
1574 detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
1575 }
1576
1577 template <typename Func, typename... ArgTs,
1578 typename AltRetT = typename Func::ReturnType>
1579 typename detail::ResultTraits<AltRetT>::ErrorReturnType
1580 callB(const ArgTs &... Args) {
1581 bool ReceivedResponse = false;
1582 using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
1583 auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
1584
1585 // We have to 'Check' result (which we know is in a success state at this
1586 // point) so that it can be overwritten in the async handler.
1587 (void)!!Result;
1588
1589 if (auto Err = this->template appendCallAsync<Func>(
56
Taking false branch
1590 [&](ResultType R) {
1591 Result = std::move(R);
1592 ReceivedResponse = true;
1593 return Error::success();
1594 },
1595 Args...)) {
1596 detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
1597 std::move(Result));
1598 return std::move(Err);
1599 }
1600
1601 while (!ReceivedResponse) {
57
Assuming 'ReceivedResponse' is 0
58
Loop condition is true. Entering loop body
1602 if (auto Err = this->handleOne()) {
59
Calling 'RPCEndpointBase::handleOne'
1603 detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
1604 std::move(Result));
1605 return std::move(Err);
1606 }
1607 }
1608
1609 return Result;
1610 }
1611};
1612
1613/// Asynchronous dispatch for a function on an RPC endpoint.
1614template <typename RPCClass, typename Func>
1615class RPCAsyncDispatch {
1616public:
1617 RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
1618
1619 template <typename HandlerT, typename... ArgTs>
1620 Error operator()(HandlerT Handler, const ArgTs &... Args) const {
1621 return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
1622 }
1623
1624private:
1625 RPCClass &Endpoint;
1626};
1627
1628/// Construct an asynchronous dispatcher from an RPC endpoint and a Func.
1629template <typename Func, typename RPCEndpointT>
1630RPCAsyncDispatch<RPCEndpointT, Func> rpcAsyncDispatch(RPCEndpointT &Endpoint) {
1631 return RPCAsyncDispatch<RPCEndpointT, Func>(Endpoint);
1632}
1633
1634/// \brief Allows a set of asynchrounous calls to be dispatched, and then
1635/// waited on as a group.
1636class ParallelCallGroup {
1637public:
1638
1639 ParallelCallGroup() = default;
1640 ParallelCallGroup(const ParallelCallGroup &) = delete;
1641 ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
1642
1643 /// \brief Make as asynchronous call.
1644 template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
1645 Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
1646 const ArgTs &... Args) {
1647 // Increment the count of outstanding calls. This has to happen before
1648 // we invoke the call, as the handler may (depending on scheduling)
1649 // be run immediately on another thread, and we don't want the decrement
1650 // in the wrapped handler below to run before the increment.
1651 {
1652 std::unique_lock<std::mutex> Lock(M);
1653 ++NumOutstandingCalls;
1654 }
1655
1656 // Wrap the user handler in a lambda that will decrement the
1657 // outstanding calls count, then poke the condition variable.
1658 using ArgType = typename detail::ResponseHandlerArg<
1659 typename detail::HandlerTraits<HandlerT>::Type>::ArgType;
1660 // FIXME: Move handler into wrapped handler once we have C++14.
1661 auto WrappedHandler = [this, Handler](ArgType Arg) {
1662 auto Err = Handler(std::move(Arg));
1663 std::unique_lock<std::mutex> Lock(M);
1664 --NumOutstandingCalls;
1665 CV.notify_all();
1666 return Err;
1667 };
1668
1669 return AsyncDispatch(std::move(WrappedHandler), Args...);
1670 }
1671
1672 /// \brief Blocks until all calls have been completed and their return value
1673 /// handlers run.
1674 void wait() {
1675 std::unique_lock<std::mutex> Lock(M);
1676 while (NumOutstandingCalls > 0)
1677 CV.wait(Lock);
1678 }
1679
1680private:
1681 std::mutex M;
1682 std::condition_variable CV;
1683 uint32_t NumOutstandingCalls = 0;
1684};
1685
1686/// @brief Convenience class for grouping RPC Functions into APIs that can be
1687/// negotiated as a block.
1688///
1689template <typename... Funcs>
1690class APICalls {
1691public:
1692
1693 /// @brief Test whether this API contains Function F.
1694 template <typename F>
1695 class Contains {
1696 public:
1697 static const bool value = false;
1698 };
1699
1700 /// @brief Negotiate all functions in this API.
1701 template <typename RPCEndpoint>
1702 static Error negotiate(RPCEndpoint &R) {
1703 return Error::success();
1704 }
1705};
1706
1707template <typename Func, typename... Funcs>
1708class APICalls<Func, Funcs...> {
1709public:
1710
1711 template <typename F>
1712 class Contains {
1713 public:
1714 static const bool value = std::is_same<F, Func>::value |
1715 APICalls<Funcs...>::template Contains<F>::value;
1716 };
1717
1718 template <typename RPCEndpoint>
1719 static Error negotiate(RPCEndpoint &R) {
1720 if (auto Err = R.template negotiateFunction<Func>())
1721 return Err;
1722 return APICalls<Funcs...>::negotiate(R);
1723 }
1724
1725};
1726
1727template <typename... InnerFuncs, typename... Funcs>
1728class APICalls<APICalls<InnerFuncs...>, Funcs...> {
1729public:
1730
1731 template <typename F>
1732 class Contains {
1733 public:
1734 static const bool value =
1735 APICalls<InnerFuncs...>::template Contains<F>::value |
1736 APICalls<Funcs...>::template Contains<F>::value;
1737 };
1738
1739 template <typename RPCEndpoint>
1740 static Error negotiate(RPCEndpoint &R) {
1741 if (auto Err = APICalls<InnerFuncs...>::negotiate(R))
1742 return Err;
1743 return APICalls<Funcs...>::negotiate(R);
1744 }
1745
1746};
1747
1748} // end namespace rpc
1749} // end namespace orc
1750} // end namespace llvm
1751
1752#endif

/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/Support/Error.h

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
41namespace llvm {
42
43class ErrorSuccess;
44
45/// Base class for error info classes. Do not extend this directly: Extend
46/// the ErrorInfo template subclass instead.
47class ErrorInfoBase {
48public:
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
85private:
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.
156class 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
169protected:
170 /// Create a success value. Prefer using 'Error::success()' for readability
171 Error() {
172 setPtr(nullptr);
173 setChecked(false);
174 }
175
176public:
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
248private:
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.
311class ErrorSuccess : public Error {};
312
313inline ErrorSuccess Error::success() { return ErrorSuccess(); }
314
315/// Make a Error instance representing failure using the given error info
316/// type.
317template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
318 return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
65
Calling 'make_unique'
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.
330template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
331class ErrorInfo : public ParentErrT {
332public:
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.
344class 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
353public:
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
367private:
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-6.0~svn319013/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-6.0~svn319013/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.
408inline 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.
418template <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
428public:
429 using storage_type = typename std::conditional<isRef, wrap, T>::type;
430 using value_type = T;
431
432private:
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
438public:
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-6.0~svn319013/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
568private:
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-6.0~svn319013/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-6.0~svn319013/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-6.0~svn319013/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-6.0~svn319013/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.
672LLVM_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
688inline 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-6.0~svn319013/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
709template <typename T>
710T 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-6.0~svn319013/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
733template <typename T>
734T& 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-6.0~svn319013/include/llvm/Support/Error.h"
, 740)
;
741 }
742}
743
744/// Helper for testing applicability of, and applying, handlers for
745/// ErrorInfo types.
746template <typename HandlerT>
747class ErrorHandlerTraits
748 : public ErrorHandlerTraits<decltype(
749 &std::remove_reference<HandlerT>::type::operator())> {};
750
751// Specialization functions of the form 'Error (const ErrT&)'.
752template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
753public:
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-6.0~svn319013/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&)'.
766template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
767public:
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-6.0~svn319013/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>)'.
781template <typename ErrT>
782class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
783public:
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-6.0~svn319013/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>)'.
797template <typename ErrT>
798class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
799public:
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-6.0~svn319013/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&)'.
814template <typename C, typename RetT, typename ErrT>
815class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
816 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
817
818// Specialization for member functions of the form 'RetT (const ErrT&) const'.
819template <typename C, typename RetT, typename ErrT>
820class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
821 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
822
823// Specialization for member functions of the form 'RetT (const ErrT&)'.
824template <typename C, typename RetT, typename ErrT>
825class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
826 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
827
828// Specialization for member functions of the form 'RetT (const ErrT&) const'.
829template <typename C, typename RetT, typename ErrT>
830class 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>)'.
835template <typename C, typename RetT, typename ErrT>
836class 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'.
841template <typename C, typename RetT, typename ErrT>
842class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
843 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
844
845inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
846 return Error(std::move(Payload));
847}
848
849template <typename HandlerT, typename... HandlerTs>
850Error 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.
865template <typename... HandlerTs>
866Error 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.
888template <typename... HandlerTs>
889void 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.
895inline 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
923template <typename T, typename RecoveryFtor, typename... HandlerTs>
924Expected<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.
943void 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.
947inline 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>.
962inline void consumeError(Error Err) {
963 handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
964}
965
966/// Helper for Errors used as out-parameters.
967///
968/// This helper is for use with the Error-as-out-parameter idiom, where an error
969/// is passed to a function or method by reference, rather than being returned.
970/// In such cases it is helpful to set the checked bit on entry to the function
971/// so that the error can be written to (unchecked Errors abort on assignment)
972/// and clear the checked bit on exit so that clients cannot accidentally forget
973/// to check the result. This helper performs these actions automatically using
974/// RAII:
975///
976/// @code{.cpp}
977/// Result foo(Error &Err) {
978/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
979/// // <body of foo>
980/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
981/// }
982/// @endcode
983///
984/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
985/// used with optional Errors (Error pointers that are allowed to be null). If
986/// ErrorAsOutParameter took an Error reference, an instance would have to be
987/// created inside every condition that verified that Error was non-null. By
988/// taking an Error pointer we can just create one instance at the top of the
989/// function.
990class ErrorAsOutParameter {
991public:
992 ErrorAsOutParameter(Error *Err) : Err(Err) {
993 // Raise the checked bit if Err is success.
994 if (Err)
995 (void)!!*Err;
996 }
997
998 ~ErrorAsOutParameter() {
999 // Clear the checked bit.
1000 if (Err && !*Err)
1001 *Err = Error::success();
1002 }
1003
1004private:
1005 Error *Err;
1006};
1007
1008/// Helper for Expected<T>s used as out-parameters.
1009///
1010/// See ErrorAsOutParameter.
1011template <typename T>
1012class ExpectedAsOutParameter {
1013public:
1014 ExpectedAsOutParameter(Expected<T> *ValOrErr)
1015 : ValOrErr(ValOrErr) {
1016 if (ValOrErr)
1017 (void)!!*ValOrErr;
1018 }
1019
1020 ~ExpectedAsOutParameter() {
1021 if (ValOrErr)
1022 ValOrErr->setUnchecked();
1023 }
1024
1025private:
1026 Expected<T> *ValOrErr;
1027};
1028
1029/// This class wraps a std::error_code in a Error.
1030///
1031/// This is useful if you're writing an interface that returns a Error
1032/// (or Expected) and you want to call code that still returns
1033/// std::error_codes.
1034class ECError : public ErrorInfo<ECError> {
1035 friend Error errorCodeToError(std::error_code);
1036
1037public:
1038 void setErrorCode(std::error_code EC) { this->EC = EC; }
1039 std::error_code convertToErrorCode() const override { return EC; }
1040 void log(raw_ostream &OS) const override { OS << EC.message(); }
1041
1042 // Used by ErrorInfo::classID.
1043 static char ID;
1044
1045protected:
1046 ECError() = default;
1047 ECError(std::error_code EC) : EC(EC) {}
1048
1049 std::error_code EC;
1050};
1051
1052/// The value returned by this function can be returned from convertToErrorCode
1053/// for Error values where no sensible translation to std::error_code exists.
1054/// It should only be used in this situation, and should never be used where a
1055/// sensible conversion to std::error_code is available, as attempts to convert
1056/// to/from this error will result in a fatal error. (i.e. it is a programmatic
1057///error to try to convert such a value).
1058std::error_code inconvertibleErrorCode();
1059
1060/// Helper for converting an std::error_code to a Error.
1061Error errorCodeToError(std::error_code EC);
1062
1063/// Helper for converting an ECError to a std::error_code.
1064///
1065/// This method requires that Err be Error() or an ECError, otherwise it
1066/// will trigger a call to abort().
1067std::error_code errorToErrorCode(Error Err);
1068
1069/// Convert an ErrorOr<T> to an Expected<T>.
1070template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
1071 if (auto EC = EO.getError())
1072 return errorCodeToError(EC);
1073 return std::move(*EO);
1074}
1075
1076/// Convert an Expected<T> to an ErrorOr<T>.
1077template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
1078 if (auto Err = E.takeError())
1079 return errorToErrorCode(std::move(Err));
1080 return std::move(*E);
1081}
1082
1083/// This class wraps a string in an Error.
1084///
1085/// StringError is useful in cases where the client is not expected to be able
1086/// to consume the specific error message programmatically (for example, if the
1087/// error message is to be presented to the user).
1088class StringError : public ErrorInfo<StringError> {
1089public:
1090 static char ID;
1091
1092 StringError(const Twine &S, std::error_code EC);
1093
1094 void log(raw_ostream &OS) const override;
1095 std::error_code convertToErrorCode() const override;
1096
1097 const std::string &getMessage() const { return Msg; }
1098
1099private:
1100 std::string Msg;
1101 std::error_code EC;
1102};
1103
1104/// Helper for check-and-exit error handling.
1105///
1106/// For tool use only. NOT FOR USE IN LIBRARY CODE.
1107///
1108class ExitOnError {
1109public:
1110 /// Create an error on exit helper.
1111 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
1112 : Banner(std::move(Banner)),
1113 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
1114
1115 /// Set the banner string for any errors caught by operator().
1116 void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
1117
1118 /// Set the exit-code mapper function.
1119 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
1120 this->GetExitCode = std::move(GetExitCode);
1121 }
1122
1123 /// Check Err. If it's in a failure state log the error(s) and exit.
1124 void operator()(Error Err) const { checkError(std::move(Err)); }
1125
1126 /// Check E. If it's in a success state then return the contained value. If
1127 /// it's in a failure state log the error(s) and exit.
1128 template <typename T> T operator()(Expected<T> &&E) const {
1129 checkError(E.takeError());
1130 return std::move(*E);
1131 }
1132
1133 /// Check E. If it's in a success state then return the contained reference. If
1134 /// it's in a failure state log the error(s) and exit.
1135 template <typename T> T& operator()(Expected<T&> &&E) const {
1136 checkError(E.takeError());
1137 return *E;
1138 }
1139
1140private:
1141 void checkError(Error Err) const {
1142 if (Err) {
1143 int ExitCode = GetExitCode(Err);
1144 logAllUnhandledErrors(std::move(Err), errs(), Banner);
1145 exit(ExitCode);
1146 }
1147 }
1148
1149 std::string Banner;
1150 std::function<int(const Error &)> GetExitCode;
1151};
1152
1153} // end namespace llvm
1154
1155#endif // LLVM_SUPPORT_ERROR_H

/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h

1//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- 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 contains some templates that are useful if you are working with the
11// STL at all.
12//
13// No library is required when using these functions.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_ADT_STLEXTRAS_H
18#define LLVM_ADT_STLEXTRAS_H
19
20#include "llvm/ADT/Optional.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/iterator.h"
23#include "llvm/ADT/iterator_range.h"
24#include "llvm/Support/ErrorHandling.h"
25#include <algorithm>
26#include <cassert>
27#include <cstddef>
28#include <cstdint>
29#include <cstdlib>
30#include <functional>
31#include <initializer_list>
32#include <iterator>
33#include <limits>
34#include <memory>
35#include <tuple>
36#include <type_traits>
37#include <utility>
38
39namespace llvm {
40
41// Only used by compiler if both template types are the same. Useful when
42// using SFINAE to test for the existence of member functions.
43template <typename T, T> struct SameType;
44
45namespace detail {
46
47template <typename RangeT>
48using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
49
50template <typename RangeT>
51using ValueOfRange = typename std::remove_reference<decltype(
52 *std::begin(std::declval<RangeT &>()))>::type;
53
54} // end namespace detail
55
56//===----------------------------------------------------------------------===//
57// Extra additions to <functional>
58//===----------------------------------------------------------------------===//
59
60template <class Ty> struct identity {
61 using argument_type = Ty;
62
63 Ty &operator()(Ty &self) const {
64 return self;
65 }
66 const Ty &operator()(const Ty &self) const {
67 return self;
68 }
69};
70
71template <class Ty> struct less_ptr {
72 bool operator()(const Ty* left, const Ty* right) const {
73 return *left < *right;
74 }
75};
76
77template <class Ty> struct greater_ptr {
78 bool operator()(const Ty* left, const Ty* right) const {
79 return *right < *left;
80 }
81};
82
83/// An efficient, type-erasing, non-owning reference to a callable. This is
84/// intended for use as the type of a function parameter that is not used
85/// after the function in question returns.
86///
87/// This class does not own the callable, so it is not in general safe to store
88/// a function_ref.
89template<typename Fn> class function_ref;
90
91template<typename Ret, typename ...Params>
92class function_ref<Ret(Params...)> {
93 Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
94 intptr_t callable;
95
96 template<typename Callable>
97 static Ret callback_fn(intptr_t callable, Params ...params) {
98 return (*reinterpret_cast<Callable*>(callable))(
99 std::forward<Params>(params)...);
100 }
101
102public:
103 function_ref() = default;
104
105 template <typename Callable>
106 function_ref(Callable &&callable,
107 typename std::enable_if<
108 !std::is_same<typename std::remove_reference<Callable>::type,
109 function_ref>::value>::type * = nullptr)
110 : callback(callback_fn<typename std::remove_reference<Callable>::type>),
111 callable(reinterpret_cast<intptr_t>(&callable)) {}
112
113 Ret operator()(Params ...params) const {
114 return callback(callable, std::forward<Params>(params)...);
115 }
116
117 operator bool() const { return callback; }
118};
119
120// deleter - Very very very simple method that is used to invoke operator
121// delete on something. It is used like this:
122//
123// for_each(V.begin(), B.end(), deleter<Interval>);
124template <class T>
125inline void deleter(T *Ptr) {
126 delete Ptr;
127}
128
129//===----------------------------------------------------------------------===//
130// Extra additions to <iterator>
131//===----------------------------------------------------------------------===//
132
133namespace adl_detail {
134
135using std::begin;
136
137template <typename ContainerTy>
138auto adl_begin(ContainerTy &&container)
139 -> decltype(begin(std::forward<ContainerTy>(container))) {
140 return begin(std::forward<ContainerTy>(container));
141}
142
143using std::end;
144
145template <typename ContainerTy>
146auto adl_end(ContainerTy &&container)
147 -> decltype(end(std::forward<ContainerTy>(container))) {
148 return end(std::forward<ContainerTy>(container));
149}
150
151using std::swap;
152
153template <typename T>
154void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
155 std::declval<T>()))) {
156 swap(std::forward<T>(lhs), std::forward<T>(rhs));
157}
158
159} // end namespace adl_detail
160
161template <typename ContainerTy>
162auto adl_begin(ContainerTy &&container)
163 -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
164 return adl_detail::adl_begin(std::forward<ContainerTy>(container));
165}
166
167template <typename ContainerTy>
168auto adl_end(ContainerTy &&container)
169 -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
170 return adl_detail::adl_end(std::forward<ContainerTy>(container));
171}
172
173template <typename T>
174void adl_swap(T &&lhs, T &&rhs) noexcept(
175 noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) {
176 adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
177}
178
179// mapped_iterator - This is a simple iterator adapter that causes a function to
180// be applied whenever operator* is invoked on the iterator.
181
182template <typename ItTy, typename FuncTy,
183 typename FuncReturnTy =
184 decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
185class mapped_iterator
186 : public iterator_adaptor_base<
187 mapped_iterator<ItTy, FuncTy>, ItTy,
188 typename std::iterator_traits<ItTy>::iterator_category,
189 typename std::remove_reference<FuncReturnTy>::type> {
190public:
191 mapped_iterator(ItTy U, FuncTy F)
192 : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
193
194 ItTy getCurrent() { return this->I; }
195
196 FuncReturnTy operator*() { return F(*this->I); }
197
198private:
199 FuncTy F;
200};
201
202// map_iterator - Provide a convenient way to create mapped_iterators, just like
203// make_pair is useful for creating pairs...
204template <class ItTy, class FuncTy>
205inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) {
206 return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
207}
208
209/// Helper to determine if type T has a member called rbegin().
210template <typename Ty> class has_rbegin_impl {
211 using yes = char[1];
212 using no = char[2];
213
214 template <typename Inner>
215 static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr);
216
217 template <typename>
218 static no& test(...);
219
220public:
221 static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
222};
223
224/// Metafunction to determine if T& or T has a member called rbegin().
225template <typename Ty>
226struct has_rbegin : has_rbegin_impl<typename std::remove_reference<Ty>::type> {
227};
228
229// Returns an iterator_range over the given container which iterates in reverse.
230// Note that the container must have rbegin()/rend() methods for this to work.
231template <typename ContainerTy>
232auto reverse(ContainerTy &&C,
233 typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
234 nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
235 return make_range(C.rbegin(), C.rend());
236}
237
238// Returns a std::reverse_iterator wrapped around the given iterator.
239template <typename IteratorTy>
240std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
241 return std::reverse_iterator<IteratorTy>(It);
242}
243
244// Returns an iterator_range over the given container which iterates in reverse.
245// Note that the container must have begin()/end() methods which return
246// bidirectional iterators for this to work.
247template <typename ContainerTy>
248auto reverse(
249 ContainerTy &&C,
250 typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
251 -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
252 llvm::make_reverse_iterator(std::begin(C)))) {
253 return make_range(llvm::make_reverse_iterator(std::end(C)),
254 llvm::make_reverse_iterator(std::begin(C)));
255}
256
257/// An iterator adaptor that filters the elements of given inner iterators.
258///
259/// The predicate parameter should be a callable object that accepts the wrapped
260/// iterator's reference type and returns a bool. When incrementing or
261/// decrementing the iterator, it will call the predicate on each element and
262/// skip any where it returns false.
263///
264/// \code
265/// int A[] = { 1, 2, 3, 4 };
266/// auto R = make_filter_range(A, [](int N) { return N % 2 == 1; });
267/// // R contains { 1, 3 }.
268/// \endcode
269template <typename WrappedIteratorT, typename PredicateT>
270class filter_iterator
271 : public iterator_adaptor_base<
272 filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
273 typename std::common_type<
274 std::forward_iterator_tag,
275 typename std::iterator_traits<
276 WrappedIteratorT>::iterator_category>::type> {
277 using BaseT = iterator_adaptor_base<
278 filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
279 typename std::common_type<
280 std::forward_iterator_tag,
281 typename std::iterator_traits<WrappedIteratorT>::iterator_category>::
282 type>;
283
284 struct PayloadType {
285 WrappedIteratorT End;
286 PredicateT Pred;
287 };
288
289 Optional<PayloadType> Payload;
290
291 void findNextValid() {
292 assert(Payload && "Payload should be engaged when findNextValid is called")(static_cast <bool> (Payload && "Payload should be engaged when findNextValid is called"
) ? void (0) : __assert_fail ("Payload && \"Payload should be engaged when findNextValid is called\""
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h"
, 292, __extension__ __PRETTY_FUNCTION__))
;
293 while (this->I != Payload->End && !Payload->Pred(*this->I))
294 BaseT::operator++();
295 }
296
297 // Construct the begin iterator. The begin iterator requires to know where end
298 // is, so that it can properly stop when it hits end.
299 filter_iterator(WrappedIteratorT Begin, WrappedIteratorT End, PredicateT Pred)
300 : BaseT(std::move(Begin)),
301 Payload(PayloadType{std::move(End), std::move(Pred)}) {
302 findNextValid();
303 }
304
305 // Construct the end iterator. It's not incrementable, so Payload doesn't
306 // have to be engaged.
307 filter_iterator(WrappedIteratorT End) : BaseT(End) {}
308
309public:
310 using BaseT::operator++;
311
312 filter_iterator &operator++() {
313 BaseT::operator++();
314 findNextValid();
315 return *this;
316 }
317
318 template <typename RT, typename PT>
319 friend iterator_range<filter_iterator<detail::IterOfRange<RT>, PT>>
320 make_filter_range(RT &&, PT);
321};
322
323/// Convenience function that takes a range of elements and a predicate,
324/// and return a new filter_iterator range.
325///
326/// FIXME: Currently if RangeT && is a rvalue reference to a temporary, the
327/// lifetime of that temporary is not kept by the returned range object, and the
328/// temporary is going to be dropped on the floor after the make_iterator_range
329/// full expression that contains this function call.
330template <typename RangeT, typename PredicateT>
331iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
332make_filter_range(RangeT &&Range, PredicateT Pred) {
333 using FilterIteratorT =
334 filter_iterator<detail::IterOfRange<RangeT>, PredicateT>;
335 return make_range(FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
336 std::end(std::forward<RangeT>(Range)),
337 std::move(Pred)),
338 FilterIteratorT(std::end(std::forward<RangeT>(Range))));
339}
340
341// forward declarations required by zip_shortest/zip_first
342template <typename R, typename UnaryPredicate>
343bool all_of(R &&range, UnaryPredicate P);
344
345template <size_t... I> struct index_sequence;
346
347template <class... Ts> struct index_sequence_for;
348
349namespace detail {
350
351using std::declval;
352
353// We have to alias this since inlining the actual type at the usage site
354// in the parameter list of iterator_facade_base<> below ICEs MSVC 2017.
355template<typename... Iters> struct ZipTupleType {
356 using type = std::tuple<decltype(*declval<Iters>())...>;
357};
358
359template <typename ZipType, typename... Iters>
360using zip_traits = iterator_facade_base<
361 ZipType, typename std::common_type<std::bidirectional_iterator_tag,
362 typename std::iterator_traits<
363 Iters>::iterator_category...>::type,
364 // ^ TODO: Implement random access methods.
365 typename ZipTupleType<Iters...>::type,
366 typename std::iterator_traits<typename std::tuple_element<
367 0, std::tuple<Iters...>>::type>::difference_type,
368 // ^ FIXME: This follows boost::make_zip_iterator's assumption that all
369 // inner iterators have the same difference_type. It would fail if, for
370 // instance, the second field's difference_type were non-numeric while the
371 // first is.
372 typename ZipTupleType<Iters...>::type *,
373 typename ZipTupleType<Iters...>::type>;
374
375template <typename ZipType, typename... Iters>
376struct zip_common : public zip_traits<ZipType, Iters...> {
377 using Base = zip_traits<ZipType, Iters...>;
378 using value_type = typename Base::value_type;
379
380 std::tuple<Iters...> iterators;
381
382protected:
383 template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
384 return value_type(*std::get<Ns>(iterators)...);
385 }
386
387 template <size_t... Ns>
388 decltype(iterators) tup_inc(index_sequence<Ns...>) const {
389 return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
390 }
391
392 template <size_t... Ns>
393 decltype(iterators) tup_dec(index_sequence<Ns...>) const {
394 return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...);
395 }
396
397public:
398 zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
399
400 value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
401
402 const value_type operator*() const {
403 return deref(index_sequence_for<Iters...>{});
404 }
405
406 ZipType &operator++() {
407 iterators = tup_inc(index_sequence_for<Iters...>{});
408 return *reinterpret_cast<ZipType *>(this);
409 }
410
411 ZipType &operator--() {
412 static_assert(Base::IsBidirectional,
413 "All inner iterators must be at least bidirectional.");
414 iterators = tup_dec(index_sequence_for<Iters...>{});
415 return *reinterpret_cast<ZipType *>(this);
416 }
417};
418
419template <typename... Iters>
420struct zip_first : public zip_common<zip_first<Iters...>, Iters...> {
421 using Base = zip_common<zip_first<Iters...>, Iters...>;
422
423 bool operator==(const zip_first<Iters...> &other) const {
424 return std::get<0>(this->iterators) == std::get<0>(other.iterators);
425 }
426
427 zip_first(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
428};
429
430template <typename... Iters>
431class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> {
432 template <size_t... Ns>
433 bool test(const zip_shortest<Iters...> &other, index_sequence<Ns...>) const {
434 return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
435 std::get<Ns>(other.iterators)...},
436 identity<bool>{});
437 }
438
439public:
440 using Base = zip_common<zip_shortest<Iters...>, Iters...>;
441
442 zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {}
443
444 bool operator==(const zip_shortest<Iters...> &other) const {
445 return !test(other, index_sequence_for<Iters...>{});
446 }
447};
448
449template <template <typename...> class ItType, typename... Args> class zippy {
450public:
451 using iterator = ItType<decltype(std::begin(std::declval<Args>()))...>;
452 using iterator_category = typename iterator::iterator_category;
453 using value_type = typename iterator::value_type;
454 using difference_type = typename iterator::difference_type;
455 using pointer = typename iterator::pointer;
456 using reference = typename iterator::reference;
457
458private:
459 std::tuple<Args...> ts;
460
461 template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
462 return iterator(std::begin(std::get<Ns>(ts))...);
463 }
464 template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
465 return iterator(std::end(std::get<Ns>(ts))...);
466 }
467
468public:
469 zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
470
471 iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
472 iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
473};
474
475} // end namespace detail
476
477/// zip iterator for two or more iteratable types.
478template <typename T, typename U, typename... Args>
479detail::zippy<detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u,
480 Args &&... args) {
481 return detail::zippy<detail::zip_shortest, T, U, Args...>(
482 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
483}
484
485/// zip iterator that, for the sake of efficiency, assumes the first iteratee to
486/// be the shortest.
487template <typename T, typename U, typename... Args>
488detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
489 Args &&... args) {
490 return detail::zippy<detail::zip_first, T, U, Args...>(
491 std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
492}
493
494/// Iterator wrapper that concatenates sequences together.
495///
496/// This can concatenate different iterators, even with different types, into
497/// a single iterator provided the value types of all the concatenated
498/// iterators expose `reference` and `pointer` types that can be converted to
499/// `ValueT &` and `ValueT *` respectively. It doesn't support more
500/// interesting/customized pointer or reference types.
501///
502/// Currently this only supports forward or higher iterator categories as
503/// inputs and always exposes a forward iterator interface.
504template <typename ValueT, typename... IterTs>
505class concat_iterator
506 : public iterator_facade_base<concat_iterator<ValueT, IterTs...>,
507 std::forward_iterator_tag, ValueT> {
508 using BaseT = typename concat_iterator::iterator_facade_base;
509
510 /// We store both the current and end iterators for each concatenated
511 /// sequence in a tuple of pairs.
512 ///
513 /// Note that something like iterator_range seems nice at first here, but the
514 /// range properties are of little benefit and end up getting in the way
515 /// because we need to do mutation on the current iterators.
516 std::tuple<std::pair<IterTs, IterTs>...> IterPairs;
517
518 /// Attempts to increment a specific iterator.
519 ///
520 /// Returns true if it was able to increment the iterator. Returns false if
521 /// the iterator is already at the end iterator.
522 template <size_t Index> bool incrementHelper() {
523 auto &IterPair = std::get<Index>(IterPairs);
524 if (IterPair.first == IterPair.second)
525 return false;
526
527 ++IterPair.first;
528 return true;
529 }
530
531 /// Increments the first non-end iterator.
532 ///
533 /// It is an error to call this with all iterators at the end.
534 template <size_t... Ns> void increment(index_sequence<Ns...>) {
535 // Build a sequence of functions to increment each iterator if possible.
536 bool (concat_iterator::*IncrementHelperFns[])() = {
537 &concat_iterator::incrementHelper<Ns>...};
538
539 // Loop over them, and stop as soon as we succeed at incrementing one.
540 for (auto &IncrementHelperFn : IncrementHelperFns)
541 if ((this->*IncrementHelperFn)())
542 return;
543
544 llvm_unreachable("Attempted to increment an end concat iterator!")::llvm::llvm_unreachable_internal("Attempted to increment an end concat iterator!"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h"
, 544)
;
545 }
546
547 /// Returns null if the specified iterator is at the end. Otherwise,
548 /// dereferences the iterator and returns the address of the resulting
549 /// reference.
550 template <size_t Index> ValueT *getHelper() const {
551 auto &IterPair = std::get<Index>(IterPairs);
552 if (IterPair.first == IterPair.second)
553 return nullptr;
554
555 return &*IterPair.first;
556 }
557
558 /// Finds the first non-end iterator, dereferences, and returns the resulting
559 /// reference.
560 ///
561 /// It is an error to call this with all iterators at the end.
562 template <size_t... Ns> ValueT &get(index_sequence<Ns...>) const {
563 // Build a sequence of functions to get from iterator if possible.
564 ValueT *(concat_iterator::*GetHelperFns[])() const = {
565 &concat_iterator::getHelper<Ns>...};
566
567 // Loop over them, and return the first result we find.
568 for (auto &GetHelperFn : GetHelperFns)
569 if (ValueT *P = (this->*GetHelperFn)())
570 return *P;
571
572 llvm_unreachable("Attempted to get a pointer from an end concat iterator!")::llvm::llvm_unreachable_internal("Attempted to get a pointer from an end concat iterator!"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h"
, 572)
;
573 }
574
575public:
576 /// Constructs an iterator from a squence of ranges.
577 ///
578 /// We need the full range to know how to switch between each of the
579 /// iterators.
580 template <typename... RangeTs>
581 explicit concat_iterator(RangeTs &&... Ranges)
582 : IterPairs({std::begin(Ranges), std::end(Ranges)}...) {}
583
584 using BaseT::operator++;
585
586 concat_iterator &operator++() {
587 increment(index_sequence_for<IterTs...>());
588 return *this;
589 }
590
591 ValueT &operator*() const { return get(index_sequence_for<IterTs...>()); }
592
593 bool operator==(const concat_iterator &RHS) const {
594 return IterPairs == RHS.IterPairs;
595 }
596};
597
598namespace detail {
599
600/// Helper to store a sequence of ranges being concatenated and access them.
601///
602/// This is designed to facilitate providing actual storage when temporaries
603/// are passed into the constructor such that we can use it as part of range
604/// based for loops.
605template <typename ValueT, typename... RangeTs> class concat_range {
606public:
607 using iterator =
608 concat_iterator<ValueT,
609 decltype(std::begin(std::declval<RangeTs &>()))...>;
610
611private:
612 std::tuple<RangeTs...> Ranges;
613
614 template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) {
615 return iterator(std::get<Ns>(Ranges)...);
616 }
617 template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) {
618 return iterator(make_range(std::end(std::get<Ns>(Ranges)),
619 std::end(std::get<Ns>(Ranges)))...);
620 }
621
622public:
623 concat_range(RangeTs &&... Ranges)
624 : Ranges(std::forward<RangeTs>(Ranges)...) {}
625
626 iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); }
627 iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); }
628};
629
630} // end namespace detail
631
632/// Concatenated range across two or more ranges.
633///
634/// The desired value type must be explicitly specified.
635template <typename ValueT, typename... RangeTs>
636detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
637 static_assert(sizeof...(RangeTs) > 1,
638 "Need more than one range to concatenate!");
639 return detail::concat_range<ValueT, RangeTs...>(
640 std::forward<RangeTs>(Ranges)...);
641}
642
643//===----------------------------------------------------------------------===//
644// Extra additions to <utility>
645//===----------------------------------------------------------------------===//
646
647/// \brief Function object to check whether the first component of a std::pair
648/// compares less than the first component of another std::pair.
649struct less_first {
650 template <typename T> bool operator()(const T &lhs, const T &rhs) const {
651 return lhs.first < rhs.first;
652 }
653};
654
655/// \brief Function object to check whether the second component of a std::pair
656/// compares less than the second component of another std::pair.
657struct less_second {
658 template <typename T> bool operator()(const T &lhs, const T &rhs) const {
659 return lhs.second < rhs.second;
660 }
661};
662
663// A subset of N3658. More stuff can be added as-needed.
664
665/// \brief Represents a compile-time sequence of integers.
666template <class T, T... I> struct integer_sequence {
667 using value_type = T;
668
669 static constexpr size_t size() { return sizeof...(I); }
670};
671
672/// \brief Alias for the common case of a sequence of size_ts.
673template <size_t... I>
674struct index_sequence : integer_sequence<std::size_t, I...> {};
675
676template <std::size_t N, std::size_t... I>
677struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
678template <std::size_t... I>
679struct build_index_impl<0, I...> : index_sequence<I...> {};
680
681/// \brief Creates a compile-time integer sequence for a parameter pack.
682template <class... Ts>
683struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
684
685/// Utility type to build an inheritance chain that makes it easy to rank
686/// overload candidates.
687template <int N> struct rank : rank<N - 1> {};
688template <> struct rank<0> {};
689
690/// \brief traits class for checking whether type T is one of any of the given
691/// types in the variadic list.
692template <typename T, typename... Ts> struct is_one_of {
693 static const bool value = false;
694};
695
696template <typename T, typename U, typename... Ts>
697struct is_one_of<T, U, Ts...> {
698 static const bool value =
699 std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
700};
701
702/// \brief traits class for checking whether type T is a base class for all
703/// the given types in the variadic list.
704template <typename T, typename... Ts> struct are_base_of {
705 static const bool value = true;
706};
707
708template <typename T, typename U, typename... Ts>
709struct are_base_of<T, U, Ts...> {
710 static const bool value =
711 std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
712};
713
714//===----------------------------------------------------------------------===//
715// Extra additions for arrays
716//===----------------------------------------------------------------------===//
717
718/// Find the length of an array.
719template <class T, std::size_t N>
720constexpr inline size_t array_lengthof(T (&)[N]) {
721 return N;
722}
723
724/// Adapt std::less<T> for array_pod_sort.
725template<typename T>
726inline int array_pod_sort_comparator(const void *P1, const void *P2) {
727 if (std::less<T>()(*reinterpret_cast<const T*>(P1),
728 *reinterpret_cast<const T*>(P2)))
729 return -1;
730 if (std::less<T>()(*reinterpret_cast<const T*>(P2),
731 *reinterpret_cast<const T*>(P1)))
732 return 1;
733 return 0;
734}
735
736/// get_array_pod_sort_comparator - This is an internal helper function used to
737/// get type deduction of T right.
738template<typename T>
739inline int (*get_array_pod_sort_comparator(const T &))
740 (const void*, const void*) {
741 return array_pod_sort_comparator<T>;
742}
743
744/// array_pod_sort - This sorts an array with the specified start and end
745/// extent. This is just like std::sort, except that it calls qsort instead of
746/// using an inlined template. qsort is slightly slower than std::sort, but
747/// most sorts are not performance critical in LLVM and std::sort has to be
748/// template instantiated for each type, leading to significant measured code
749/// bloat. This function should generally be used instead of std::sort where
750/// possible.
751///
752/// This function assumes that you have simple POD-like types that can be
753/// compared with std::less and can be moved with memcpy. If this isn't true,
754/// you should use std::sort.
755///
756/// NOTE: If qsort_r were portable, we could allow a custom comparator and
757/// default to std::less.
758template<class IteratorTy>
759inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
760 // Don't inefficiently call qsort with one element or trigger undefined
761 // behavior with an empty sequence.
762 auto NElts = End - Start;
763 if (NElts <= 1) return;
764 qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
765}
766
767template <class IteratorTy>
768inline void array_pod_sort(
769 IteratorTy Start, IteratorTy End,
770 int (*Compare)(
771 const typename std::iterator_traits<IteratorTy>::value_type *,
772 const typename std::iterator_traits<IteratorTy>::value_type *)) {
773 // Don't inefficiently call qsort with one element or trigger undefined
774 // behavior with an empty sequence.
775 auto NElts = End - Start;
776 if (NElts <= 1) return;
777 qsort(&*Start, NElts, sizeof(*Start),
778 reinterpret_cast<int (*)(const void *, const void *)>(Compare));
779}
780
781//===----------------------------------------------------------------------===//
782// Extra additions to <algorithm>
783//===----------------------------------------------------------------------===//
784
785/// For a container of pointers, deletes the pointers and then clears the
786/// container.
787template<typename Container>
788void DeleteContainerPointers(Container &C) {
789 for (auto V : C)
790 delete V;
791 C.clear();
792}
793
794/// In a container of pairs (usually a map) whose second element is a pointer,
795/// deletes the second elements and then clears the container.
796template<typename Container>
797void DeleteContainerSeconds(Container &C) {
798 for (auto &V : C)
799 delete V.second;
800 C.clear();
801}
802
803/// Provide wrappers to std::for_each which take ranges instead of having to
804/// pass begin/end explicitly.
805template <typename R, typename UnaryPredicate>
806UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
807 return std::for_each(adl_begin(Range), adl_end(Range), P);
808}
809
810/// Provide wrappers to std::all_of which take ranges instead of having to pass
811/// begin/end explicitly.
812template <typename R, typename UnaryPredicate>
813bool all_of(R &&Range, UnaryPredicate P) {
814 return std::all_of(adl_begin(Range), adl_end(Range), P);
815}
816
817/// Provide wrappers to std::any_of which take ranges instead of having to pass
818/// begin/end explicitly.
819template <typename R, typename UnaryPredicate>
820bool any_of(R &&Range, UnaryPredicate P) {
821 return std::any_of(adl_begin(Range), adl_end(Range), P);
822}
823
824/// Provide wrappers to std::none_of which take ranges instead of having to pass
825/// begin/end explicitly.
826template <typename R, typename UnaryPredicate>
827bool none_of(R &&Range, UnaryPredicate P) {
828 return std::none_of(adl_begin(Range), adl_end(Range), P);
829}
830
831/// Provide wrappers to std::find which take ranges instead of having to pass
832/// begin/end explicitly.
833template <typename R, typename T>
834auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
835 return std::find(adl_begin(Range), adl_end(Range), Val);
836}
837
838/// Provide wrappers to std::find_if which take ranges instead of having to pass
839/// begin/end explicitly.
840template <typename R, typename UnaryPredicate>
841auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
842 return std::find_if(adl_begin(Range), adl_end(Range), P);
843}
844
845template <typename R, typename UnaryPredicate>
846auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
847 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
848}
849
850/// Provide wrappers to std::remove_if which take ranges instead of having to
851/// pass begin/end explicitly.
852template <typename R, typename UnaryPredicate>
853auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
854 return std::remove_if(adl_begin(Range), adl_end(Range), P);
855}
856
857/// Provide wrappers to std::copy_if which take ranges instead of having to
858/// pass begin/end explicitly.
859template <typename R, typename OutputIt, typename UnaryPredicate>
860OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
861 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
862}
863
864/// Wrapper function around std::find to detect if an element exists
865/// in a container.
866template <typename R, typename E>
867bool is_contained(R &&Range, const E &Element) {
868 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
869}
870
871/// Wrapper function around std::count to count the number of times an element
872/// \p Element occurs in the given range \p Range.
873template <typename R, typename E>
874auto count(R &&Range, const E &Element) ->
875 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
876 return std::count(adl_begin(Range), adl_end(Range), Element);
877}
878
879/// Wrapper function around std::count_if to count the number of times an
880/// element satisfying a given predicate occurs in a range.
881template <typename R, typename UnaryPredicate>
882auto count_if(R &&Range, UnaryPredicate P) ->
883 typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
884 return std::count_if(adl_begin(Range), adl_end(Range), P);
885}
886
887/// Wrapper function around std::transform to apply a function to a range and
888/// store the result elsewhere.
889template <typename R, typename OutputIt, typename UnaryPredicate>
890OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
891 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
892}
893
894/// Provide wrappers to std::partition which take ranges instead of having to
895/// pass begin/end explicitly.
896template <typename R, typename UnaryPredicate>
897auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
898 return std::partition(adl_begin(Range), adl_end(Range), P);
899}
900
901/// Provide wrappers to std::lower_bound which take ranges instead of having to
902/// pass begin/end explicitly.
903template <typename R, typename ForwardIt>
904auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
905 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
906}
907
908/// \brief Given a range of type R, iterate the entire range and return a
909/// SmallVector with elements of the vector. This is useful, for example,
910/// when you want to iterate a range and then sort the results.
911template <unsigned Size, typename R>
912SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size>
913to_vector(R &&Range) {
914 return {adl_begin(Range), adl_end(Range)};
915}
916
917/// Provide a container algorithm similar to C++ Library Fundamentals v2's
918/// `erase_if` which is equivalent to:
919///
920/// C.erase(remove_if(C, pred), C.end());
921///
922/// This version works for any container with an erase method call accepting
923/// two iterators.
924template <typename Container, typename UnaryPredicate>
925void erase_if(Container &C, UnaryPredicate P) {
926 C.erase(remove_if(C, P), C.end());
927}
928
929//===----------------------------------------------------------------------===//
930// Extra additions to <memory>
931//===----------------------------------------------------------------------===//
932
933// Implement make_unique according to N3656.
934
935/// \brief Constructs a `new T()` with the given args and returns a
936/// `unique_ptr<T>` which owns the object.
937///
938/// Example:
939///
940/// auto p = make_unique<int>();
941/// auto p = make_unique<std::tuple<int, int>>(0, 1);
942template <class T, class... Args>
943typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
944make_unique(Args &&... args) {
945 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
66
Calling 'forward'
67
Returning from 'forward'
68
2nd function call argument is an uninitialized value
946}
947
948/// \brief Constructs a `new T[n]` with the given args and returns a
949/// `unique_ptr<T[]>` which owns the object.
950///
951/// \param n size of the new array.
952///
953/// Example:
954///
955/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
956template <class T>
957typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
958 std::unique_ptr<T>>::type
959make_unique(size_t n) {
960 return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
961}
962
963/// This function isn't used and is only here to provide better compile errors.
964template <class T, class... Args>
965typename std::enable_if<std::extent<T>::value != 0>::type
966make_unique(Args &&...) = delete;
967
968struct FreeDeleter {
969 void operator()(void* v) {
970 ::free(v);
971 }
972};
973
974template<typename First, typename Second>
975struct pair_hash {
976 size_t operator()(const std::pair<First, Second> &P) const {
977 return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
978 }
979};
980
981/// A functor like C++14's std::less<void> in its absence.
982struct less {
983 template <typename A, typename B> bool operator()(A &&a, B &&b) const {
984 return std::forward<A>(a) < std::forward<B>(b);
985 }
986};
987
988/// A functor like C++14's std::equal<void> in its absence.
989struct equal {
990 template <typename A, typename B> bool operator()(A &&a, B &&b) const {
991 return std::forward<A>(a) == std::forward<B>(b);
992 }
993};
994
995/// Binary functor that adapts to any other binary functor after dereferencing
996/// operands.
997template <typename T> struct deref {
998 T func;
999
1000 // Could be further improved to cope with non-derivable functors and
1001 // non-binary functors (should be a variadic template member function
1002 // operator()).
1003 template <typename A, typename B>
1004 auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
1005 assert(lhs)(static_cast <bool> (lhs) ? void (0) : __assert_fail ("lhs"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h"
, 1005, __extension__ __PRETTY_FUNCTION__))
;
1006 assert(rhs)(static_cast <bool> (rhs) ? void (0) : __assert_fail ("rhs"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h"
, 1006, __extension__ __PRETTY_FUNCTION__))
;
1007 return func(*lhs, *rhs);
1008 }
1009};
1010
1011namespace detail {
1012
1013template <typename R> class enumerator_iter;
1014
1015template <typename R> struct result_pair {
1016 friend class enumerator_iter<R>;
1017
1018 result_pair() = default;
1019 result_pair(std::size_t Index, IterOfRange<R> Iter)
1020 : Index(Index), Iter(Iter) {}
1021
1022 result_pair<R> &operator=(const result_pair<R> &Other) {
1023 Index = Other.Index;
1024 Iter = Other.Iter;
1025 return *this;
1026 }
1027
1028 std::size_t index() const { return Index; }
1029 const ValueOfRange<R> &value() const { return *Iter; }
1030 ValueOfRange<R> &value() { return *Iter; }
1031
1032private:
1033 std::size_t Index = std::numeric_limits<std::size_t>::max();
1034 IterOfRange<R> Iter;
1035};
1036
1037template <typename R>
1038class enumerator_iter
1039 : public iterator_facade_base<
1040 enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,
1041 typename std::iterator_traits<IterOfRange<R>>::difference_type,
1042 typename std::iterator_traits<IterOfRange<R>>::pointer,
1043 typename std::iterator_traits<IterOfRange<R>>::reference> {
1044 using result_type = result_pair<R>;
1045
1046public:
1047 explicit enumerator_iter(IterOfRange<R> EndIter)
1048 : Result(std::numeric_limits<size_t>::max(), EndIter) {}
1049
1050 enumerator_iter(std::size_t Index, IterOfRange<R> Iter)
1051 : Result(Index, Iter) {}
1052
1053 result_type &operator*() { return Result; }
1054 const result_type &operator*() const { return Result; }
1055
1056 enumerator_iter<R> &operator++() {
1057 assert(Result.Index != std::numeric_limits<size_t>::max())(static_cast <bool> (Result.Index != std::numeric_limits
<size_t>::max()) ? void (0) : __assert_fail ("Result.Index != std::numeric_limits<size_t>::max()"
, "/build/llvm-toolchain-snapshot-6.0~svn319013/include/llvm/ADT/STLExtras.h"
, 1057, __extension__ __PRETTY_FUNCTION__))
;
1058 ++Result.Iter;
1059 ++Result.Index;
1060 return *this;
1061 }
1062
1063 bool operator==(const enumerator_iter<R> &RHS) const {
1064 // Don't compare indices here, only iterators. It's possible for an end
1065 // iterator to have different indices depending on whether it was created
1066 // by calling std::end() versus incrementing a valid iterator.
1067 return Result.Iter == RHS.Result.Iter;
1068 }
1069
1070 enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {
1071 Result = Other.Result;
1072 return *this;
1073 }
1074
1075private:
1076 result_type Result;
1077};
1078
1079template <typename R> class enumerator {
1080public:
1081 explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
1082
1083 enumerator_iter<R> begin() {
1084 return enumerator_iter<R>(0, std::begin(TheRange));
1085 }
1086
1087 enumerator_iter<R> end() {
1088 return enumerator_iter<R>(std::end(TheRange));
1089 }
1090
1091private:
1092 R TheRange;
1093};
1094
1095} // end namespace detail
1096
1097/// Given an input range, returns a new range whose values are are pair (A,B)
1098/// such that A is the 0-based index of the item in the sequence, and B is
1099/// the value from the original sequence. Example:
1100///
1101/// std::vector<char> Items = {'A', 'B', 'C', 'D'};
1102/// for (auto X : enumerate(Items)) {
1103/// printf("Item %d - %c\n", X.index(), X.value());
1104/// }
1105///
1106/// Output:
1107/// Item 0 - A
1108/// Item 1 - B
1109/// Item 2 - C
1110/// Item 3 - D
1111///
1112template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {
1113 return detail::enumerator<R>(std::forward<R>(TheRange));
1114}
1115
1116namespace detail {
1117
1118template <typename F, typename Tuple, std::size_t... I>
1119auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>)
1120 -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) {
1121 return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
1122}
1123
1124} // end namespace detail
1125
1126/// Given an input tuple (a1, a2, ..., an), pass the arguments of the
1127/// tuple variadically to f as if by calling f(a1, a2, ..., an) and
1128/// return the result.
1129template <typename F, typename Tuple>
1130auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
1131 std::forward<F>(f), std::forward<Tuple>(t),
1132 build_index_impl<
1133 std::tuple_size<typename std::decay<Tuple>::type>::value>{})) {
1134 using Indices = build_index_impl<
1135 std::tuple_size<typename std::decay<Tuple>::type>::value>;
1136
1137 return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t),
1138 Indices{});
1139}
1140
1141} // end namespace llvm
1142
1143#endif // LLVM_ADT_STLEXTRAS_H