Remove the junk I accidentally committed.
This commit is contained in:
committed by
sftnight
parent
2c16f39465
commit
f5250400d4
101
#Makefile#
101
#Makefile#
@ -1,101 +0,0 @@
|
|||||||
##===- Makefile --------------------------------------------*- Makefile -*-===##
|
|
||||||
#
|
|
||||||
# The Cling Interpreter
|
|
||||||
#
|
|
||||||
# This file is dual-licensed: you can choose to license it under the University
|
|
||||||
# of Illinois Open Source License or the GNU Lesser General Public License. See
|
|
||||||
# LICENSE.TXT for details.
|
|
||||||
#
|
|
||||||
##===----------------------------------------------------------------------===##
|
|
||||||
|
|
||||||
# If CLING_LEVEL is not set, then we are the top-level Makefile. Otherwise, we
|
|
||||||
# are being included from a subdirectory makefile.
|
|
||||||
|
|
||||||
ifndef CLING_LEVEL
|
|
||||||
|
|
||||||
IS_TOP_LEVEL := 1
|
|
||||||
CLING_LEVEL := .
|
|
||||||
DIRS := include lib tools docs
|
|
||||||
|
|
||||||
PARALLEL_DIRS :=
|
|
||||||
|
|
||||||
ifeq ($(BUILD_EXAMPLES),1)
|
|
||||||
PARALLEL_DIRS += examples
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(MAKECMDGOALS),libs-only)
|
|
||||||
DIRS := $(filter-out tools docs, $(DIRS))
|
|
||||||
OPTIONAL_DIRS :=
|
|
||||||
endif
|
|
||||||
|
|
||||||
###
|
|
||||||
# Common Makefile code, shared by all Cling Makefiles.
|
|
||||||
|
|
||||||
# Set LLVM source root level.
|
|
||||||
LEVEL := $(CLING_LEVEL)/../..
|
|
||||||
|
|
||||||
# Include LLVM common makefile.
|
|
||||||
include $(LEVEL)/Makefile.common
|
|
||||||
|
|
||||||
ifneq ($(ENABLE_DOCS),1)
|
|
||||||
DIRS := $(filter-out docs, $(DIRS))
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Set common Cling build flags.
|
|
||||||
CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLING_LEVEL)/include -I$(PROJ_OBJ_DIR)/$(CLING_LEVEL)/include
|
|
||||||
ifdef CLING_VENDOR
|
|
||||||
CPP.Flags += -DCLING_VENDOR='"$(CLING_VENDOR) "'
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't
|
|
||||||
# work with it enabled with GCC), Cling/llvm-gc don't support it yet, and newer
|
|
||||||
# GCC's have false positive warnings with it on Linux (which prove a pain to
|
|
||||||
# fix). For example:
|
|
||||||
# http://gcc.gnu.org/PR41874
|
|
||||||
# http://gcc.gnu.org/PR41838
|
|
||||||
#
|
|
||||||
# We can revisit this when LLVM/Cling support it.
|
|
||||||
CXX.Flags += -fno-strict-aliasing
|
|
||||||
|
|
||||||
# Determine cling's version:
|
|
||||||
CLING_VERSION=$(shell cat "VERSION")
|
|
||||||
CPP.Flags += -DCLING_VERSION='"$(CLING_VERSION) "'
|
|
||||||
|
|
||||||
###
|
|
||||||
# Cling Top Level specific stuff.
|
|
||||||
|
|
||||||
ifeq ($(IS_TOP_LEVEL),1)
|
|
||||||
|
|
||||||
ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
|
|
||||||
$(RecursiveTargets)::
|
|
||||||
$(Verb) if [ ! -f test/Makefile ]; then \
|
|
||||||
$(MKDIR) test; \
|
|
||||||
$(CP) $(PROJ_SRC_DIR)/test/Makefile test/Makefile; \
|
|
||||||
fi
|
|
||||||
endif
|
|
||||||
|
|
||||||
test::
|
|
||||||
@ $(MAKE) -C test
|
|
||||||
|
|
||||||
report::
|
|
||||||
@ $(MAKE) -C test report
|
|
||||||
|
|
||||||
clean::
|
|
||||||
@ $(MAKE) -C test clean
|
|
||||||
|
|
||||||
libs-only: all
|
|
||||||
|
|
||||||
tags::
|
|
||||||
$(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \
|
|
||||||
grep -v /lib/Headers | grep -v /test/`
|
|
||||||
|
|
||||||
cscope.files:
|
|
||||||
find tools lib include -name '*.cpp' \
|
|
||||||
-or -name '*.def' \
|
|
||||||
-or -name '*.td' \
|
|
||||||
-or -name '*.h' > cscope.files
|
|
||||||
|
|
||||||
.PHONY: test report clean cscope.files
|
|
||||||
|
|
||||||
endif
|
|
@ -1,17 +0,0 @@
|
|||||||
//--------------------------------------------------------------------*- C++ -*-
|
|
||||||
// CLING - the C++ LLVM-based InterpreterG :)
|
|
||||||
// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
|
|
||||||
//
|
|
||||||
// This file is dual-licensed: you can choose to license it under the University
|
|
||||||
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
|
||||||
// LICENSE.TXT for details.
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef CLING_VALUEPRINTERC_H
|
|
||||||
#define CLING_VALUEPRINTERC_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
#endif
|
|
||||||
void cling_PrintValue(void* /*cling::Value**/ V);
|
|
||||||
|
|
||||||
#endif // CLING_VALUEPRINTERC_H
|
|
@ -1,379 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// CLING - the C++ LLVM-based InterpreterG :)
|
|
||||||
// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
|
|
||||||
//
|
|
||||||
// This file is dual-licensed: you can choose to license it under the University
|
|
||||||
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
|
||||||
// LICENSE.TXT for details.
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "cling/Interpreter/DynamicLibraryManager.h"
|
|
||||||
#include "cling/Interpreter/Interpreter.h"
|
|
||||||
#include "cling/Interpreter/InterpreterCallbacks.h"
|
|
||||||
#include "cling/Interpreter/InvocationOptions.h"
|
|
||||||
|
|
||||||
#include "llvm/Support/DynamicLibrary.h"
|
|
||||||
#include "llvm/Support/FileSystem.h"
|
|
||||||
#include "llvm/Support/Path.h"
|
|
||||||
#include "llvm/Support/raw_ostream.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#else
|
|
||||||
#include <limits.h> /* PATH_MAX */
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
#if defined(LLVM_ON_UNIX)
|
|
||||||
static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
|
|
||||||
char* env_var = getenv("LD_LIBRARY_PATH");
|
|
||||||
#if __APPLE__
|
|
||||||
if (!env_var)
|
|
||||||
env_var = getenv("DYLD_LIBRARY_PATH");
|
|
||||||
if (!env_var)
|
|
||||||
env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
|
|
||||||
#endif
|
|
||||||
if (env_var != 0) {
|
|
||||||
static const char PathSeparator = ':';
|
|
||||||
const char* at = env_var;
|
|
||||||
const char* delim = strchr(at, PathSeparator);
|
|
||||||
while (delim != 0) {
|
|
||||||
std::string tmp(at, size_t(delim-at));
|
|
||||||
if (llvm::sys::fs::is_directory(tmp.c_str()))
|
|
||||||
Paths.push_back(tmp);
|
|
||||||
at = delim + 1;
|
|
||||||
delim = strchr(at, PathSeparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*at != 0)
|
|
||||||
if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
|
|
||||||
Paths.push_back(at);
|
|
||||||
}
|
|
||||||
#if defined(__APPLE__) || defined(__CYGWIN__)
|
|
||||||
Paths.push_back("/usr/local/lib/");
|
|
||||||
Paths.push_back("/usr/X11R6/lib/");
|
|
||||||
Paths.push_back("/usr/lib/");
|
|
||||||
Paths.push_back("/lib/");
|
|
||||||
|
|
||||||
Paths.push_back("/lib/x86_64-linux-gnu/");
|
|
||||||
Paths.push_back("/usr/local/lib64/");
|
|
||||||
Paths.push_back("/usr/lib64/");
|
|
||||||
Paths.push_back("/lib64/");
|
|
||||||
#else
|
|
||||||
static bool initialized = false;
|
|
||||||
static std::vector<std::string> SysPaths;
|
|
||||||
if (!initialized) {
|
|
||||||
// trick to get the system search path
|
|
||||||
std::string cmd("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
|
|
||||||
FILE *pf = popen(cmd.c_str (), "r");
|
|
||||||
std::string result = "";
|
|
||||||
std::string sys_path = "";
|
|
||||||
char buffer[128];
|
|
||||||
while (!feof(pf)) {
|
|
||||||
if (fgets(buffer, 128, pf) != NULL)
|
|
||||||
result += buffer;
|
|
||||||
}
|
|
||||||
pclose(pf);
|
|
||||||
std::size_t from
|
|
||||||
= result.find("search path=", result.find("(LD_LIBRARY_PATH)"));
|
|
||||||
std::size_t to = result.find("(system search path)");
|
|
||||||
if (from != std::string::npos && to != std::string::npos) {
|
|
||||||
from += 12;
|
|
||||||
sys_path = result.substr(from, to-from);
|
|
||||||
sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace),
|
|
||||||
sys_path.end());
|
|
||||||
sys_path += ':';
|
|
||||||
}
|
|
||||||
static const char PathSeparator = ':';
|
|
||||||
const char* at = sys_path.c_str();
|
|
||||||
const char* delim = strchr(at, PathSeparator);
|
|
||||||
while (delim != 0) {
|
|
||||||
std::string tmp(at, size_t(delim-at));
|
|
||||||
if (llvm::sys::fs::is_directory(tmp.c_str()))
|
|
||||||
SysPaths.push_back(tmp);
|
|
||||||
at = delim + 1;
|
|
||||||
delim = strchr(at, PathSeparator);
|
|
||||||
}
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator I = SysPaths.begin(),
|
|
||||||
E = SysPaths.end(); I != E; ++I)
|
|
||||||
Paths.push_back((*I).c_str());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#elif defined(LLVM_ON_WIN32)
|
|
||||||
static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
|
|
||||||
char buff[MAX_PATH];
|
|
||||||
// Generic form of C:\Windows\System32
|
|
||||||
HRESULT res = SHGetFolderPathA(NULL,
|
|
||||||
CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
|
|
||||||
NULL,
|
|
||||||
SHGFP_TYPE_CURRENT,
|
|
||||||
buff);
|
|
||||||
if (res != S_OK) {
|
|
||||||
assert(0 && "Failed to get system directory");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Paths.push_back(buff);
|
|
||||||
|
|
||||||
// Reset buff.
|
|
||||||
buff[0] = 0;
|
|
||||||
// Generic form of C:\Windows
|
|
||||||
res = SHGetFolderPathA(NULL,
|
|
||||||
CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
|
|
||||||
NULL,
|
|
||||||
SHGFP_TYPE_CURRENT,
|
|
||||||
buff);
|
|
||||||
if (res != S_OK) {
|
|
||||||
assert(0 && "Failed to get windows directory");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Paths.push_back(buff);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# error "Unsupported platform."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace cling {
|
|
||||||
DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts,
|
|
||||||
Interpreter& I)
|
|
||||||
: m_Opts(Opts), m_Interpreter(I) {
|
|
||||||
GetSystemLibraryPaths(m_SystemSearchPaths);
|
|
||||||
m_SystemSearchPaths.push_back(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicLibraryManager::~DynamicLibraryManager() {}
|
|
||||||
|
|
||||||
static bool isSharedLib(llvm::StringRef LibName, bool* exists = 0) {
|
|
||||||
using namespace llvm::sys::fs;
|
|
||||||
file_magic Magic;
|
|
||||||
llvm::error_code Error = identify_magic(LibName, Magic);
|
|
||||||
bool onDisk = (Error == llvm::errc::success);
|
|
||||||
if (exists)
|
|
||||||
*exists = onDisk;
|
|
||||||
|
|
||||||
return onDisk &&
|
|
||||||
#ifdef __APPLE__
|
|
||||||
(Magic == file_magic::macho_fixed_virtual_memory_shared_lib
|
|
||||||
|| Magic == file_magic::macho_dynamically_linked_shared_lib
|
|
||||||
|| Magic == file_magic::macho_dynamically_linked_shared_lib_stub)
|
|
||||||
#elif defined(LLVM_ON_UNIX)
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
(Magic == file_magic::pecoff_executable)
|
|
||||||
#else
|
|
||||||
(Magic == file_magic::elf_shared_object)
|
|
||||||
#endif
|
|
||||||
#elif defined(LLVM_ON_WIN32)
|
|
||||||
(Magic == file_magic::pecoff_executable)
|
|
||||||
#else
|
|
||||||
# error "Unsupported platform."
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
|
|
||||||
llvm::SmallVector<std::string, 128>
|
|
||||||
Paths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
|
|
||||||
Paths.append(m_SystemSearchPaths.begin(), m_SystemSearchPaths.end());
|
|
||||||
|
|
||||||
for (llvm::SmallVectorImpl<std::string>::const_iterator
|
|
||||||
IPath = Paths.begin(), E = Paths.end();IPath != E; ++IPath) {
|
|
||||||
llvm::SmallString<512> ThisPath(*IPath); // FIXME: move alloc outside loop
|
|
||||||
llvm::sys::path::append(ThisPath, libStem);
|
|
||||||
bool exists;
|
|
||||||
if (isSharedLib(ThisPath.str(), &exists))
|
|
||||||
return ThisPath.str();
|
|
||||||
if (exists)
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
|
|
||||||
using namespace llvm::sys;
|
|
||||||
|
|
||||||
std::string foundDyLib = lookupLibInPaths(libStem);
|
|
||||||
|
|
||||||
if (foundDyLib.empty()) {
|
|
||||||
// Add DyLib extension:
|
|
||||||
llvm::SmallString<512> filenameWithExt(libStem);
|
|
||||||
#if defined(LLVM_ON_UNIX)
|
|
||||||
#ifdef __APPLE__
|
|
||||||
llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
|
|
||||||
#endif
|
|
||||||
static const char* DyLibExt = ".so";
|
|
||||||
#elif defined(LLVM_ON_WIN32)
|
|
||||||
static const char* DyLibExt = ".dll";
|
|
||||||
#else
|
|
||||||
# error "Unsupported platform."
|
|
||||||
#endif
|
|
||||||
filenameWithExt += DyLibExt;
|
|
||||||
foundDyLib = lookupLibInPaths(filenameWithExt);
|
|
||||||
#ifdef __APPLE__
|
|
||||||
if (foundDyLib.empty()) {
|
|
||||||
filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
|
|
||||||
filenameWithExt += ".dylib";
|
|
||||||
FfgoundDyLib = lookupLibInPaths(filenameWithExt);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundDyLib.empty())
|
|
||||||
return "";
|
|
||||||
|
|
||||||
// get canonical path name and check if already loaded
|
|
||||||
#if defined(LLVM_ON_WIN32)
|
|
||||||
llvm::SmallString<_MAX_PATH> FullPath("");
|
|
||||||
char *res = _fullpath((char *)FullPath.data(), foundDyLib.c_str(), _MAX_PATH);
|
|
||||||
#else
|
|
||||||
llvm::SmallString<PATH_MAX+1> FullPath("");
|
|
||||||
char *res = realpath(foundDyLib.c_str(), (char *)FullPath.data());
|
|
||||||
#endif
|
|
||||||
if (res == 0) {
|
|
||||||
llvm::errs() << "cling::DyLibMan::lookupLibMaybeAddExt(): error getting "
|
|
||||||
"real (canonical) path of library " << foundDyLib << '\n';
|
|
||||||
return foundDyLib;
|
|
||||||
}
|
|
||||||
FullPath.set_size(strlen(res));
|
|
||||||
return FullPath.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string normalizePath(llvm::StringRef path) {
|
|
||||||
// Make the path canonical if the file exists.
|
|
||||||
struct stat buffer;
|
|
||||||
if (stat(path.data(), &buffer) != 0)
|
|
||||||
return "";
|
|
||||||
#if defined(LLVM_ON_WIN32)
|
|
||||||
char buf[_MAX_PATH];
|
|
||||||
char *res = _fullpath(buf, path.data(), _MAX_PATH);
|
|
||||||
#else
|
|
||||||
char buf[PATH_MAX+1];
|
|
||||||
char *res = realpath(path.data(), buf);
|
|
||||||
#endif
|
|
||||||
if (res == 0) {
|
|
||||||
assert(0 && "Cannot normalize!?");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
|
|
||||||
llvm::SmallString<128> Absolute(libStem);
|
|
||||||
llvm::sys::fs::make_absolute(Absolute);
|
|
||||||
bool isAbsolute = libStem == Absolute;
|
|
||||||
|
|
||||||
// If it is an absolute path, don't try iterate over the paths.
|
|
||||||
if (isAbsolute) {
|
|
||||||
if (isSharedLib(libStem))
|
|
||||||
return normalizePath(libStem);
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string foundName = lookupLibMaybeAddExt(libStem);
|
|
||||||
if (foundName.empty() && !libStem.startswith("lib")) {
|
|
||||||
// try with "lib" prefix:
|
|
||||||
foundName = lookupLibMaybeAddExt("lib" + libStem.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSharedLib(foundName))
|
|
||||||
return normalizePath(foundName);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicLibraryManager::LoadLibResult
|
|
||||||
DynamicLibraryManager::loadLibrary(const std::string& libStem,
|
|
||||||
bool permanent) {
|
|
||||||
std::string canonicalLoadedLib = lookupLibrary(libStem);
|
|
||||||
if (canonicalLoadedLib.empty())
|
|
||||||
return kLoadLibNotFound;
|
|
||||||
|
|
||||||
if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
|
|
||||||
return kLoadLibAlreadyLoaded;
|
|
||||||
|
|
||||||
std::string errMsg;
|
|
||||||
// TODO: !permanent case
|
|
||||||
#if defined(LLVM_ON_WIN32)
|
|
||||||
HMODULE dyLibHandle = LoadLibraryEx(canonicalLoadedLib.c_str(), NULL,
|
|
||||||
DONT_RESOLVE_DLL_REFERENCES);
|
|
||||||
errMsg = "LoadLibraryEx: GetLastError() returned ";
|
|
||||||
errMsg += GetLastError();
|
|
||||||
#else
|
|
||||||
const void* dyLibHandle = dlopen(canonicalLoadedLib.c_str(),
|
|
||||||
RTLD_LAZY|RTLD_GLOBAL);
|
|
||||||
if (const char* DyLibError = dlerror()) {
|
|
||||||
errMsg = DyLibError;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!dyLibHandle) {
|
|
||||||
llvm::errs() << "cling::DyLibMan::loadLibrary(): " << errMsg << '\n';
|
|
||||||
return kLoadLibLoadError;
|
|
||||||
}
|
|
||||||
else if (InterpreterCallbacks* C = m_Interpreter.getCallbacks())
|
|
||||||
C->LibraryLoaded(dyLibHandle, canonicalLoadedLib);
|
|
||||||
|
|
||||||
std::pair<DyLibs::iterator, bool> insRes
|
|
||||||
= m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
|
|
||||||
canonicalLoadedLib));
|
|
||||||
if (!insRes.second)
|
|
||||||
return kLoadLibAlreadyLoaded;
|
|
||||||
m_LoadedLibraries.insert(canonicalLoadedLib);
|
|
||||||
return kLoadLibSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
|
|
||||||
std::string canonicalLoadedLib = lookupLibrary(libStem);
|
|
||||||
if (!isLibraryLoaded(canonicalLoadedLib))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DyLibHandle dyLibHandle = 0;
|
|
||||||
for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
|
|
||||||
I != E; ++I) {
|
|
||||||
if (I->second == canonicalLoadedLib)
|
|
||||||
dyLibHandle = I->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string errMsg;
|
|
||||||
// TODO: !permanent case
|
|
||||||
#if defined(LLVM_ON_WIN32)
|
|
||||||
UnloadLibraryEx(dyLibHandle);
|
|
||||||
errMsg = "UnoadLibraryEx: GetLastError() returned ";
|
|
||||||
errMsg += GetLastError();
|
|
||||||
#else
|
|
||||||
dlclose(const_cast<void*>(dyLibHandle));
|
|
||||||
if (const char* DyLibError = dlerror()) {
|
|
||||||
errMsg = DyLibError;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (InterpreterCallbacks* C = m_Interpreter.getCallbacks())
|
|
||||||
C->LibraryUnloaded(dyLibHandle, canonicalLoadedLib);
|
|
||||||
|
|
||||||
m_DyLibs.erase(dyLibHandle);
|
|
||||||
m_LoadedLibraries.erase(canonicalLoadedLib);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
|
|
||||||
std::string canonPath = normalizePath(fullPath);
|
|
||||||
if (m_LoadedLibraries.find(canonPath) != m_LoadedLibraries.end())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
|
|
||||||
llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
|
|
||||||
}
|
|
||||||
} // end namespace cling
|
|
File diff suppressed because it is too large
Load Diff
@ -1,210 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// CLING - the C++ LLVM-based InterpreterG :)
|
|
||||||
//
|
|
||||||
// This file is dual-licensed: you can choose to license it under the University
|
|
||||||
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
|
||||||
// LICENSE.TXT for details.
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// RUN: cat %s | %cling -Xclang -verify | FileCheck %s
|
|
||||||
|
|
||||||
#include "cling/Interpreter/Interpreter.h"
|
|
||||||
#include "cling/Interpreter/Value.h"
|
|
||||||
|
|
||||||
cling::Value V;
|
|
||||||
V // CHECK: (cling::Value &) <<<invalid>>> @0x{{.*}}
|
|
||||||
|
|
||||||
gCling->evaluate("return 1;", V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(int) 1]
|
|
||||||
|
|
||||||
gCling->evaluate("(void)V", V);
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(void) @0x{{.*}}]
|
|
||||||
|
|
||||||
// Returns must put the result in the Value.
|
|
||||||
bool cond = true;
|
|
||||||
gCling->evaluate("if (cond) return \"true\"; else return 0;", V);
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(const char [5]) "true"]
|
|
||||||
gCling->evaluate("if (cond) return; else return 12;", V);
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(void) @0x{{.*}}]
|
|
||||||
gCling->evaluate("if (cond) return; int aa = 12;", V);
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(void) @0x{{.*}}]
|
|
||||||
gCling->evaluate("cond = false; if (cond) return \"true\"; else return 0;", V);
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(int) 0]
|
|
||||||
|
|
||||||
gCling->evaluate("auto a = 12.3; a;", V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(double) 1.230000e+01]
|
|
||||||
|
|
||||||
long LongV = 17;
|
|
||||||
gCling->evaluate("LongV;", V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(long) 17]
|
|
||||||
|
|
||||||
int* IntP = (int*)0x12;
|
|
||||||
gCling->evaluate("IntP;", V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(int *) 0x12]
|
|
||||||
|
|
||||||
cling::Value Result;
|
|
||||||
gCling->evaluate("V", Result);
|
|
||||||
// Here we check what happens for record type like cling::Value; they are returned by reference.
|
|
||||||
Result // CHECK: (cling::Value &) boxes [(cling::Value &) boxes [(int *) 0x12]]
|
|
||||||
V // CHECK: (cling::Value &) boxes [(int *) 0x12]
|
|
||||||
|
|
||||||
// Savannah #96277
|
|
||||||
gCling->evaluate("gCling->declare(\"double sin(double);\"); double one = sin(3.141/2);", V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(double) 1.000000e+00]
|
|
||||||
|
|
||||||
gCling->process("double one = sin(3.141/2);", &V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(double) 1.000000e+00]
|
|
||||||
one // CHECK: (double) 1.000
|
|
||||||
int one; // expected-error {{redefinition of 'one' with a different type: 'int' vs 'double'}} expected-note {{previous definition is here}}
|
|
||||||
|
|
||||||
// Make sure that PR#98434 doesn't get reintroduced.
|
|
||||||
.rawInput
|
|
||||||
void f(int) { return; }
|
|
||||||
.rawInput
|
|
||||||
|
|
||||||
gCling->evaluate("f", V);
|
|
||||||
V.isValid() //CHECK: {{\([_]B|b}}ool) true
|
|
||||||
// end PR#98434
|
|
||||||
|
|
||||||
// Check lifetime of objects in Value
|
|
||||||
.rawInput 1
|
|
||||||
struct WithDtor {
|
|
||||||
static int fgCount;
|
|
||||||
WithDtor() { ++fgCount; }
|
|
||||||
WithDtor(const WithDtor&) { ++fgCount; }
|
|
||||||
~WithDtor() { --fgCount; }
|
|
||||||
};
|
|
||||||
int WithDtor::fgCount = 0;
|
|
||||||
WithDtor getWithDtor() { return WithDtor(); }
|
|
||||||
#include <vector>
|
|
||||||
std::vector<WithDtor> getWithDtorVec() { std::vector<WithDtor> ret; ret.resize(7); return ret; }
|
|
||||||
.rawInput 0
|
|
||||||
|
|
||||||
cling::Value* VOnHeap = new cling::Value();
|
|
||||||
gCling->evaluate("getWithDtor()", *VOnHeap);
|
|
||||||
*VOnHeap //CHECK: (cling::Value &) boxes [(WithDtor) @0x{{.*}}]
|
|
||||||
WithDtor::fgCount //CHECK: (int) 1
|
|
||||||
delete VOnHeap;
|
|
||||||
WithDtor::fgCount //CHECK: (int) 0
|
|
||||||
|
|
||||||
// Check destructor call for templates
|
|
||||||
VOnHeap = new cling::Value();
|
|
||||||
gCling->evaluate("getWithDtorVec()", *VOnHeap);
|
|
||||||
*VOnHeap //CHECK: (cling::Value &) boxes [(std::vector<WithDtor>) @0x{{.*}}]
|
|
||||||
WithDtor::fgCount //CHECK: (int) 7
|
|
||||||
delete VOnHeap;
|
|
||||||
WithDtor::fgCount //CHECK: (int) 0
|
|
||||||
|
|
||||||
// long doubles (tricky for the JIT).
|
|
||||||
gCling->evaluate("17.42L", V);
|
|
||||||
V // CHECK: (cling::Value &) boxes [(long double) 17.42{{[0-9]*}}L]
|
|
||||||
|
|
||||||
// Test references, temporaries
|
|
||||||
.rawInput 1
|
|
||||||
extern "C" int printf(const char*,...);
|
|
||||||
struct Tracer {
|
|
||||||
std::string Content;
|
|
||||||
static int InstanceCount;
|
|
||||||
Tracer(const char* str): Content(str) { ++InstanceCount; dump("ctor"); }
|
|
||||||
Tracer(const Tracer& o): Content(o.Content + "+") {
|
|
||||||
++InstanceCount; dump("copy");
|
|
||||||
}
|
|
||||||
~Tracer() {--InstanceCount; dump("dtor");}
|
|
||||||
std::string asStr() const {
|
|
||||||
return Content + "{" + (char)('0' + InstanceCount) + "}";
|
|
||||||
}
|
|
||||||
void dump(const char* tag) { printf("%s:%s\n", asStr().c_str(), tag); }
|
|
||||||
};
|
|
||||||
int Tracer::InstanceCount = 0;
|
|
||||||
|
|
||||||
Tracer ObjMaker() { return Tracer("MADE"); }
|
|
||||||
Tracer& RefMaker() { static Tracer R("REF"); return R; }
|
|
||||||
const Tracer& ConstRefMaker() {static Tracer R("CONSTREF"); return R;}
|
|
||||||
namespace cling {
|
|
||||||
// FIXME: inline printValue is not used by PrintClingValue()!
|
|
||||||
std::string printValue(const Tracer* const p, const Tracer* const u,
|
|
||||||
const ValuePrinterInfo& VPI) {
|
|
||||||
return p->asStr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void dumpTracerSVR(cling::Value& svr) {
|
|
||||||
((Tracer*)svr.getAs<void*>())->dump("dump");
|
|
||||||
}
|
|
||||||
.rawInput 0
|
|
||||||
|
|
||||||
// Creating the static in constructs one object. It gets returned by
|
|
||||||
// reference; it should only be destructed by ~JIT, definitely not by
|
|
||||||
// ~Value (which should only store a Tracer&)
|
|
||||||
gCling->evaluate("RefMaker()", V);
|
|
||||||
// This is the local static:
|
|
||||||
// CHECK: REF{1}:ctor
|
|
||||||
printf("RefMaker() done\n"); // CHECK-NEXT: RefMaker() done
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(Tracer &) @{{.*}}]
|
|
||||||
dumpTracerSVR(V); // CHECK-NEXT: REF{1}:dump
|
|
||||||
|
|
||||||
// Setting a new value should destruct the old - BUT it's a ref thus no
|
|
||||||
// destruction.
|
|
||||||
|
|
||||||
// Create a temporary. Copies it into V through placement-new and copy
|
|
||||||
// construction. The latter is elided; the temporary *is* what's stored in V.
|
|
||||||
// Thus all we see is the construction of the temporary.
|
|
||||||
gCling->evaluate("ObjMaker()", V);
|
|
||||||
// The temporary gets created:
|
|
||||||
// CHECK-NEXT:MADE{2}:ctor
|
|
||||||
printf("ObjMaker() done\n"); //CHECK-NEXT: ObjMaker() done
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(Tracer) @{{.*}}]
|
|
||||||
dumpTracerSVR(V); // CHECK-NEXT: MADE{2}:dump
|
|
||||||
|
|
||||||
// Creating a variable:
|
|
||||||
Tracer RT("VAR"); // CHECK-NEXT: VAR{3}:ctor
|
|
||||||
|
|
||||||
// The following is a declRefExpr of lvalue type. We explicitly treat this as
|
|
||||||
// a reference; i.e. the cling::Value will claim to store a Tracer&. No extra
|
|
||||||
// construction, no extra allocation should happen.
|
|
||||||
//
|
|
||||||
// Setting a new value should destruct the old:
|
|
||||||
// CHECK-NEXT: MADE{2}:dtor
|
|
||||||
gCling->evaluate("RT", V); // should not call any ctor!
|
|
||||||
printf("RT done\n"); //CHECK-NEXT: RT done
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(Tracer &) @{{.*}}]
|
|
||||||
dumpTracerSVR(V); // CHECK-NEXT: VAR{2}:dump
|
|
||||||
|
|
||||||
// The following creates a copy, explicitly. This temporary object is then put
|
|
||||||
// into the Value.
|
|
||||||
//
|
|
||||||
gCling->evaluate("(Tracer)RT", V);
|
|
||||||
// Copies RT:
|
|
||||||
//CHECK-NEXT: VAR+{3}:copy
|
|
||||||
printf("(Tracer)RT done\n"); //CHECK-NEXT: RT done
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(Tracer) @{{.*}}]
|
|
||||||
dumpTracerSVR(V); // CHECK-NEXT: VAR+{3}:dump
|
|
||||||
|
|
||||||
// Check eval of array var
|
|
||||||
Tracer arrV[] = {ObjMaker(), ObjMaker(), ObjMaker()};
|
|
||||||
// The array is built:
|
|
||||||
//CHECK-NEXT: MADE{4}:ctor
|
|
||||||
//CHECK-NEXT: MADE{5}:ctor
|
|
||||||
//CHECK-NEXT: MADE{6}:ctor
|
|
||||||
|
|
||||||
gCling->evaluate("arrV", V);
|
|
||||||
// Now V gets destructed...
|
|
||||||
//CHECK-NEXT: VAR+{5}:dtor
|
|
||||||
// ...and the elements are copied:
|
|
||||||
//CHECK-NEXT: MADE+{6}:copy
|
|
||||||
//CHECK-NEXT: MADE+{7}:copy
|
|
||||||
//CHECK-NEXT: MADE+{8}:copy
|
|
||||||
|
|
||||||
V // CHECK-NEXT: (cling::Value &) boxes [(Tracer [3]) { @{{.*}}, @{{.*}}, @{{.*}} }]
|
|
||||||
|
|
||||||
// Destruct the variables with static storage:
|
|
||||||
// Destruct arrV:
|
|
||||||
//CHECK-NEXT: MADE{7}:dtor
|
|
||||||
//CHECK-NEXT: MADE{6}:dtor
|
|
||||||
//CHECK-NEXT: MADE{5}:dtor
|
|
||||||
|
|
||||||
// CHECK-NEXT: VAR{4}:dtor
|
|
||||||
// CHECK-NEXT: REF{3}:dtor
|
|
||||||
|
|
||||||
//CHECK-NEXT: MADE+{2}:dtor
|
|
||||||
//CHECK-NEXT: MADE+{1}:dtor
|
|
||||||
//CHECK-NEXT: MADE+{0}:dtor
|
|
@ -1,29 +0,0 @@
|
|||||||
/*------------------------------------------------------------------------------
|
|
||||||
// CLING - the C++ LLVM-based InterpreterG :)
|
|
||||||
//
|
|
||||||
// This file is dual-licensed: you can choose to license it under the University
|
|
||||||
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
|
||||||
// LICENSE.TXT for details.
|
|
||||||
//----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// same test as test_01.c but ensuring the .c file to be processed
|
|
||||||
// is in the working directory (issue ROOT-6244)
|
|
||||||
|
|
||||||
// RUN: cd `dirname %s` ; %cling %s | FileCheck %s
|
|
||||||
|
|
||||||
extern "C" int printf(const char*,...);
|
|
||||||
|
|
||||||
const char* defaultArgV[] = {"A default argument", "", 0};
|
|
||||||
|
|
||||||
int test_exec_in_same_dir(int argc=12, const char** argv = defaultArgV)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for( i = 0; i < 5; ++i )
|
|
||||||
printf( "Hello World #%d\n", i );
|
|
||||||
// CHECK: Hello World #0
|
|
||||||
// CHECK: Hello World #1
|
|
||||||
// CHECK: Hello World #2
|
|
||||||
// CHECK: Hello World #3
|
|
||||||
// CHECK: Hello World #4
|
|
||||||
return 0;
|
|
||||||
}
|
|
Reference in New Issue
Block a user