blob: b2b389ad339b4d5dca7d95a3c0b386ecb8300590 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- 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// Contains core ORC APIs.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H
15#define LLVM_EXECUTIONENGINE_ORC_LEGACY_H
16
17#include "llvm/ExecutionEngine/JITSymbol.h"
18#include "llvm/ExecutionEngine/Orc/Core.h"
19
20namespace llvm {
21namespace orc {
22
23class JITSymbolResolverAdapter : public JITSymbolResolver {
24public:
25 JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R);
26 Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) override;
27 Expected<LookupResult> lookup(const LookupSet &Symbols) override;
28
29private:
30 ExecutionSession &ES;
31 std::set<SymbolStringPtr> ResolvedStrings;
32 SymbolResolver &R;
33};
34
35/// @brief Use the given legacy-style FindSymbol function (i.e. a function that
36/// takes a const std::string& or StringRef and returns a JITSymbol) to
37/// find the flags for each symbol in Symbols and store their flags in
38/// SymbolFlags. If any JITSymbol returned by FindSymbol is in an error
39/// state the function returns immediately with that error, otherwise it
40/// returns the set of symbols not found.
41///
42/// Useful for implementing lookupFlags bodies that query legacy resolvers.
43template <typename FindSymbolFn>
44Expected<SymbolNameSet> lookupFlagsWithLegacyFn(SymbolFlagsMap &SymbolFlags,
45 const SymbolNameSet &Symbols,
46 FindSymbolFn FindSymbol) {
47 SymbolNameSet SymbolsNotFound;
48
49 for (auto &S : Symbols) {
50 if (JITSymbol Sym = FindSymbol(*S))
51 SymbolFlags[S] = Sym.getFlags();
52 else if (auto Err = Sym.takeError())
53 return std::move(Err);
54 else
55 SymbolsNotFound.insert(S);
56 }
57
58 return SymbolsNotFound;
59}
60
61/// @brief Use the given legacy-style FindSymbol function (i.e. a function that
62/// takes a const std::string& or StringRef and returns a JITSymbol) to
63/// find the address and flags for each symbol in Symbols and store the
64/// result in Query. If any JITSymbol returned by FindSymbol is in an
65/// error then Query.setFailed(...) is called with that error and the
66/// function returns immediately. On success, returns the set of symbols
67/// not found.
68///
69/// Useful for implementing lookup bodies that query legacy resolvers.
70template <typename FindSymbolFn>
71SymbolNameSet lookupWithLegacyFn(AsynchronousSymbolQuery &Query,
72 const SymbolNameSet &Symbols,
73 FindSymbolFn FindSymbol) {
74 SymbolNameSet SymbolsNotFound;
75
76 for (auto &S : Symbols) {
77 if (JITSymbol Sym = FindSymbol(*S)) {
78 if (auto Addr = Sym.getAddress()) {
79 Query.setDefinition(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
80 Query.notifySymbolFinalized();
81 } else {
82 Query.setFailed(Addr.takeError());
83 return SymbolNameSet();
84 }
85 } else if (auto Err = Sym.takeError()) {
86 Query.setFailed(std::move(Err));
87 return SymbolNameSet();
88 } else
89 SymbolsNotFound.insert(S);
90 }
91
92 return SymbolsNotFound;
93}
94
95/// @brief An ORC SymbolResolver implementation that uses a legacy
96/// findSymbol-like function to perform lookup;
97template <typename LegacyLookupFn>
98class LegacyLookupFnResolver final : public SymbolResolver {
99public:
100 using ErrorReporter = std::function<void(Error)>;
101
102 LegacyLookupFnResolver(LegacyLookupFn LegacyLookup, ErrorReporter ReportError)
103 : LegacyLookup(std::move(LegacyLookup)),
104 ReportError(std::move(ReportError)) {}
105
106 SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
107 const SymbolNameSet &Symbols) final {
108 if (auto RemainingSymbols =
109 lookupFlagsWithLegacyFn(Flags, Symbols, LegacyLookup))
110 return std::move(*RemainingSymbols);
111 else {
112 ReportError(RemainingSymbols.takeError());
113 return Symbols;
114 }
115 }
116
117 SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
118 SymbolNameSet Symbols) final {
119 return lookupWithLegacyFn(*Query, Symbols, LegacyLookup);
120 }
121
122private:
123 LegacyLookupFn LegacyLookup;
124 ErrorReporter ReportError;
125};
126
127template <typename LegacyLookupFn>
128std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>>
129createLegacyLookupResolver(LegacyLookupFn LegacyLookup,
130 std::function<void(Error)> ErrorReporter) {
131 return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>(
132 std::move(LegacyLookup), std::move(ErrorReporter));
133}
134
135} // End namespace orc
136} // End namespace llvm
137
138#endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H