Help ValuePrinter find the transaction:

If the ValuePrinter runtime header gets included,
a transaction might be emitted, and the transaction
containing the function body cannot be found anymore.
This causes roottest/root/meta/getFuncBody.C to fail
with runtime modules.
This commit is contained in:
Axel Naumann 2019-08-30 19:00:57 +02:00 committed by SFT
parent 0c880f8472
commit 6a73fd08d2
5 changed files with 37 additions and 7 deletions

View File

@ -713,6 +713,7 @@ namespace cling {
const Transaction* getFirstTransaction() const;
const Transaction* getLastTransaction() const;
const Transaction* getLastWrapperTransaction() const;
const Transaction* getCurrentTransaction() const;
///\brief Returns the current or last Transaction.

View File

@ -392,6 +392,28 @@ namespace cling {
&& (!initialized || (m_TransactionPool && m_Parser));
}
namespace {
template <class T>
struct Reversed {
const T &m_orig;
auto begin() -> decltype(m_orig.rbegin()) { return m_orig.rbegin(); }
auto end() -> decltype (m_orig.rend()) { return m_orig.rend(); }
};
template <class T>
Reversed<T> reverse(const T& orig) { return {orig}; }
}
const Transaction* IncrementalParser::getLastWrapperTransaction() const {
if (auto *T = getCurrentTransaction())
if (T->getWrapperFD())
return T;
for (auto T: reverse(m_Transactions))
if (T->getWrapperFD())
return T;
return nullptr;
}
const Transaction* IncrementalParser::getCurrentTransaction() const {
return m_Consumer->getTransaction();
}

View File

@ -187,6 +187,11 @@ namespace cling {
return m_Transactions.back();
}
///\brief Returns the most recent transaction with an input line wrapper,
/// which could well be the current one.
///
const Transaction* getLastWrapperTransaction() const;
///\brief Returns the currently active transaction.
///
const Transaction* getCurrentTransaction() const;

View File

@ -1598,6 +1598,9 @@ namespace cling {
return m_IncrParser->getLastTransaction();
}
const Transaction* Interpreter::getLastWrapperTransaction() const {
return m_IncrParser->getLastWrapperTransaction();
}
const Transaction* Interpreter::getCurrentTransaction() const {
return m_IncrParser->getCurrentTransaction();
}

View File

@ -723,17 +723,16 @@ static std::string printEnumValue(const Value &V) {
return enumString.str();
}
static std::string printFunctionValue(const Value &V, const void *ptr, clang::QualType Ty) {
static std::string printFunctionValue(const Value &V, const void *ptr,
clang::QualType Ty) {
cling::largestream o;
o << "Function @" << ptr;
// If a function is the first thing printed in a session,
// getLastTransaction() will point to the transaction that loaded the
// ValuePrinter, and won't have a wrapper FD.
// Even if it did have one it wouldn't be the one that was requested to print.
Interpreter &Interp = *const_cast<Interpreter *>(V.getInterpreter());
const Transaction *T = Interp.getLastTransaction();
const Transaction *T = Interp.getLastWrapperTransaction();
if (!T)
return o.str();
if (clang::FunctionDecl *WrapperFD = T->getWrapperFD()) {
clang::ASTContext &C = V.getASTContext();
const clang::FunctionDecl *FD = nullptr;