Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Library autoloader #308

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a4242e9
Library autoloader
alexander-penev Jul 10, 2024
aae272b
Fix some clang-tidy suggested issues
alexander-penev Jul 11, 2024
1cbc857
Fix some clang-tidy suggested issues 2
alexander-penev Jul 11, 2024
ae4b0ab
Fix
alexander-penev Jul 28, 2024
f55485a
Update CppInterOp.cpp
alexander-penev Jul 30, 2024
4af7185
Fix demangle
alexander-penev Jul 31, 2024
38066ab
Apply suggestions from code review
alexander-penev Jul 31, 2024
7240434
Update DynamicLibraryManagerSymbol.cpp
alexander-penev Jul 31, 2024
f815bac
Update DynamicLibraryManagerSymbol.cpp
alexander-penev Jul 31, 2024
a8f441d
Update DynamicLibraryManagerTest.cpp
alexander-penev Jul 31, 2024
b5eb022
Update CMakeLists.txt
alexander-penev Jul 31, 2024
80c76c1
Fix demangle build
alexander-penev Jul 31, 2024
1f5111e
Cleanup
alexander-penev Sep 6, 2024
2ab35af
Restore sAutoSG in CppInterOp.cpp
alexander-penev Dec 18, 2024
b307433
Fix null -> nullptr in CppInterOp.cpp
alexander-penev Dec 18, 2024
a369962
Fix ExecutorSymbolDef compat in llvm<17
alexander-penev Jan 11, 2025
ea75cb4
Fix compat in llvm<17
alexander-penev Jan 11, 2025
90e9c85
Fix compat in llvm<17 (2)
alexander-penev Jan 11, 2025
3e7e87e
Fix compat in llvm<17 (3)
alexander-penev Jan 11, 2025
bbcb9f0
Fix compat in llvm<17 (4)
alexander-penev Jan 11, 2025
c280c70
Fix compat in llvm<17 (5)
alexander-penev Jan 12, 2025
c4c646f
Fix compat in llvm<17 (6)
alexander-penev Jan 12, 2025
6ef47d7
Fix
alexander-penev Jan 31, 2025
2cb8352
Fix1
alexander-penev Jan 31, 2025
03a8e0b
Fix3
alexander-penev Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/clang/Interpreter/CppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,14 @@ namespace Cpp {
unsigned complete_line = 1U,
unsigned complete_column = 1U);

/// Set libraries autoload.
///\param[in] autoload - true to enable library autoload.
CPPINTEROP_API void SetLibrariesAutoload(bool autoload = true);

/// Get libraries autoload status.
///\returns LibraryAutoLoad state (true = libraries autoload is on).
CPPINTEROP_API bool GetLibrariesAutoload();

} // end namespace Cpp

#endif // CPPINTEROP_CPPINTEROP_H
205 changes: 203 additions & 2 deletions lib/Interpreter/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Debug.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: #includes are not sorted properly [llvm-include-order]

Suggested change
#include "llvm/Support/Debug.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"

#include "llvm/Support/raw_os_ostream.h"

#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>

