std::map<SymbolStringPtr, RelativeLinkageStrength>;
using SourceWorkMap = std::map<SymbolSource *, SymbolNameSet>;
+ struct LookupFlagsResult {
+ SymbolFlagsMap SymbolFlags;
+ SymbolNameSet SymbolsNotFound;
+ };
+
struct LookupResult {
SourceWorkMap MaterializationWork;
SymbolNameSet UnresolvedSymbols;
/// @brief Finalize the given symbols.
void finalize(SymbolNameSet SymbolsToFinalize);
+ /// @brief Look up the flags for the given symbols.
+ ///
+ /// Returns the flags for the give symbols, together with the set of symbols
+ /// not found.
+ LookupFlagsResult lookupFlags(SymbolNameSet Symbols);
+
/// @brief Apply the given query to the given symbols in this VSO.
///
/// For symbols in this VSO that have already been materialized, their address
}
}
+VSO::LookupFlagsResult VSO::lookupFlags(SymbolNameSet Names) {
+ SymbolFlagsMap FlagsFound;
+
+ for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) {
+ auto Tmp = I++;
+ auto SymI = Symbols.find(*Tmp);
+
+ // If the symbol isn't in this dylib then just continue.
+ if (SymI == Symbols.end())
+ continue;
+
+ Names.erase(Tmp);
+
+ FlagsFound[SymI->first] =
+ JITSymbolFlags::stripTransientFlags(SymI->second.getFlags());
+ }
+
+ return {std::move(FlagsFound), std::move(Names)};
+}
+
VSO::LookupResult VSO::lookup(AsynchronousSymbolQuery &Query,
SymbolNameSet Names) {
SourceWorkMap MaterializationWork;
EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
}
+TEST(CoreAPIsTest, LookupFlagsTest) {
+
+ // Test that lookupFlags works on a predefined symbol, and does not trigger
+ // materialization of a lazy symbol.
+
+ SymbolStringPool SP;
+ auto Foo = SP.intern("foo");
+ auto Bar = SP.intern("bar");
+ auto Baz = SP.intern("baz");
+
+ VSO V;
+
+ auto Source = std::make_shared<SimpleSource>(
+ [](VSO &V, SymbolNameSet Symbols) -> Error {
+ llvm_unreachable("Symbol materialized on flags lookup");
+ },
+ [](VSO &V, SymbolStringPtr Name) -> Error {
+ llvm_unreachable("Symbol finalized on flags lookup");
+ });
+
+ JITSymbolFlags FooFlags = JITSymbolFlags::Exported;
+ JITSymbolFlags BarFlags = static_cast<JITSymbolFlags::FlagNames>(
+ JITSymbolFlags::Exported | JITSymbolFlags::Weak);
+
+ SymbolMap InitialDefs;
+ InitialDefs[Foo] = JITEvaluatedSymbol(0xdeadbeef, FooFlags);
+ cantFail(V.define(std::move(InitialDefs)));
+
+ SymbolFlagsMap InitialLazyDefs({{Bar, BarFlags}});
+ cantFail(V.defineLazy(InitialLazyDefs, *Source));
+
+ SymbolNameSet Names({Foo, Bar, Baz});
+
+ auto LFR = V.lookupFlags(Names);
+
+ EXPECT_EQ(LFR.SymbolsNotFound.size(), 1U) << "Expected one not-found symbol";
+ EXPECT_EQ(*LFR.SymbolsNotFound.begin(), Baz)
+ << "Expected Baz to be not-found";
+ EXPECT_EQ(LFR.SymbolFlags.size(), 2U)
+ << "Returned symbol flags contains unexpected results";
+ EXPECT_EQ(LFR.SymbolFlags.count(Foo), 1U)
+ << "Missing lookupFlags result for Foo";
+ EXPECT_EQ(LFR.SymbolFlags[Foo], FooFlags)
+ << "Incorrect flags returned for Foo";
+ EXPECT_EQ(LFR.SymbolFlags.count(Bar), 1U)
+ << "Missing lookupFlags result for Bar";
+ EXPECT_EQ(LFR.SymbolFlags[Bar], BarFlags)
+ << "Incorrect flags returned for Bar";
+}
+
TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) {
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;