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.
|
||||
///
|
||||
enum LoadLibResult {
|
||||
LoadLibSuccess, // library loaded successfully
|
||||
LoadLibExists, // library was already loaded
|
||||
LoadLibError, // library was not found
|
||||
LoadLibNumResults
|
||||
kLoadLibSuccess, // library loaded successfully
|
||||
kLoadLibExists, // library was already loaded
|
||||
kLoadLibError, // library was not found
|
||||
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:
|
||||
@ -176,10 +216,17 @@ namespace cling {
|
||||
///
|
||||
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.
|
||||
///
|
||||
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.
|
||||
///
|
||||
void handleFrontendOptions();
|
||||
@ -428,19 +475,24 @@ namespace cling {
|
||||
///\brief Loads a shared library.
|
||||
///
|
||||
///\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
|
||||
/// already loaded, LoadLibError if the library cannot be found or any
|
||||
///\returns kLoadLibSuccess on success, kLoadLibExists if the library was
|
||||
/// already loaded, kLoadLibError if the library cannot be found or any
|
||||
/// other error was encountered.
|
||||
///
|
||||
///
|
||||
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);
|
||||
bool isDynamicLookupEnabled() { return m_DynamicLookupEnabled; }
|
||||
|
||||
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;
|
||||
const clang::Sema& getSema() const;
|
||||
|
@ -78,7 +78,6 @@ namespace cling {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// This function isn't referenced outside its translation unit, but it
|
||||
// can't use the "static" keyword because its address is used for
|
||||
// GetMainExecutable (since some platforms don't support taking the
|
||||
@ -542,15 +541,24 @@ namespace cling {
|
||||
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::loadFile(const std::string& filename,
|
||||
bool allowSharedLib /*=true*/) {
|
||||
if (allowSharedLib && loadLibrary(filename, false) == LoadLibSuccess)
|
||||
if (allowSharedLib && loadLibrary(filename, false) == kLoadLibSuccess)
|
||||
return kSuccess;
|
||||
|
||||
std::string code;
|
||||
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::QuietErrors);
|
||||
struct LinkerModuleReleaseRAII {
|
||||
LinkerModuleReleaseRAII(llvm::Linker& L): m_L(L) {}
|
||||
~LinkerModuleReleaseRAII() { m_L.releaseModule(); }
|
||||
llvm::Linker& m_L;
|
||||
} LinkerModuleReleaseRAII_(L);
|
||||
|
||||
const InvocationOptions& Opts = getOptions();
|
||||
for (std::vector<Path>::const_iterator I
|
||||
= Opts.LibSearchPath.begin(), E = Opts.LibSearchPath.end(); I != E;
|
||||
@ -576,22 +590,21 @@ namespace cling {
|
||||
std::string Magic;
|
||||
if (!FilePath.getMagicNumber(Magic, 64)) {
|
||||
// filename doesn't exist...
|
||||
L.releaseModule();
|
||||
return LoadLibError;
|
||||
return kLoadLibError;
|
||||
}
|
||||
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 {
|
||||
if (IdentifyFileType(Magic.c_str(), 64) != Bitcode_FileType) {
|
||||
// Nothing the linker can handle
|
||||
L.releaseModule();
|
||||
return LoadLibError;
|
||||
return kLoadLibError;
|
||||
}
|
||||
} 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!
|
||||
Path SoFile = L.FindLib(filename);
|
||||
assert(!SoFile.isEmpty() && "The shared lib exists but can't find it!");
|
||||
@ -599,30 +612,33 @@ namespace cling {
|
||||
// TODO: !permanent case
|
||||
DynamicLibrary DyLib
|
||||
= DynamicLibrary::getPermanentLibrary(SoFile.str().c_str(), &errMsg);
|
||||
L.releaseModule();
|
||||
if (!DyLib.isValid())
|
||||
return LoadLibError;
|
||||
if (!m_DyLibs.insert(DyLib).second)
|
||||
return LoadLibExists;
|
||||
return LoadLibSuccess;
|
||||
return kLoadLibError;
|
||||
std::pair<std::set<llvm::sys::DynamicLibrary>::iterator, bool> insRes
|
||||
= m_DyLibs.insert(DyLib);
|
||||
if (!insRes.second)
|
||||
return kLoadLibExists;
|
||||
addLoadedFile(filename, LoadedFileInfo::kDynamicLibrary,
|
||||
&(*insRes.first));
|
||||
return kLoadLibSuccess;
|
||||
}
|
||||
return LoadLibError;
|
||||
return kLoadLibError;
|
||||
}
|
||||
|
||||
Interpreter::LoadLibResult
|
||||
Interpreter::loadLibrary(const std::string& filename, bool permanent) {
|
||||
LoadLibResult res = tryLinker(filename, permanent);
|
||||
if (res != LoadLibError) {
|
||||
if (res != kLoadLibError) {
|
||||
return res;
|
||||
}
|
||||
if (filename.compare(0, 3, "lib") == 0) {
|
||||
// starts with "lib", try without (the llvm::Linker forces
|
||||
// a "lib" in front, which makes it liblib...
|
||||
res = tryLinker(filename.substr(3, std::string::npos), permanent);
|
||||
if (res != LoadLibError)
|
||||
if (res != kLoadLibError)
|
||||
return res;
|
||||
}
|
||||
return LoadLibError;
|
||||
return kLoadLibError;
|
||||
}
|
||||
|
||||
void Interpreter::installLazyFunctionCreator(void* (*fp)(const std::string&)) {
|
||||
|
@ -421,10 +421,20 @@ namespace cling {
|
||||
PrintCommandHelp();
|
||||
return true;
|
||||
}
|
||||
else if (Command.equals("file")) {
|
||||
else if (Command.equals("fileEx")) {
|
||||
PrintFileStats();
|
||||
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;
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user