2012-09-05 13:37:39 +04:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author: Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------
# ifndef CLING_INCREMENTAL_PARSER_H
# define CLING_INCREMENTAL_PARSER_H
# include "DeclCollector.h"
# include "clang/AST/DeclBase.h"
# include "clang/AST/DeclGroup.h"
# include "clang/Basic/SourceLocation.h"
# include "llvm/ADT/OwningPtr.h"
# include "llvm/ADT/StringRef.h"
# include <vector>
namespace llvm {
struct GenericValue ;
class MemoryBuffer ;
}
namespace clang {
class ASTConsumer ;
class CodeGenerator ;
class CompilerInstance ;
class Decl ;
class FileID ;
class FunctionDecl ;
class Parser ;
class Sema ;
class SourceLocation ;
}
namespace cling {
2012-10-02 14:30:25 +04:00
class CompilationOptions ;
2012-09-05 13:37:39 +04:00
class CIFactory ;
class DeclCollector ;
class ExecutionContext ;
class Interpreter ;
2012-10-02 14:30:25 +04:00
class Transaction ;
2012-09-05 13:37:39 +04:00
class TransactionTransformer ;
///\brief Responsible for the incremental parsing and compilation of input.
///
/// The class manages the entire process of compilation line-by-line by
/// appending the compiled delta to clang'a AST. It provides basic operations
/// on the already compiled code. See cling::Transaction class.
///
class IncrementalParser {
private :
// our interpreter context
Interpreter * m_Interpreter ;
// compiler instance.
llvm : : OwningPtr < clang : : CompilerInstance > m_CI ;
// parser (incremental)
llvm : : OwningPtr < clang : : Parser > m_Parser ;
// One buffer for each command line, owner by the source file manager
std : : vector < llvm : : MemoryBuffer * > m_MemoryBuffers ;
// file ID of the memory buffer
clang : : FileID m_VirtualFileID ;
// CI owns it
DeclCollector * m_Consumer ;
2012-10-19 18:17:20 +04:00
///\brief The head of the single list of transactions.
2012-09-05 13:37:39 +04:00
///
2012-10-19 18:17:20 +04:00
const Transaction * m_FirstTransaction ;
///\brief The last transaction
///
Transaction * m_LastTransaction ;
2012-09-05 13:37:39 +04:00
///\brief Code generator
///
llvm : : OwningPtr < clang : : CodeGenerator > m_CodeGen ;
///\brief Contains the transaction transformers.
///
2012-10-15 17:42:09 +04:00
llvm : : SmallVector < TransactionTransformer * , 6 > m_TTransformers ;
2012-09-05 13:37:39 +04:00
public :
enum EParseResult {
kSuccess ,
kSuccessWithWarnings ,
kFailed
} ;
IncrementalParser ( Interpreter * interp , int argc , const char * const * argv ,
const char * llvmdir ) ;
~ IncrementalParser ( ) ;
clang : : CompilerInstance * getCI ( ) const { return m_CI . get ( ) ; }
clang : : Parser * getParser ( ) const { return m_Parser . get ( ) ; }
clang : : CodeGenerator * getCodeGenerator ( ) const { return m_CodeGen . get ( ) ; }
bool hasCodeGenerator ( ) const { return m_CodeGen . get ( ) ; }
/// \{
/// \name Transaction Support
///\brief Starts a transaction.
///
2012-11-15 02:06:58 +04:00
Transaction * beginTransaction ( const CompilationOptions & Opts ) ;
2012-09-05 13:37:39 +04:00
///\brief Finishes a transaction.
///
2012-11-15 02:06:58 +04:00
Transaction * endTransaction ( ) const ;
2012-09-05 13:37:39 +04:00
2012-11-15 02:06:58 +04:00
///\brief Commits a transaction if it was compete. I.e pipes it
2012-09-05 13:37:39 +04:00
/// through the consumer chain, including codegen.
///
2012-11-15 02:06:58 +04:00
void commitTransaction ( Transaction * T ) ;
2012-09-05 13:37:39 +04:00
///\brief Reverts the AST into its previous state.
///
/// If one of the declarations caused error in clang it is rolled back from
/// the AST. This is essential feature for the error recovery subsystem.
///
///\param[in] T - The transaction to be reverted from the AST
///
void rollbackTransaction ( Transaction * T ) const ;
2012-10-19 18:17:20 +04:00
///\brief Returns the first transaction the incremental parser saw.
2012-09-05 13:37:39 +04:00
///
2012-10-19 18:17:20 +04:00
const Transaction * getFirstTransaction ( ) const {
return m_FirstTransaction ;
2012-09-05 13:37:39 +04:00
}
///\brief Returns the last transaction the incremental parser saw.
///
2012-10-19 18:17:20 +04:00
Transaction * getLastTransaction ( ) {
return m_LastTransaction ;
2012-10-19 17:29:03 +04:00
}
2012-10-19 18:17:20 +04:00
///\brief Returns the last transaction the incremental parser saw.
2012-10-19 17:29:03 +04:00
///
2012-10-19 18:17:20 +04:00
const Transaction * getLastTransaction ( ) const {
return m_LastTransaction ;
2012-10-19 17:29:03 +04:00
}
2012-11-15 02:06:58 +04:00
///\brief Returns the list of transactions seen by the interpreter.
/// Intentionally makes a copy - that function is meant to be use for debug
/// purposes.
///
std : : vector < const Transaction * > getAllTransactions ( ) ;
2012-09-05 13:37:39 +04:00
/// \}
///\brief Compiles the given input with the given compilation options.
///
2012-10-15 17:42:09 +04:00
///\param[in] input - The code to compile.
///\param[in] Opts - The compilation options to use.
///\returns whether the operation was successful.
///
2012-09-05 13:37:39 +04:00
EParseResult Compile ( llvm : : StringRef input , const CompilationOptions & Opts ) ;
///\brief Parses the given input without calling the custom consumers and
/// code generation.
///
/// I.e changes to the decls in the transaction commiting it will cause
/// different executable code.
///
///\param[in] input - The code to parse.
2012-10-15 17:42:09 +04:00
///\param[in] Opts - The compilation options to use.
///\returns The transaction corresponding to the input.
2012-09-05 13:37:39 +04:00
///
2012-10-15 17:42:09 +04:00
Transaction * Parse ( llvm : : StringRef input , const CompilationOptions & Opts ) ;
2012-09-05 13:37:39 +04:00
void unloadTransaction ( Transaction * T ) ;
private :
void CreateSLocOffsetGenerator ( ) ;
EParseResult ParseInternal ( llvm : : StringRef input ) ;
} ;
} // end namespace cling
# endif // CLING_INCREMENTAL_PARSER_H