The callback class implements LookupObject callback, which should be called even

no dynamic scopes are involved. The information about a failed lookup comes from 
slightly different channel - ExternalSemaSource (if attached to sema).

In order to make the callback LookupObject work when we attach an arbitrary 
callback class we should attach ExternalSemaSource to Sema as well. This require
a default implementation for an ExternalSemaSource.


git-svn-id: http://root.cern.ch/svn/root/trunk@46396 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
Vassil Vassilev 2012-10-09 10:17:19 +00:00
parent 6e341e8376
commit e75c9b1a13
2 changed files with 93 additions and 11 deletions

View File

@ -7,6 +7,10 @@
#ifndef CLING_INTERPRETER_CALLBACKS_H
#define CLING_INTERPRETER_CALLBACKS_H
#include "clang/Sema/ExternalSemaSource.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {
class LookupResult;
class Scope;
@ -14,8 +18,41 @@ namespace clang {
namespace cling {
class Interpreter;
class InterpreterCallbacks;
class InterpreterExternalSemaSource;
class Transaction;
///\brief Translates 'interesting' for the interpreter ExternalSemaSource
/// events into interpreter callbacks.
///
class InterpreterExternalSemaSource : public clang::ExternalSemaSource {
private:
///\brief The interpreter callback which are subscribed for the events.
///
/// Usually the callbacks is the owner of the class and the interpreter owns
/// the callbacks so they can't be out of sync. Eg we notifying the wrong
/// callback class.
///
InterpreterCallbacks* m_Callbacks; // we don't own it.
public:
InterpreterExternalSemaSource(InterpreterCallbacks* cb) : m_Callbacks(cb){}
~InterpreterExternalSemaSource();
/// \brief Provides last resort lookup for failed unqualified lookups.
///
/// This gets translated into InterpreterCallback's call.
///
///\param[out] R The recovered symbol.
///\param[in] S The scope in which the lookup failed.
///
///\returns true if a suitable declaration is found.
///
virtual bool LookupUnqualified(clang::LookupResult& R, clang::Scope* S);
};
/// \brief This interface provides a way to observe the actions of the
/// interpreter as it does its thing. Clients can define their hooks here to
/// implement interpreter level tools.
@ -25,16 +62,23 @@ namespace cling {
InterpreterCallbacks(){}
protected:
Interpreter* m_Interpreter;
///\brief Our interpreter instance.
///
Interpreter* m_Interpreter; // we don't own
///\brief Whether or not the callbacks are enabled.
///
bool m_Enabled;
///\brief Our custom SemaExternalSource, translating interesting events into
/// callbacks.
///
llvm::OwningPtr<InterpreterExternalSemaSource> m_SemaExternalSource;
public:
InterpreterCallbacks(Interpreter* interp, bool enabled = false)
: m_Interpreter(interp) {
setEnabled(enabled);
}
InterpreterCallbacks(Interpreter* interp, bool enabled = false);
virtual ~InterpreterCallbacks() {}
virtual ~InterpreterCallbacks();
void setEnabled(bool e = true) {
m_Enabled = e;
@ -48,9 +92,7 @@ namespace cling {
///
/// \returns true if lookup result is found and should be used.
///
virtual bool LookupObject(clang::LookupResult&, clang::Scope*) {
return false;
}
virtual bool LookupObject(clang::LookupResult&, clang::Scope*);
///\brief This callback is invoked whenever interpreter has committed new
/// portion of declarations.
@ -64,7 +106,7 @@ namespace cling {
///
///\param[out] - The transaction that was reverted.
///
virtual void TransactionUnloaded(const Transaction&) {};
virtual void TransactionUnloaded(const Transaction&) {}
};
} // end namespace cling

View File

@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author: Vassil Vassilev <vvasilev@cern.ch>
//------------------------------------------------------------------------------
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/Interpreter.h"
#include "clang/Sema/Sema.h"
namespace cling {
// pin the vtable here
InterpreterExternalSemaSource::~InterpreterExternalSemaSource() {}
bool InterpreterExternalSemaSource::LookupUnqualified(clang::LookupResult& R,
clang::Scope* S) {
if (m_Callbacks && m_Callbacks->isEnabled())
return m_Callbacks->LookupObject(R, S);
return false;
}
InterpreterCallbacks::InterpreterCallbacks(Interpreter* interp, bool enabled)
: m_Interpreter(interp), m_Enabled(enabled) {
m_SemaExternalSource.reset(new InterpreterExternalSemaSource(this));
m_Interpreter->getSema().addExternalSource(m_SemaExternalSource.get());
}
// pin the vtable here
InterpreterCallbacks::~InterpreterCallbacks() {}
bool InterpreterCallbacks::LookupObject(clang::LookupResult&, clang::Scope*) {
return false;
}
} // end namespace cling