@@ -104,38 +104,45 @@ class AutoloadLibraryGenerator : public llvm::orc::DefinitionGenerator {
104104 // so no need to check that again. Instead search for the library that
105105 // provides the symbol and create one MaterializationUnit per library to
106106 // actually load it if needed.
107- std::unordered_map<std::string, llvm::orc::SymbolNameVector> found;
107+ llvm::StringMap< llvm::orc::SymbolNameVector> found;
108108
109109 // TODO: Do we need to take gInterpreterMutex?
110110 // R__LOCKGUARD(gInterpreterMutex);
111111
112- for (auto &&KV : Symbols) {
113- llvm::orc::SymbolStringPtr name = KV.first ;
114-
115- const cling::DynamicLibraryManager &DLM = *fInterpreter ->getDynamicLibraryManager ();
116-
117- std::string libName = DLM.searchLibrariesForSymbol ((*name).str (),
118- /* searchSystem=*/ true );
119-
120- // libNew overrides memory management functions; must never autoload that.
121- assert (libName.find (" /libNew." ) == std::string::npos && " We must not autoload libNew!" );
122-
123- // libCling symbols are intentionally hidden from the process, and libCling must not be
124- // dlopened. Instead, symbols must be resolved by specifically querying the dynlib handle of
125- // libCling, which by definition is loaded - else we could not call this code. The handle
126- // is made available as argument to `CreateInterpreter`.
127- assert (libName.find (" /libCling." ) == std::string::npos && " Must not autoload libCling!" );
128-
129- if (!libName.empty ())
130- found[libName].push_back (name);
131- }
112+ SmallVector<StringRef> Syms;
113+ for (auto &KV : Symbols)
114+ Syms.push_back (*KV.first );
115+
116+ const cling::DynamicLibraryManager &DLM = *fInterpreter ->getDynamicLibraryManager ();
117+ DLM.searchLibrariesForSymbol (
118+ Syms,
119+ [&](llvm::orc::SymbolQuery &Q) {
120+ for (auto &&KV : Symbols) {
121+ auto ResolvedLibOrOpt = Q.getResolvedLib (*KV.first );
122+ if (!ResolvedLibOrOpt || ResolvedLibOrOpt->empty ())
123+ continue ;
124+ auto ResolvedLib = *ResolvedLibOrOpt;
125+ // libNew overrides memory management functions; must never autoload that.
126+ assert (ResolvedLib.find (" /libNew." ) == std::string::npos && " We must not autoload libNew!" );
127+
128+ // libCling symbols are intentionally hidden from the process, and libCling must not be
129+ // dlopened. Instead, symbols must be resolved by specifically querying the dynlib handle of
130+ // libCling, which by definition is loaded - else we could not call this code. The handle
131+ // is made available as argument to `CreateInterpreter`.
132+ assert (ResolvedLib.find (" /libCling." ) == std::string::npos && " Must not autoload libCling!" );
133+
134+ if (!ResolvedLib.empty ())
135+ found[ResolvedLib].push_back (KV.first );
136+ }
137+ },
138+ /* searchSystem=*/ true );
132139
133140 llvm::orc::SymbolMap loadedSymbols;
134141 for (const auto &KV : found) {
135142 // Try to load the library which should provide the symbol definition.
136143 // TODO: Should this interface with the DynamicLibraryManager directly?
137- if (TCling__LoadLibrary (KV.first . c_str ()) < 0 ) {
138- ROOT::TMetaUtils::Error (" AutoloadLibraryMU" , " Failed to load library %s" , KV.first . c_str ());
144+ if (TCling__LoadLibrary (KV.first (). data ()) < 0 ) {
145+ ROOT::TMetaUtils::Error (" AutoloadLibraryMU" , " Failed to load library %s" , KV.first (). data ());
139146 }
140147
141148 for (const auto &symbol : KV.second ) {
0 commit comments