2012-09-05 09:37:39 +00:00
//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author: Vassil Vassilev <vvasielv@cern.ch>
//------------------------------------------------------------------------------
2012-10-02 10:30:25 +00:00
# include "cling/Interpreter/Transaction.h"
2012-09-05 09:37:39 +00:00
2012-10-19 11:49:49 +00:00
# include "cling/Utils/AST.h"
2012-10-01 11:47:27 +00:00
# include "clang/AST/ASTContext.h"
2012-09-05 09:37:39 +00:00
# include "clang/AST/DeclBase.h"
2012-10-01 11:47:27 +00:00
# include "clang/AST/PrettyPrinter.h"
2012-09-05 09:37:39 +00:00
using namespace clang ;
namespace cling {
Transaction : : ~ Transaction ( ) {
2013-04-08 14:27:57 +00:00
if ( hasNestedTransactions ( ) )
for ( size_t i = 0 ; i < m_NestedTransactions - > size ( ) ; + + i )
delete ( * m_NestedTransactions ) [ i ] ;
2012-09-05 09:37:39 +00:00
}
2012-12-03 14:27:12 +00:00
void Transaction : : append ( DelayCallInfo DCI ) {
2013-03-11 13:11:15 +00:00
if ( getState ( ) = = kCommitting ) {
// We are committing and getting enw decls in.
// Move them into a sub transaction that will be processed
// recursively at the end of of commitTransaction.
Transaction * subTransactionWhileCommitting = 0 ;
if ( hasNestedTransactions ( )
2013-04-08 14:27:57 +00:00
& & m_NestedTransactions - > back ( ) - > getState ( ) = = kCollecting )
subTransactionWhileCommitting = m_NestedTransactions - > back ( ) ;
2013-03-11 13:11:15 +00:00
else {
// FIXME: is this correct (Axel says "yes")
CompilationOptions Opts ( getCompilationOpts ( ) ) ;
Opts . DeclarationExtraction = 0 ;
Opts . ValuePrinting = CompilationOptions : : VPDisabled ;
Opts . ResultEvaluation = 0 ;
Opts . DynamicScoping = 0 ;
subTransactionWhileCommitting
= new Transaction ( Opts , getModule ( ) ) ;
addNestedTransaction ( subTransactionWhileCommitting ) ;
}
subTransactionWhileCommitting - > append ( DCI ) ;
return ;
}
2013-04-05 13:43:01 +00:00
assert ( getState ( ) = = kCollecting | | getState ( ) = = kCompleted ) ;
2013-03-28 14:48:13 +00:00
bool checkForWrapper = ! m_WrapperFD ;
assert ( checkForWrapper = true & & " Check for wrappers with asserts " ) ;
2013-04-09 08:47:47 +00:00
// register the wrapper if any.
2013-03-28 14:48:13 +00:00
if ( checkForWrapper & & DCI . m_DGR . isSingleDecl ( ) ) {
2012-12-03 14:27:12 +00:00
if ( FunctionDecl * FD = dyn_cast < FunctionDecl > ( DCI . m_DGR . getSingleDecl ( ) ) )
2012-10-19 11:49:49 +00:00
if ( utils : : Analyze : : IsWrapper ( FD ) ) {
assert ( ! m_WrapperFD & & " Two wrappers in one transaction? " ) ;
m_WrapperFD = FD ;
}
}
2013-04-05 13:43:01 +00:00
2013-04-09 08:47:47 +00:00
// Lazy create the container on first append.
2013-04-05 13:43:01 +00:00
if ( ! m_DeclQueue )
2013-04-08 14:27:57 +00:00
m_DeclQueue . reset ( new DeclQueue ( ) ) ;
2013-04-05 13:43:01 +00:00
m_DeclQueue - > push_back ( DCI ) ;
2012-12-03 14:27:12 +00:00
}
void Transaction : : append ( clang : : DeclGroupRef DGR ) {
append ( DelayCallInfo ( DGR , kCCIHandleTopLevelDecl ) ) ;
2012-09-05 09:37:39 +00:00
}
2012-12-03 14:27:12 +00:00
void Transaction : : append ( Decl * D ) {
append ( DeclGroupRef ( D ) ) ;
2012-11-21 02:26:05 +00:00
}
2012-09-05 09:37:39 +00:00
void Transaction : : dump ( ) const {
2012-10-24 07:34:53 +00:00
if ( ! size ( ) )
return ;
2012-10-08 10:38:52 +00:00
ASTContext & C = getFirstDecl ( ) . getSingleDecl ( ) - > getASTContext ( ) ;
PrintingPolicy Policy = C . getPrintingPolicy ( ) ;
Policy . DumpSourceManager = & C . getSourceManager ( ) ;
2013-01-17 15:27:14 +00:00
print ( llvm : : errs ( ) , Policy , /*Indent*/ 0 , /*PrintInstantiation*/ true ) ;
2012-10-01 11:47:27 +00:00
}
void Transaction : : dumpPretty ( ) const {
2012-10-24 07:34:53 +00:00
if ( ! size ( ) )
return ;
2012-11-20 13:20:22 +00:00
ASTContext * C = 0 ;
2012-11-19 21:17:28 +00:00
if ( m_WrapperFD )
C = & ( m_WrapperFD - > getASTContext ( ) ) ;
if ( ! getFirstDecl ( ) . isNull ( ) )
C = & ( getFirstDecl ( ) . getSingleDecl ( ) - > getASTContext ( ) ) ;
PrintingPolicy Policy ( C - > getLangOpts ( ) ) ;
2013-01-17 15:27:14 +00:00
print ( llvm : : errs ( ) , Policy , /*Indent*/ 0 , /*PrintInstantiation*/ true ) ;
2012-10-01 11:47:27 +00:00
}
void Transaction : : print ( llvm : : raw_ostream & Out , const PrintingPolicy & Policy ,
unsigned Indent , bool PrintInstantiation ) const {
2012-09-05 09:37:39 +00:00
int nestedT = 0 ;
for ( const_iterator I = decls_begin ( ) , E = decls_end ( ) ; I ! = E ; + + I ) {
2012-12-03 14:27:12 +00:00
if ( I - > m_DGR . isNull ( ) ) {
2012-09-05 09:37:39 +00:00
assert ( hasNestedTransactions ( ) & & " DGR is null even if no nesting? " ) ;
// print the nested decl
2012-11-19 21:17:28 +00:00
Out < < " \n " ;
2012-10-01 11:47:27 +00:00
Out < < " +====================================================+ \n " ;
2012-11-19 21:17:28 +00:00
Out < < " Nested Transaction " < < nestedT < < " \n " ;
2012-10-01 11:47:27 +00:00
Out < < " +====================================================+ \n " ;
2013-04-08 14:27:57 +00:00
( * m_NestedTransactions ) [ nestedT + + ] - > print ( Out , Policy , Indent ,
PrintInstantiation ) ;
2012-11-19 21:17:28 +00:00
Out < < " \n " ;
2012-10-01 11:47:27 +00:00
Out < < " +====================================================+ \n " ;
2012-11-19 21:17:28 +00:00
Out < < " End Transaction " < < nestedT < < " \n " ;
2012-10-01 11:47:27 +00:00
Out < < " +====================================================+ \n " ;
2012-09-05 09:37:39 +00:00
}
2012-12-03 14:27:12 +00:00
for ( DeclGroupRef : : const_iterator J = I - > m_DGR . begin ( ) ,
L = I - > m_DGR . end ( ) ; J ! = L ; + + J )
2012-10-14 14:36:40 +00:00
if ( * J )
( * J ) - > print ( Out , Policy , Indent , PrintInstantiation ) ;
else
Out < < " <<NULL DECL>> " ;
2012-09-05 09:37:39 +00:00
}
}
2013-04-05 13:12:57 +00:00
void Transaction : : printStructure ( size_t nindent ) const {
static const char * const stateNames [ ] = {
" Collecting " ,
" RolledBack " ,
" RolledBackWithErrors " ,
" Committing " ,
" Committed "
} ;
std : : string indent ( nindent , ' ' ) ;
llvm : : errs ( ) < < indent < < " Transaction @ " < < this < < " : \n " ;
2013-04-08 14:35:35 +00:00
for ( const_nested_iterator I = nested_begin ( ) , E = nested_end ( ) ;
I ! = E ; + + I ) {
2013-04-05 13:12:57 +00:00
( * I ) - > printStructure ( nindent + 1 ) ;
}
llvm : : errs ( ) < < indent < < " state: " < < stateNames [ getState ( ) ] < < " , "
2013-04-05 13:43:01 +00:00
< < size ( ) < < " decl groups, "
2013-04-08 14:27:57 +00:00
< < m_NestedTransactions - > size ( ) < < " nested transactions \n "
2013-04-05 13:12:57 +00:00
< < indent < < " wrapper: " < < m_WrapperFD
< < " , parent: " < < m_Parent
< < " , next: " < < m_Next < < " \n " ;
}
2012-09-05 09:37:39 +00:00
} // end namespace cling