Move CompilationException into Interpreter library.

InterpreterException is compiled with RTTI on, so all subclasses need to be as well.
Throwing from llvm_unreachable should be available to all clients of libInterpreter.
This commit is contained in:
Frederich Munch 2016-09-05 14:06:32 -04:00 committed by sftnight
parent e4ffea8cd4
commit 28ab61a8da
4 changed files with 44 additions and 54 deletions

View File

@ -11,7 +11,7 @@
#define CLING_RUNTIME_EXCEPTION_H
#include "llvm/Support/Compiler.h"
#include <exception>
#include <stdexcept>
namespace clang {
class Sema;
@ -48,5 +48,30 @@ namespace cling {
const char* what() const LLVM_NOEXCEPT override;
void diagnose() const override;
};
///\brief Exception that pulls cling out of runtime-compilation (llvm + clang)
/// errors.
///
/// If user code provokes an llvm::unreachable it will cause this exception
/// to be thrown. Given that this is at the process's runtime and an
/// interpreter error it inherits from InterpreterException and runtime_error.
/// Note that this exception is *not* thrown during the execution of the
/// user's code but during its compilation (at runtime).
class CompilationException: public virtual InterpreterException,
public virtual std::runtime_error {
public:
CompilationException(const std::string& reason);
~CompilationException() LLVM_NOEXCEPT;
const char* what() const LLVM_NOEXCEPT override;
// Handle fatal llvm errors by throwing an exception.
// Yes, throwing exceptions in error handlers is bad.
// Doing nothing is pretty terrible, too.
static void throwingHandler(void * /*user_data*/,
const std::string& reason,
bool /*gen_crash_diag*/);
};
} // end namespace cling
#endif // CLING_RUNTIME_EXCEPTION_H

View File

@ -1,41 +0,0 @@
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@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_COMPILATIONEXCEPTION_H
#define CLING_COMPILATIONEXCEPTION_H
#include <stdexcept>
#include <string>
#include "cling/Interpreter/Exception.h"
namespace cling {
class Interpreter;
class MetaProcessor;
///\brief Exception that pulls cling out of runtime-compilation (llvm + clang)
/// errors.
///
/// If user code provokes an llvm::unreachable it will cause this exception
/// to be thrown. Given that this is at the process's runtime and an
/// interpreter error it inherits from InterpreterException and runtime_error.
/// Note that this exception is *not* thrown during the execution of the
/// user's code but during its compilation (at runtime).
class CompilationException:
public virtual InterpreterException,
public virtual std::runtime_error {
public:
CompilationException(const std::string& reason):
std::runtime_error(reason) {}
~CompilationException() LLVM_NOEXCEPT; // vtable pinned to UserInterface.cpp
virtual const char* what() const LLVM_NOEXCEPT {
return std::runtime_error::what(); }
};
}
#endif // CLING_COMPILATIONEXCEPTION_H

View File

@ -69,4 +69,20 @@ namespace cling {
else
return "Trying to dereference null pointer or trying to call routine taking non-null arguments";
}
CompilationException::CompilationException(const std::string& reason) :
std::runtime_error(reason) {}
CompilationException::~CompilationException() LLVM_NOEXCEPT {}
const char* CompilationException::what() const LLVM_NOEXCEPT {
return std::runtime_error::what();
}
void CompilationException::throwingHandler(void * /*user_data*/,
const std::string& reason,
bool /*gen_crash_diag*/) {
throw cling::CompilationException(reason);
}
} // end namespace cling

View File

@ -9,7 +9,6 @@
#include "cling/UserInterface/UserInterface.h"
#include "cling/UserInterface/CompilationException.h"
#include "cling/Interpreter/Exception.h"
#include "cling/MetaProcessor/MetaProcessor.h"
#include "textinput/Callbacks.h"
@ -50,14 +49,7 @@
#include <memory>
namespace {
// Handle fatal llvm errors by throwing an exception.
// Yes, throwing exceptions in error handlers is bad.
// Doing nothing is pretty terrible, too.
void exceptionErrorHandler(void * /*user_data*/,
const std::string& reason,
bool /*gen_crash_diag*/) {
throw cling::CompilationException(reason);
}
#if defined(LLVM_ON_UNIX)
static void GetUserHomeDirectory(llvm::SmallVectorImpl<char>& str) {
str.clear();
@ -110,8 +102,6 @@ namespace {
}
namespace cling {
// Declared in CompilationException.h; vtable pinned here.
CompilationException::~CompilationException() LLVM_NOEXCEPT {}
UserInterface::UserInterface(Interpreter& interp) {
// We need stream that doesn't close its file descriptor, thus we are not
@ -119,7 +109,7 @@ namespace cling {
// the results in pipes (Savannah #99234).
static llvm::raw_fd_ostream m_MPOuts (STDOUT_FILENO, /*ShouldClose*/false);
m_MetaProcessor.reset(new MetaProcessor(interp, m_MPOuts));
llvm::install_fatal_error_handler(&exceptionErrorHandler);
llvm::install_fatal_error_handler(&CompilationException::throwingHandler);
}
UserInterface::~UserInterface() {}