Define result of ExecutionContext::executeFunction().
Return it all the way through Interpreter. Fixes bug #98837. git-svn-id: http://root.cern.ch/svn/root/trunk@47337 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
parent
f8b1205d19
commit
7d5ed9e511
@ -78,6 +78,30 @@ namespace cling {
|
||||
kLoadLibNumResults
|
||||
};
|
||||
|
||||
///\brief Describes the result of running a function.
|
||||
///
|
||||
enum ExecutionResult {
|
||||
///\brief The function was run successfully.
|
||||
kExeSuccess,
|
||||
///\brief Code generator is unavailable; not an error.
|
||||
kExeNoCodeGen,
|
||||
|
||||
///\brief First error value.
|
||||
kExeFirstError,
|
||||
///\brief The function is not known and cannot be called.
|
||||
kExeFunctionNotCompiled = kExeFirstError,
|
||||
///\brief While compiling the function, unknown symbols were encountered.
|
||||
kExeUnresolvedSymbols,
|
||||
///\brief Compilation error.
|
||||
kExeCompilationError,
|
||||
///\brief The function is not known.
|
||||
kExeUnkownFunction,
|
||||
|
||||
///\brief Number of possible results.
|
||||
kNumExeResults
|
||||
};
|
||||
|
||||
|
||||
class LoadedFileInfo {
|
||||
public:
|
||||
enum FileType {
|
||||
@ -276,9 +300,10 @@ namespace cling {
|
||||
/// initialized to point to the return value's location if the
|
||||
/// expression result is an aggregate.
|
||||
///
|
||||
///\returns true if successful otherwise false.
|
||||
///\returns The result of the execution.
|
||||
///
|
||||
bool RunFunction(const clang::FunctionDecl* FD, StoredValueRef* res = 0);
|
||||
ExecutionResult RunFunction(const clang::FunctionDecl* FD,
|
||||
StoredValueRef* res = 0);
|
||||
|
||||
///\brief Forwards to cling::ExecutionContext::addSymbol.
|
||||
///
|
||||
|
@ -131,7 +131,7 @@ ExecutionContext::NotifyLazyFunctionCreators(const std::string& mangled_name)
|
||||
return HandleMissingFunction(mangled_name);
|
||||
}
|
||||
|
||||
void
|
||||
ExecutionContext::ExecutionResult
|
||||
ExecutionContext::executeFunction(llvm::StringRef funcname,
|
||||
const clang::ASTContext& Ctx,
|
||||
clang::QualType retType,
|
||||
@ -156,8 +156,9 @@ ExecutionContext::executeFunction(llvm::StringRef funcname,
|
||||
|
||||
llvm::Function* f = m_engine->FindFunctionNamed(funcname.data());
|
||||
if (!f) {
|
||||
llvm::errs() << "ExecutionContext::executeFunction: could not find function named " << funcname << '\n';
|
||||
return;
|
||||
llvm::errs() << "ExecutionContext::executeFunction: could not find function named "
|
||||
<< funcname << '\n';
|
||||
return kExeFunctionNotCompiled;
|
||||
}
|
||||
JITtedFunctionCollector listener;
|
||||
// register the listener
|
||||
@ -177,7 +178,7 @@ ExecutionContext::executeFunction(llvm::StringRef funcname,
|
||||
// cleanup functions
|
||||
listener.UnregisterFunctionMapping(*m_engine);
|
||||
m_engine->UnregisterJITEventListener(&listener);
|
||||
return;
|
||||
return kExeUnresolvedSymbols;
|
||||
}
|
||||
// cleanup list and unregister our listener
|
||||
m_engine->UnregisterJITEventListener(&listener);
|
||||
@ -209,6 +210,7 @@ ExecutionContext::executeFunction(llvm::StringRef funcname,
|
||||
}
|
||||
|
||||
m_engine->freeMachineCodeForFunction(f);
|
||||
return kExeSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,13 @@ namespace cling {
|
||||
|
||||
public:
|
||||
|
||||
enum ExecutionResult {
|
||||
kExeSuccess,
|
||||
kExeFunctionNotCompiled,
|
||||
kExeUnresolvedSymbols,
|
||||
kNumExeResults
|
||||
};
|
||||
|
||||
ExecutionContext();
|
||||
~ExecutionContext();
|
||||
|
||||
@ -42,10 +49,10 @@ namespace cling {
|
||||
void runStaticInitializersOnce(llvm::Module* m);
|
||||
void runStaticDestructorsOnce(llvm::Module* m);
|
||||
|
||||
void executeFunction(llvm::StringRef function,
|
||||
const clang::ASTContext& Ctx,
|
||||
clang::QualType retType,
|
||||
StoredValueRef* returnValue = 0);
|
||||
ExecutionResult executeFunction(llvm::StringRef function,
|
||||
const clang::ASTContext& Ctx,
|
||||
clang::QualType retType,
|
||||
StoredValueRef* returnValue = 0);
|
||||
|
||||
///\brief Adds a symbol (function) to the execution engine.
|
||||
///
|
||||
|
@ -438,7 +438,7 @@ namespace cling {
|
||||
if (m_IncrParser->Compile(Wrapper, CO) == IncrementalParser::kSuccess) {
|
||||
const Transaction* lastT = m_IncrParser->getLastTransaction();
|
||||
if (lastT->getState() == Transaction::kCommitted
|
||||
&& RunFunction(lastT->getWrapperFD()))
|
||||
&& RunFunction(lastT->getWrapperFD()) < kExeFirstError)
|
||||
return Interpreter::kSuccess;
|
||||
}
|
||||
|
||||
@ -451,25 +451,35 @@ namespace cling {
|
||||
input.append("\n;\n}");
|
||||
}
|
||||
|
||||
bool Interpreter::RunFunction(const FunctionDecl* FD,
|
||||
StoredValueRef* res /*=0*/) {
|
||||
Interpreter::ExecutionResult
|
||||
Interpreter::RunFunction(const FunctionDecl* FD, StoredValueRef* res /*=0*/) {
|
||||
if (getCI()->getDiagnostics().hasErrorOccurred())
|
||||
return false;
|
||||
return kExeCompilationError;
|
||||
|
||||
if (!m_IncrParser->hasCodeGenerator()) {
|
||||
return true;
|
||||
return kExeNoCodeGen;
|
||||
}
|
||||
|
||||
if (!FD)
|
||||
return false;
|
||||
return kExeUnkownFunction;
|
||||
|
||||
std::string mangledNameIfNeeded;
|
||||
mangleName(FD, mangledNameIfNeeded);
|
||||
m_ExecutionContext->executeFunction(mangledNameIfNeeded.c_str(),
|
||||
getCI()->getASTContext(),
|
||||
FD->getResultType(), res);
|
||||
// FIXME: Probably we need better handling of the error case.
|
||||
return true;
|
||||
ExecutionContext::ExecutionResult ExeRes =
|
||||
m_ExecutionContext->executeFunction(mangledNameIfNeeded.c_str(),
|
||||
getCI()->getASTContext(),
|
||||
FD->getResultType(), res);
|
||||
switch (ExeRes) {
|
||||
case ExecutionContext::kExeSuccess:
|
||||
return kExeSuccess;
|
||||
case ExecutionContext::kExeFunctionNotCompiled:
|
||||
return kExeFunctionNotCompiled;
|
||||
case ExecutionContext::kExeUnresolvedSymbols:
|
||||
return kExeUnresolvedSymbols;
|
||||
default: break;
|
||||
}
|
||||
// Should not end up here...
|
||||
return kExeSuccess;
|
||||
}
|
||||
|
||||
void Interpreter::createUniqueName(std::string& out) {
|
||||
@ -533,7 +543,7 @@ namespace cling {
|
||||
const Transaction* lastT = m_IncrParser->getLastTransaction();
|
||||
|
||||
if (lastT->getState() == Transaction::kCommitted
|
||||
&& RunFunction(lastT->getWrapperFD(), V))
|
||||
&& RunFunction(lastT->getWrapperFD(), V) < kExeFirstError)
|
||||
return Interpreter::kSuccess;
|
||||
else if (V)
|
||||
*V = StoredValueRef::invalidValue();
|
||||
|
Loading…
Reference in New Issue
Block a user