// Stream redirect.
#ifdef _WIN32
Expand All @@ -64,6 +67,10 @@ namespace Cpp {
using namespace llvm;
using namespace std;

// Last assigned Autoload SearchGenerator
// TODO: Test fot thread safe.
class AutoLoadLibrarySearchGenerator;
static AutoLoadLibrarySearchGenerator *sAutoSG = nullptr;
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'sAutoSG' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

  static AutoLoadLibrarySearchGenerator *sAutoSG = nullptr;
                                         ^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'sAutoSG' provides global access to a non-const object; consider making the pointed-to data 'const' [cppcoreguidelines-avoid-non-const-global-variables]

  static AutoLoadLibrarySearchGenerator *sAutoSG = nullptr;
                                         ^

// Flag to indicate ownership when an external interpreter instance is used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'null' [clang-diagnostic-error]

  static AutoLoadLibrarySearchGenerator *sAutoSG = null;
                                                   ^

static bool OwningSInterpreter = true;
static compat::Interpreter* sInterpreter = nullptr;
Expand Down Expand Up @@ -1137,7 +1144,6 @@ namespace Cpp {
llvm::consumeError(std::move(Err)); // nullptr if missing
else
return llvm::jitTargetAddressToPointer<void*>(*FDAorErr);

return nullptr;
}

Expand Down Expand Up @@ -2728,7 +2734,7 @@ namespace Cpp {
std::string BinaryPath = GetExecutablePath(/*Argv0=*/nullptr, MainAddr);

// build/tools/clang/unittests/Interpreter/Executable -> build/
StringRef Dir = sys::path::parent_path(BinaryPath);
Dir = sys::path::parent_path(BinaryPath);

Dir = sys::path::parent_path(Dir);
Dir = sys::path::parent_path(Dir);
Expand Down Expand Up @@ -3546,4 +3552,199 @@ namespace Cpp {
complete_column);
}

#define DEBUG_TYPE "autoload"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays]

      std::unique_ptr<char[]> content(new char[bufsize + 1]);
                      ^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::unique_ptr" is directly included [misc-include-cleaner]

      std::unique_ptr<char[]> content(new char[bufsize + 1]);
           ^


static inline std::string DemangleNameForDlsym(const std::string& name) {
std::string nameForDlsym = name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "SEEK_SET" is directly included [misc-include-cleaner]

      if (fseek(m_TempFile.get(), 0L, SEEK_SET) != 0)
                                      ^


static bool is_demangle_active = false;
static bool demangle = false;
if (!is_demangle_active) {
auto& I = getInterp();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fread" is directly included [misc-include-cleaner]

          fread(content.get(), sizeof(char), bufsize, m_TempFile.get());
          ^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: The 1st argument to 'fread' is a buffer with size 0 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 1) times the 3rd argument (which is 18446744073709551615) [clang-analyzer-unix.StdCLibraryFunctions]

          fread(content.get(), sizeof(char), bufsize, m_TempFile.get());
          ^
Additional context

lib/Interpreter/CppInterOp.cpp:3475: Calling 'StreamCaptureInfo::GetCapturedString'

    std::string result = SCI.GetCapturedString();
                         ^

lib/Interpreter/CppInterOp.cpp:3430: Assuming the condition is false

      if (dup2(m_DupFD, m_FD) < 0)
          ^

lib/Interpreter/CppInterOp.cpp:3430: Taking false branch

      if (dup2(m_DupFD, m_FD) < 0)
      ^

lib/Interpreter/CppInterOp.cpp:3433: Assuming the condition is false

      if (fseek(m_TempFile.get(), 0L, SEEK_END) != 0)
          ^

lib/Interpreter/CppInterOp.cpp:3433: Taking false branch

      if (fseek(m_TempFile.get(), 0L, SEEK_END) != 0)
      ^

lib/Interpreter/CppInterOp.cpp:3437: 'bufsize' initialized here

      long bufsize = ftell(m_TempFile.get());
      ^

lib/Interpreter/CppInterOp.cpp:3438: Assuming the condition is true

      if (bufsize == -1)
          ^

lib/Interpreter/CppInterOp.cpp:3438: Taking true branch

      if (bufsize == -1)
      ^

lib/Interpreter/CppInterOp.cpp:3442: Storing uninitialized value

      std::unique_ptr<char[]> content(new char[bufsize + 1]);
                                      ^

lib/Interpreter/CppInterOp.cpp:3442: Passing value via 1st parameter '__p'

      std::unique_ptr<char[]> content(new char[bufsize + 1]);
                                      ^

lib/Interpreter/CppInterOp.cpp:3442: Calling constructor for 'unique_ptr<char[], std::default_delete<char[]>>'

      std::unique_ptr<char[]> content(new char[bufsize + 1]);
                              ^

/usr/include/c++/13/bits/unique_ptr.h:603: Calling constructor for '__uniq_ptr_data<char, std::default_delete<char[]>, true, true>'

	: _M_t(__p)
   ^

/usr/include/c++/13/bits/unique_ptr.h:603: Passing '' via 1st parameter '__p'

	: _M_t(__p)
        ^

/usr/include/c++/13/bits/unique_ptr.h:603: Calling constructor for '__uniq_ptr_impl<char, std::default_delete<char[]>>'

	: _M_t(__p)
   ^

/usr/include/c++/13/bits/unique_ptr.h:175: Calling '__uniq_ptr_impl::_M_ptr'

      __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
                                              ^

/usr/include/c++/13/bits/unique_ptr.h:196: Calling 'get<0UL, char *, std::default_delete<char[]>>'

      pointer&   _M_ptr() noexcept { return std::get<0>(_M_t); }
                                            ^

/usr/include/c++/13/tuple:1803: Calling '__get_helper<0UL, char *, std::default_delete<char[]>>'

    { return std::__get_helper<__i>(__t); }
             ^

/usr/include/c++/13/tuple:1787: Calling '_Tuple_impl::_M_head'

    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
             ^

/usr/include/c++/13/tuple:268: Calling '_Head_base::_M_head'

      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
                                                  ^

/usr/include/c++/13/tuple:268: Returning from '_Head_base::_M_head'

      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
                                                  ^

/usr/include/c++/13/tuple:1787: Returning from '_Tuple_impl::_M_head'

    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
             ^

/usr/include/c++/13/tuple:1803: Returning from '__get_helper<0UL, char *, std::default_delete<char[]>>'

    { return std::__get_helper<__i>(__t); }
             ^

/usr/include/c++/13/bits/unique_ptr.h:196: Returning from 'get<0UL, char *, std::default_delete<char[]>>'

      pointer&   _M_ptr() noexcept { return std::get<0>(_M_t); }
                                            ^

/usr/include/c++/13/bits/unique_ptr.h:175: Returning from '__uniq_ptr_impl::_M_ptr'

      __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
                                              ^

/usr/include/c++/13/bits/unique_ptr.h:175: The value of '__p' is assigned to 'content._M_t._M_t._M_head_impl'

      __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
                                              ^

/usr/include/c++/13/bits/unique_ptr.h:603: Returning from constructor for '__uniq_ptr_impl<char, std::default_delete<char[]>>'

	: _M_t(__p)
   ^

/usr/include/c++/13/bits/unique_ptr.h:603: Returning from constructor for '__uniq_ptr_data<char, std::default_delete<char[]>, true, true>'

	: _M_t(__p)
   ^

lib/Interpreter/CppInterOp.cpp:3442: Returning from constructor for 'unique_ptr<char[], std::default_delete<char[]>>'

      std::unique_ptr<char[]> content(new char[bufsize + 1]);
                              ^

lib/Interpreter/CppInterOp.cpp:3445: Assuming the condition is false

      if (fseek(m_TempFile.get(), 0L, SEEK_SET) != 0)
          ^

lib/Interpreter/CppInterOp.cpp:3445: Taking false branch

      if (fseek(m_TempFile.get(), 0L, SEEK_SET) != 0)
      ^

lib/Interpreter/CppInterOp.cpp:3450: The 1st argument to 'fread' is a buffer with size 0 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 1) times the 3rd argument (which is 18446744073709551615)

          fread(content.get(), sizeof(char), bufsize, m_TempFile.get());
          ^

llvm::orc::LLJIT& EE = *compat::getExecutionEngine(I);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "ferror" is directly included [misc-include-cleaner]

      if (ferror(m_TempFile.get()) != 0)
          ^

auto t = EE.getTargetTriple();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fputs" is directly included [misc-include-cleaner]

        fputs("Error reading file", stderr);
        ^

demangle = t.isOSDarwin() || t.isOSWindows();
is_demangle_active = true;
}

