Rename LoadLibResult constants to start with 'k'.
Enable kLoadLibExists case in TCintWithCling. Collect statistics about loaded files. Give access to that through .file; rename SourceManager dump to fileEx. Documentation. (Sorry, should have been three patches.) git-svn-id: http://root.cern.ch/svn/root/trunk@47330 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
parent
6379c2a21d
commit
226b360b15
@ -72,10 +72,50 @@ namespace cling {
|
|||||||
///\brief Describes the result of loading a library.
|
///\brief Describes the result of loading a library.
|
||||||
///
|
///
|
||||||
enum LoadLibResult {
|
enum LoadLibResult {
|
||||||
LoadLibSuccess, // library loaded successfully
|
kLoadLibSuccess, // library loaded successfully
|
||||||
LoadLibExists, // library was already loaded
|
kLoadLibExists, // library was already loaded
|
||||||
LoadLibError, // library was not found
|
kLoadLibError, // library was not found
|
||||||
LoadLibNumResults
|
kLoadLibNumResults
|
||||||
|
};
|
||||||
|
|
||||||
|
class LoadedFileInfo {
|
||||||
|
public:
|
||||||
|
enum FileType {
|
||||||
|
kSource,
|
||||||
|
kDynamicLibrary,
|
||||||
|
kBitcode,
|
||||||
|
kNumFileTypes
|
||||||
|
};
|
||||||
|
|
||||||
|
///\brief Name as loaded for the first time.
|
||||||
|
///
|
||||||
|
const std::string& getName() const { return m_Name; }
|
||||||
|
|
||||||
|
///\brief Type of the file.
|
||||||
|
FileType getType() const { return m_Type; }
|
||||||
|
|
||||||
|
///\brief Pointer to Interpreter::m_DyLibs entry if dynamic library
|
||||||
|
///
|
||||||
|
const llvm::sys::DynamicLibrary* getDynLib() const { return m_DynLib; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
///\brief Constructor used by Interpreter.
|
||||||
|
LoadedFileInfo(const std::string& name, FileType type,
|
||||||
|
const llvm::sys::DynamicLibrary* dynLib):
|
||||||
|
m_Name(name), m_Type(type), m_DynLib(dynLib) {}
|
||||||
|
|
||||||
|
///\brief Name as loaded for the first time.
|
||||||
|
///
|
||||||
|
std::string m_Name;
|
||||||
|
|
||||||
|
///\brief Type of the file.
|
||||||
|
FileType m_Type;
|
||||||
|
|
||||||
|
///\brief Pointer to Interpreter::m_DyLibs entry if dynamic library
|
||||||
|
///
|
||||||
|
const llvm::sys::DynamicLibrary* m_DynLib;
|
||||||
|
|
||||||
|
friend class Interpreter;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -176,10 +216,17 @@ namespace cling {
|
|||||||
///
|
///
|
||||||
std::set<llvm::sys::DynamicLibrary> m_DyLibs;
|
std::set<llvm::sys::DynamicLibrary> m_DyLibs;
|
||||||
|
|
||||||
|
///\brief Information about loaded files.
|
||||||
|
///
|
||||||
|
llvm::SmallVector<LoadedFileInfo*, 200> m_LoadedFiles;
|
||||||
|
|
||||||
///\brief Try to load a library file via the llvm::Linker.
|
///\brief Try to load a library file via the llvm::Linker.
|
||||||
///
|
///
|
||||||
LoadLibResult tryLinker(const std::string& filename, bool permanent);
|
LoadLibResult tryLinker(const std::string& filename, bool permanent);
|
||||||
|
|
||||||
|
void addLoadedFile(const std::string& name, LoadedFileInfo::FileType type,
|
||||||
|
const llvm::sys::DynamicLibrary* dyLib = 0);
|
||||||
|
|
||||||
///\brief Processes the invocation options.
|
///\brief Processes the invocation options.
|
||||||
///
|
///
|
||||||
void handleFrontendOptions();
|
void handleFrontendOptions();
|
||||||
@ -428,19 +475,24 @@ namespace cling {
|
|||||||
///\brief Loads a shared library.
|
///\brief Loads a shared library.
|
||||||
///
|
///
|
||||||
///\param [in] filename - The file to loaded.
|
///\param [in] filename - The file to loaded.
|
||||||
|
///\param [in] permanent - If false, the file can be unloaded later.
|
||||||
///
|
///
|
||||||
///\returns LoadLibSuccess on success, LoadLibExists if the library was
|
///\returns kLoadLibSuccess on success, kLoadLibExists if the library was
|
||||||
/// already loaded, LoadLibError if the library cannot be found or any
|
/// already loaded, kLoadLibError if the library cannot be found or any
|
||||||
/// other error was encountered.
|
/// other error was encountered.
|
||||||
///
|
///
|
||||||
///
|
|
||||||
LoadLibResult loadLibrary(const std::string& filename, bool permanent);
|
LoadLibResult loadLibrary(const std::string& filename, bool permanent);
|
||||||
|
|
||||||
|
///\brief Get the collection of loaded files.
|
||||||
|
///
|
||||||
|
const llvm::SmallVectorImpl<LoadedFileInfo*>& getLoadedFiles() const {
|
||||||
|
return m_LoadedFiles; }
|
||||||
|
|
||||||
void enableDynamicLookup(bool value = true);
|
void enableDynamicLookup(bool value = true);
|
||||||
bool isDynamicLookupEnabled() { return m_DynamicLookupEnabled; }
|
bool isDynamicLookupEnabled() { return m_DynamicLookupEnabled; }
|
||||||
|
|
||||||
bool isPrintingAST() { return m_PrintAST; }
|
bool isPrintingAST() { return m_PrintAST; }
|
||||||
void enablePrintAST(bool print = true) { m_PrintAST = print;}
|
void enablePrintAST(bool print = true) { m_PrintAST = print; }
|
||||||
|
|
||||||
clang::CompilerInstance* getCI() const;
|
clang::CompilerInstance* getCI() const;
|
||||||
const clang::Sema& getSema() const;
|
const clang::Sema& getSema() const;
|
||||||
|
@ -78,7 +78,6 @@ namespace cling {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// This function isn't referenced outside its translation unit, but it
|
// This function isn't referenced outside its translation unit, but it
|
||||||
// can't use the "static" keyword because its address is used for
|
// can't use the "static" keyword because its address is used for
|
||||||
// GetMainExecutable (since some platforms don't support taking the
|
// GetMainExecutable (since some platforms don't support taking the
|
||||||
@ -542,15 +541,24 @@ namespace cling {
|
|||||||
return Interpreter::kFailure;
|
return Interpreter::kFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Interpreter::addLoadedFile(const std::string& name,
|
||||||
|
Interpreter::LoadedFileInfo::FileType type,
|
||||||
|
const llvm::sys::DynamicLibrary* dyLib) {
|
||||||
|
m_LoadedFiles.push_back(new LoadedFileInfo(name, type, dyLib));
|
||||||
|
}
|
||||||
|
|
||||||
Interpreter::CompilationResult
|
Interpreter::CompilationResult
|
||||||
Interpreter::loadFile(const std::string& filename,
|
Interpreter::loadFile(const std::string& filename,
|
||||||
bool allowSharedLib /*=true*/) {
|
bool allowSharedLib /*=true*/) {
|
||||||
if (allowSharedLib && loadLibrary(filename, false) == LoadLibSuccess)
|
if (allowSharedLib && loadLibrary(filename, false) == kLoadLibSuccess)
|
||||||
return kSuccess;
|
return kSuccess;
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
code += "#include \"" + filename + "\"";
|
code += "#include \"" + filename + "\"";
|
||||||
return declare(code);
|
CompilationResult res = declare(code);
|
||||||
|
if (res == kSuccess)
|
||||||
|
addLoadedFile(filename,LoadedFileInfo::kSource);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -562,6 +570,12 @@ namespace cling {
|
|||||||
|
|
||||||
llvm::Linker L("cling", module, llvm::Linker::QuietWarnings
|
llvm::Linker L("cling", module, llvm::Linker::QuietWarnings
|
||||||
| llvm::Linker::QuietErrors);
|
| llvm::Linker::QuietErrors);
|
||||||
|
struct LinkerModuleReleaseRAII {
|
||||||
|
LinkerModuleReleaseRAII(llvm::Linker& L): m_L(L) {}
|
||||||
|
~LinkerModuleReleaseRAII() { m_L.releaseModule(); }
|
||||||
|
llvm::Linker& m_L;
|
||||||
|
} LinkerModuleReleaseRAII_(L);
|
||||||
|
|
||||||
const InvocationOptions& Opts = getOptions();
|
const InvocationOptions& Opts = getOptions();
|
||||||
for (std::vector<Path>::const_iterator I
|
for (std::vector<Path>::const_iterator I
|
||||||
= Opts.LibSearchPath.begin(), E = Opts.LibSearchPath.end(); I != E;
|
= Opts.LibSearchPath.begin(), E = Opts.LibSearchPath.end(); I != E;
|
||||||
@ -576,22 +590,21 @@ namespace cling {
|
|||||||
std::string Magic;
|
std::string Magic;
|
||||||
if (!FilePath.getMagicNumber(Magic, 64)) {
|
if (!FilePath.getMagicNumber(Magic, 64)) {
|
||||||
// filename doesn't exist...
|
// filename doesn't exist...
|
||||||
L.releaseModule();
|
return kLoadLibError;
|
||||||
return LoadLibError;
|
|
||||||
}
|
}
|
||||||
if (IdentifyFileType(Magic.c_str(), 64) == Bitcode_FileType) {
|
if (IdentifyFileType(Magic.c_str(), 64) != Bitcode_FileType) {
|
||||||
// We are promised a bitcode file, complain if it fails
|
|
||||||
L.setFlags(0);
|
|
||||||
if (L.LinkInFile(Path(filename), Native)) {
|
|
||||||
L.releaseModule();
|
|
||||||
return LoadLibError;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Nothing the linker can handle
|
// Nothing the linker can handle
|
||||||
L.releaseModule();
|
return kLoadLibError;
|
||||||
return LoadLibError;
|
|
||||||
}
|
}
|
||||||
} else if (Native) {
|
// We are promised a bitcode file, complain if it fails
|
||||||
|
L.setFlags(0);
|
||||||
|
if (L.LinkInFile(Path(filename), Native)) {
|
||||||
|
return kLoadLibError;
|
||||||
|
}
|
||||||
|
addLoadedFile(filename, LoadedFileInfo::kBitcode);
|
||||||
|
return kLoadLibSuccess;
|
||||||
|
}
|
||||||
|
if (Native) {
|
||||||
// native shared library, load it!
|
// native shared library, load it!
|
||||||
Path SoFile = L.FindLib(filename);
|
Path SoFile = L.FindLib(filename);
|
||||||
assert(!SoFile.isEmpty() && "The shared lib exists but can't find it!");
|
assert(!SoFile.isEmpty() && "The shared lib exists but can't find it!");
|
||||||
@ -599,30 +612,33 @@ namespace cling {
|
|||||||
// TODO: !permanent case
|
// TODO: !permanent case
|
||||||
DynamicLibrary DyLib
|
DynamicLibrary DyLib
|
||||||
= DynamicLibrary::getPermanentLibrary(SoFile.str().c_str(), &errMsg);
|
= DynamicLibrary::getPermanentLibrary(SoFile.str().c_str(), &errMsg);
|
||||||
L.releaseModule();
|
|
||||||
if (!DyLib.isValid())
|
if (!DyLib.isValid())
|
||||||
return LoadLibError;
|
return kLoadLibError;
|
||||||
if (!m_DyLibs.insert(DyLib).second)
|
std::pair<std::set<llvm::sys::DynamicLibrary>::iterator, bool> insRes
|
||||||
return LoadLibExists;
|
= m_DyLibs.insert(DyLib);
|
||||||
return LoadLibSuccess;
|
if (!insRes.second)
|
||||||
|
return kLoadLibExists;
|
||||||
|
addLoadedFile(filename, LoadedFileInfo::kDynamicLibrary,
|
||||||
|
&(*insRes.first));
|
||||||
|
return kLoadLibSuccess;
|
||||||
}
|
}
|
||||||
return LoadLibError;
|
return kLoadLibError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interpreter::LoadLibResult
|
Interpreter::LoadLibResult
|
||||||
Interpreter::loadLibrary(const std::string& filename, bool permanent) {
|
Interpreter::loadLibrary(const std::string& filename, bool permanent) {
|
||||||
LoadLibResult res = tryLinker(filename, permanent);
|
LoadLibResult res = tryLinker(filename, permanent);
|
||||||
if (res != LoadLibError) {
|
if (res != kLoadLibError) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (filename.compare(0, 3, "lib") == 0) {
|
if (filename.compare(0, 3, "lib") == 0) {
|
||||||
// starts with "lib", try without (the llvm::Linker forces
|
// starts with "lib", try without (the llvm::Linker forces
|
||||||
// a "lib" in front, which makes it liblib...
|
// a "lib" in front, which makes it liblib...
|
||||||
res = tryLinker(filename.substr(3, std::string::npos), permanent);
|
res = tryLinker(filename.substr(3, std::string::npos), permanent);
|
||||||
if (res != LoadLibError)
|
if (res != kLoadLibError)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
return LoadLibError;
|
return kLoadLibError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::installLazyFunctionCreator(void* (*fp)(const std::string&)) {
|
void Interpreter::installLazyFunctionCreator(void* (*fp)(const std::string&)) {
|
||||||
|
@ -421,10 +421,20 @@ namespace cling {
|
|||||||
PrintCommandHelp();
|
PrintCommandHelp();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (Command.equals("file")) {
|
else if (Command.equals("fileEx")) {
|
||||||
PrintFileStats();
|
PrintFileStats();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (Command.equals("file")) {
|
||||||
|
typedef llvm::SmallVectorImpl<Interpreter::LoadedFileInfo*> LoadedFiles_t;
|
||||||
|
const LoadedFiles_t& LoadedFiles = m_Interp.getLoadedFiles();
|
||||||
|
for (LoadedFiles_t::const_iterator I = LoadedFiles.begin(),
|
||||||
|
E = LoadedFiles.end(); I != E; ++I) {
|
||||||
|
char cType[] = { 'S', 'D', 'B' };
|
||||||
|
llvm::outs() << '[' << cType[(*I)->getType()] << "] " << (*I)->getName() << '\n';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (compRes) *compRes = Interpreter::kFailure;
|
if (compRes) *compRes = Interpreter::kFailure;
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user