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:
Axel Naumann 2012-11-15 20:55:43 +00:00
parent f8b1205d19
commit 7d5ed9e511
4 changed files with 66 additions and 22 deletions

View File

@ -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.
///

View File

@ -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;
}

View File

@ -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.
///

View File

@ -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();