// The JIT gives us a mangled name which has an additional leading underscore
// on macOS and Windows, for instance __ZN8TRandom34RndmEv. However, dlsym
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
// requires us to remove it.
// FIXME: get this information from the DataLayout via getGlobalPrefix()!
if (demangle && nameForDlsym[0] == '_')
nameForDlsym.erase(0, 1);
return nameForDlsym;
}

class AutoLoadLibrarySearchGenerator : public llvm::orc::DefinitionGenerator {
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
bool Enabled = false;
public:
bool isEnabled() {
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: method 'isEnabled' can be made const [readability-make-member-function-const]

Suggested change
bool isEnabled() {
bool isEnabled() const {

return Enabled;
}

void setEnabled(bool enabled) {
Enabled = enabled;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: method 'isEnabled' can be made const [readability-make-member-function-const]

Suggested change
Enabled = enabled;
bool isEnabled() const {

}
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved

// Lazy materialization unit class helper
class AutoloadLibraryMU : public llvm::orc::MaterializationUnit {
std::string lib;
std::string fLibrary;
llvm::orc::SymbolNameVector fSymbols;
public:
AutoloadLibraryMU(const std::string &Library, const llvm::orc::SymbolNameVector &Symbols)
: MaterializationUnit({getSymbolFlagsMap(Symbols), nullptr}), fLibrary(Library), fSymbols(Symbols) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: pass by value and use std::move [modernize-pass-by-value]

Suggested change
: MaterializationUnit({getSymbolFlagsMap(Symbols), nullptr}), fLibrary(Library), fSymbols(Symbols) {}
AutoloadLibraryMU(std::string Library, const llvm::orc::SymbolNameVector &Symbols)
: MaterializationUnit({getSymbolFlagsMap(Symbols), nullptr}), fLibrary(std::move(Library)), fSymbols(Symbols) {}


StringRef getName() const override {
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'getName' should be marked [[nodiscard]] [modernize-use-nodiscard]

Suggested change
StringRef getName() const override {
[[nodiscard]] StringRef getName() const override {

return "<Symbols from Autoloaded Library>";
}

void materialize(std::unique_ptr<llvm::orc::MaterializationResponsibility> R) override {
//if (!sAutoSG || !sAutoSG->isEnabled()) {
// R->failMaterialization();
// return;
//}

LLVM_DEBUG(dbgs() << "Materialize " << lib << " syms=" << fSymbols);

alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
auto& I = getInterp();
auto *DLM = I.getDynamicLibraryManager();

llvm::orc::SymbolMap loadedSymbols;
llvm::orc::SymbolNameSet failedSymbols;
bool loadedLibrary = false;

alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
for (const auto &symbol : fSymbols) {
std::string symbolStr = (*symbol).str();
std::string nameForDlsym = DemangleNameForDlsym(symbolStr);

// Check if the symbol is available without loading the library.
void *addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(nameForDlsym);

if (!addr && !loadedLibrary) {
// Try to load the library which should provide the symbol definition.
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
if (DLM->loadLibrary(lib, false) != DynamicLibraryManager::LoadLibResult::kLoadLibSuccess) {
LLVM_DEBUG(dbgs() << "MU: Failed to load library " << lib);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: method 'isEnabled' can be made const [readability-make-member-function-const]

Suggested change
LLVM_DEBUG(dbgs() << "MU: Failed to load library " << lib);
bool isEnabled() const {

string err = "MU: Failed to load library! " + lib;
perror(err.c_str());
} else {
LLVM_DEBUG(dbgs() << "MU: Autoload library " << lib);
}
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved

// Only try loading the library once.
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
loadedLibrary = true;

addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(nameForDlsym);
}

if (addr) {
loadedSymbols[symbol] =
#if CLANG_VERSION_MAJOR < 17
llvm::JITEvaluatedSymbol::fromPointer(addr, JITSymbolFlags::Exported);
#else
llvm::orc::ExecutorSymbolDef(llvm::orc::ExecutorAddr::fromPtr(addr), JITSymbolFlags::Exported);
#endif // CLANG_VERSION_MAJOR < 17
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'getName' should be marked [[nodiscard]] [modernize-use-nodiscard]

Suggested change
} else {
[[nodiscard]] StringRef getName() const override {

// Collect all failing symbols, delegate their responsibility and then
// fail their materialization. R->defineNonExistent() sounds like it
// should do that, but it's not implemented?!
failedSymbols.insert(symbol);
}
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
}

if (!failedSymbols.empty()) {
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
auto failingMR = R->delegate(failedSymbols);
if (failingMR) {
(*failingMR)->failMaterialization();
}
}

if (!loadedSymbols.empty()) {
llvm::cantFail(R->notifyResolved(loadedSymbols));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "llvm::cantFail" is directly included [misc-include-cleaner]

          llvm::cantFail(R->notifyResolved(loadedSymbols));
                ^


#if CLANG_VERSION_MAJOR < 18
llvm::orc::SymbolDependenceGroup DepGroup;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no type named 'SymbolDependenceGroup' in namespace 'llvm::orc'; did you mean 'SymbolDependenceMap'? [clang-diagnostic-error]

Suggested change
llvm::orc::SymbolDependenceGroup DepGroup;
llvm::orc::SymbolDependenceMap DepGroup;
Additional context

llvm/include/llvm/ExecutionEngine/Orc/Core.h:125: 'SymbolDependenceMap' declared here

using SymbolDependenceMap = DenseMap<JITDylib *, SymbolNameSet>;
      ^

llvm::cantFail(R->notifyEmitted({DepGroup}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: too many arguments to function call, expected 0, have 1 [clang-diagnostic-error]

          llvm::cantFail(R->notifyEmitted({DepGroup}));
                                          ^
Additional context

llvm/include/llvm/ExecutionEngine/Orc/Core.h:1932: 'notifyEmitted' declared here

inline Error MaterializationResponsibility::notifyEmitted() {
                                            ^

#else
llvm::cantFail(R->notifyEmitted());
#endif
}
}

void discard(const llvm::orc::JITDylib &JD, const llvm::orc::SymbolStringPtr &Name) override {}

private:
static llvm::orc::SymbolFlagsMap getSymbolFlagsMap(const llvm::orc::SymbolNameVector &Symbols) {
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
llvm::orc::SymbolFlagsMap map;
for (const auto &symbolName : Symbols)
map[symbolName] = llvm::JITSymbolFlags::Exported;
return map;
}
};

llvm::Error tryToGenerate(llvm::orc::LookupState &LS, llvm::orc::LookupKind K, llvm::orc::JITDylib &JD,
llvm::orc::JITDylibLookupFlags JDLookupFlags, const llvm::orc::SymbolLookupSet &Symbols) override {
if (!isEnabled())
return llvm::Error::success();
LLVM_DEBUG(dbgs() << "tryToGenerate");

auto& I = getInterp();
auto *DLM = I.getDynamicLibraryManager();

std::unordered_map<std::string, llvm::orc::SymbolNameVector> found;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::unordered_map" is directly included [misc-include-cleaner]

lib/Interpreter/CppInterOp.cpp:26:

- #if CLANG_VERSION_MAJOR >= 19
+ #include <unordered_map>
+ #if CLANG_VERSION_MAJOR >= 19

llvm::orc::SymbolMap NewSymbols;
for (const auto &KV : Symbols) {
const auto &Name = KV.first;
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
if ((*Name).empty())
continue;

auto lib = DLM->searchLibrariesForSymbol(*Name, /*searchSystem=*/true); // false?
if (lib.empty())
continue;

found[lib].push_back(Name);

// Workaround: This getAddressOfGlobal call make first symbol search
// to work, immediatelly after library auto load. This approach do not
// use MU
//DLM->loadLibrary(lib, true);
//I.getAddressOfGlobal(*Name);
}

for (auto &&KV : found) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "llvm::cantFail" is directly included [misc-include-cleaner]

          llvm::cantFail(R->notifyResolved(loadedSymbols));
                ^

auto MU = std::make_unique<AutoloadLibraryMU>(KV.first, std::move(KV.second));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::make_unique" is directly included [misc-include-cleaner]

	auto MU = std::make_unique<AutoloadLibraryMU>(KV.first, std::move(KV.second));
                ^

if (auto Err = JD.define(MU))
return Err;
}

return llvm::Error::success();
}

};

void SetLibrariesAutoload(bool autoload /* = true */) {
auto& I = getInterp();
llvm::orc::LLJIT& EE = *compat::getExecutionEngine(I);
#if CLANG_VERSION_MAJOR < 17
llvm::orc::JITDylib& DyLib = EE.getMainJITDylib();
#else
llvm::orc::JITDylib& DyLib = *EE.getProcessSymbolsJITDylib().get();
#endif // CLANG_VERSION_MAJOR
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved

if (!sAutoSG) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'sAutoSG' [clang-diagnostic-error]

    if (!sAutoSG) {
         ^

sAutoSG = &DyLib.addGenerator(std::make_unique<AutoLoadLibrarySearchGenerator>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'sAutoSG' [clang-diagnostic-error]

      sAutoSG = &DyLib.addGenerator(std::make_unique<AutoLoadLibrarySearchGenerator>());
      ^

}
sAutoSG->setEnabled(autoload);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'sAutoSG' [clang-diagnostic-error]

    sAutoSG->setEnabled(autoload);
    ^


LLVM_DEBUG(dbgs() << "Autoload=" << (sAutoSG->isEnabled() ? "ON" : "OFF"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::unordered_map" is directly included [misc-include-cleaner]

lib/Interpreter/CppInterOp.cpp:26:

- #if CLANG_VERSION_MAJOR >= 19
+ #include <unordered_map>
+ #if CLANG_VERSION_MAJOR >= 19

}
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved

alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
bool GetLibrariesAutoload() {
LLVM_DEBUG(dbgs() << "Autoload is " << (sAutoSG && sAutoSG->isEnabled() ? "ON" : "OFF"));
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved
return sAutoSG && sAutoSG->isEnabled();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'sAutoSG' [clang-diagnostic-error]

    return sAutoSG && sAutoSG->isEnabled();
                      ^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'sAutoSG' [clang-diagnostic-error]

    return sAutoSG && sAutoSG->isEnabled();
           ^

}

#undef DEBUG_TYPE

} // end namespace Cpp
11 changes: 5 additions & 6 deletions lib/Interpreter/DynamicLibraryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ namespace Cpp {
// get canonical path name and check if already loaded
const std::string Path = platform::NormalizePath(foundDyLib);
if (Path.empty()) {
LLVM_DEBUG(dbgs() << "cling::DynamicLibraryManager::lookupLibMaybeAddExt(): "
LLVM_DEBUG(dbgs() << "DynamicLibraryManager::lookupLibMaybeAddExt(): "
<< "error getting real (canonical) path of library " << foundDyLib << '\n');
return foundDyLib;
}
Expand Down Expand Up @@ -392,10 +392,9 @@ namespace Cpp {
return;

DyLibHandle dyLibHandle = nullptr;
for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
I != E; ++I) {
if (I->second == canonicalLoadedLib) {
dyLibHandle = I->first;
for (const auto& dylib : m_DyLibs) {
if (dylib.second == canonicalLoadedLib) {
dyLibHandle = dylib.first;
break;
}
}
Expand All @@ -405,7 +404,7 @@ namespace Cpp {
std::string errMsg;
platform::DLClose(dyLibHandle, &errMsg);
if (!errMsg.empty()) {
LLVM_DEBUG(dbgs() << "cling::DynamicLibraryManager::unloadLibrary(): "
LLVM_DEBUG(dbgs() << "DynamicLibraryManager::unloadLibrary(): "
<< errMsg << '\n');
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Interpreter/DynamicLibraryManagerSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@ namespace Cpp {

void DynamicLibraryManager::initializeDyld(
std::function<bool(llvm::StringRef)> shouldPermanentlyIgnore) {
//assert(!m_Dyld && "Already initialized!");
assert(!m_Dyld && "Already initialized!");
if (m_Dyld)
delete m_Dyld;

Expand Down
21 changes: 19 additions & 2 deletions unittests/CppInterOp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ target_link_libraries(CppInterOpTests
)

set_output_directory(CppInterOpTests
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/CppInterOpTests/unittests/bin/$<CONFIG>/
LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/CppInterOpTests/unittests/bin/$<CONFIG>/
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin/$<CONFIG>/
LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin/$<CONFIG>/
)

if(NOT WIN32)
Expand All @@ -43,10 +43,27 @@ target_link_libraries(DynamicLibraryManagerTests
clangCppInterOp
)

set_source_files_properties(DynamicLibraryManagerTest.cpp PROPERTIES COMPILE_DEFINITIONS
"LLVM_BINARY_DIR=\"${LLVM_BINARY_DIR}\""
)
set_source_files_properties(DynamicLibraryManagerTest.cpp PROPERTIES COMPILE_DEFINITIONS
"CPPINTEROP_VERSION=\"${CPPINTEROP_VERSION}\""
)
alexander-penev marked this conversation as resolved.
Show resolved Hide resolved

set_output_directory(DynamicLibraryManagerTests BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/TestSharedLib/unittests/bin/$<CONFIG>/)

set_output_directory(DynamicLibraryManagerTests
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/TestSharedLib/unittests/bin/$<CONFIG>/
LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/TestSharedLib/unittests/bin/$<CONFIG>/
)
add_dependencies(DynamicLibraryManagerTests TestSharedLib)
#export_executable_symbols_for_plugins(TestSharedLib)
add_subdirectory(TestSharedLib)

add_dependencies(DynamicLibraryManagerTests TestSharedLib1)
#export_executable_symbols_for_plugins(TestSharedLib1)
add_subdirectory(TestSharedLib1)

add_dependencies(DynamicLibraryManagerTests TestSharedLib2)
#export_executable_symbols_for_plugins(TestSharedLib2)
add_subdirectory(TestSharedLib2)
Loading
Loading