cling/lib/Interpreter/Transaction.cpp
Vassil Vassilev 1ae610b211 Fix savannah #99234.
The issue we experienced is that we couldn't pipe the output in the terminal.
The reason is that we were using llvm::outs() which closes explicitly the file
descriptor (thanks Axel for the help debugging).
We introduce our custom stream, which keeps the file descriptor open so that
we can use it in pipes. For debugging purposes, however we use/should use llvm::errs()

The lesson learned:
DONT USE LLVM::OUTS() ANYMORE!


git-svn-id: http://root.cern.ch/svn/root/trunk@48316 27541ba8-7e3a-0410-8455-c3a389f83636
2013-01-17 15:27:14 +00:00

99 lines
3.3 KiB
C++

//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author: Vassil Vassilev <vvasielv@cern.ch>
//------------------------------------------------------------------------------
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/PrettyPrinter.h"
using namespace clang;
namespace cling {
Transaction::~Transaction() {
for (size_t i = 0; i < m_NestedTransactions.size(); ++i)
delete m_NestedTransactions[i];
}
void Transaction::append(DelayCallInfo DCI) {
// for (const_iterator I = decls_begin(), E = decls_end(); I != E; ++I) {
// if (DGR.isNull() || (*I).getAsOpaquePtr() == DGR.getAsOpaquePtr())
// return;
// }
// register the wrapper if any.
if (DCI.m_DGR.isSingleDecl()) {
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(DCI.m_DGR.getSingleDecl()))
if (utils::Analyze::IsWrapper(FD)) {
assert(!m_WrapperFD && "Two wrappers in one transaction?");
m_WrapperFD = FD;
}
}
m_DeclQueue.push_back(DCI);
}
void Transaction::append(clang::DeclGroupRef DGR) {
append(DelayCallInfo(DGR, kCCIHandleTopLevelDecl));
}
void Transaction::append(Decl* D) {
append(DeclGroupRef(D));
}
void Transaction::dump() const {
if (!size())
return;
ASTContext& C = getFirstDecl().getSingleDecl()->getASTContext();
PrintingPolicy Policy = C.getPrintingPolicy();
Policy.DumpSourceManager = &C.getSourceManager();
print(llvm::errs(), Policy, /*Indent*/0, /*PrintInstantiation*/true);
}
void Transaction::dumpPretty() const {
if (!size())
return;
ASTContext* C = 0;
if (m_WrapperFD)
C = &(m_WrapperFD->getASTContext());
if (!getFirstDecl().isNull())
C = &(getFirstDecl().getSingleDecl()->getASTContext());
PrintingPolicy Policy(C->getLangOpts());
print(llvm::errs(), Policy, /*Indent*/0, /*PrintInstantiation*/true);
}
void Transaction::print(llvm::raw_ostream& Out, const PrintingPolicy& Policy,
unsigned Indent, bool PrintInstantiation) const {
int nestedT = 0;
for (const_iterator I = decls_begin(), E = decls_end(); I != E; ++I) {
if (I->m_DGR.isNull()) {
assert(hasNestedTransactions() && "DGR is null even if no nesting?");
// print the nested decl
Out<< "\n";
Out<<"+====================================================+\n";
Out<<" Nested Transaction" << nestedT << " \n";
Out<<"+====================================================+\n";
m_NestedTransactions[nestedT++]->print(Out, Policy, Indent,
PrintInstantiation);
Out<< "\n";
Out<<"+====================================================+\n";
Out<<" End Transaction" << nestedT << " \n";
Out<<"+====================================================+\n";
}
for (DeclGroupRef::const_iterator J = I->m_DGR.begin(),
L = I->m_DGR.end(); J != L; ++J)
if (*J)
(*J)->print(Out, Policy, Indent, PrintInstantiation);
else
Out << "<<NULL DECL>>";
}
}
} // end namespace cling