2012-09-05 13:37:39 +04:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@cern.ch>
2014-01-07 14:08:37 +04:00
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
2012-09-05 13:37:39 +04:00
//------------------------------------------------------------------------------
# ifndef CLING_INCREMENTAL_PARSER_H
# define CLING_INCREMENTAL_PARSER_H
# include "clang/Basic/SourceLocation.h"
2015-03-16 13:25:01 +03:00
# include "llvm/ADT/PointerIntPair.h"
2013-04-09 13:03:54 +04:00
# include "llvm/ADT/SmallVector.h"
2012-09-05 13:37:39 +04:00
# include "llvm/ADT/StringRef.h"
# include <vector>
2013-05-27 17:24:57 +04:00
# include <deque>
2014-08-01 16:02:15 +04:00
# include <memory>
2012-09-05 13:37:39 +04:00
namespace llvm {
struct GenericValue ;
class MemoryBuffer ;
2017-03-11 03:31:57 +03:00
class Module ;
2012-09-05 13:37:39 +04:00
}
namespace clang {
2018-07-26 13:39:04 +03:00
class ASTConsumer ;
2012-09-05 13:37:39 +04:00
class CodeGenerator ;
class CompilerInstance ;
2017-01-28 04:41:30 +03:00
class DiagnosticConsumer ;
2013-09-13 12:37:54 +04:00
class Decl ;
2012-09-05 13:37:39 +04:00
class FileID ;
2019-05-24 10:41:17 +03:00
class ModuleFileExtension ;
2012-09-05 13:37:39 +04:00
class Parser ;
}
namespace cling {
2012-10-02 14:30:25 +04:00
class CompilationOptions ;
2012-09-05 13:37:39 +04:00
class DeclCollector ;
class ExecutionContext ;
class Interpreter ;
2012-10-02 14:30:25 +04:00
class Transaction ;
2013-07-06 15:04:31 +04:00
class TransactionPool ;
2015-03-16 16:49:28 +03:00
class ASTTransformer ;
2012-09-05 13:37:39 +04:00
///\brief Responsible for the incremental parsing and compilation of input.
///
2014-08-04 06:05:42 +04:00
/// The class manages the entire process of compilation line-by-line by
2012-09-05 13:37:39 +04:00
/// 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
2013-04-09 13:04:30 +04:00
// FIXME: Get rid of that back reference to the interpreter.
2012-09-05 13:37:39 +04:00
Interpreter * m_Interpreter ;
// compiler instance.
2014-08-01 16:02:15 +04:00
std : : unique_ptr < clang : : CompilerInstance > m_CI ;
2012-09-05 13:37:39 +04:00
// parser (incremental)
2014-08-01 16:02:15 +04:00
std : : unique_ptr < clang : : Parser > m_Parser ;
2012-09-05 13:37:39 +04:00
// One buffer for each command line, owner by the source file manager
2015-01-23 18:18:01 +03:00
std : : deque < std : : pair < llvm : : MemoryBuffer * , clang : : FileID > > m_MemoryBuffers ;
2012-09-05 13:37:39 +04:00
// file ID of the memory buffer
clang : : FileID m_VirtualFileID ;
2020-02-25 19:13:44 +03:00
// The next available unique sourcelocation offset.
unsigned m_VirtualFileLocOffset = 1 ; // skip the system sloc 0.
2012-09-05 13:37:39 +04:00
// CI owns it
DeclCollector * m_Consumer ;
2013-05-27 17:24:57 +04:00
///\brief The storage for our transactions.
2012-09-05 13:37:39 +04:00
///
2013-05-27 17:24:57 +04:00
/// We don't need the elements to be contiguous in memory, that is why we
/// don't use std::vector. We don't need to copy the elements every time the
/// capacity is exceeded.
2012-10-19 18:17:20 +04:00
///
2013-05-27 17:24:57 +04:00
std : : deque < Transaction * > m_Transactions ;
2012-09-05 13:37:39 +04:00
2015-01-07 12:22:52 +03:00
///\brief Number of created modules.
2018-07-26 13:39:04 +03:00
unsigned m_ModuleNo = 0 ;
2015-01-07 12:22:52 +03:00
2012-09-05 13:37:39 +04:00
///\brief Code generator
///
2018-07-26 13:39:04 +03:00
clang : : CodeGenerator * m_CodeGen = nullptr ;
2012-09-05 13:37:39 +04:00
2013-07-06 15:04:31 +04:00
///\brief Pool of reusable block-allocated transactions.
///
2014-08-01 16:02:15 +04:00
std : : unique_ptr < TransactionPool > m_TransactionPool ;
2013-07-06 15:04:31 +04:00
2017-01-28 04:41:30 +03:00
///\brief DiagnosticConsumer instance
///
std : : unique_ptr < clang : : DiagnosticConsumer > m_DiagConsumer ;
2019-05-24 10:41:17 +03:00
using ModuleFileExtensions =
std : : vector < std : : shared_ptr < clang : : ModuleFileExtension > > ;
2012-09-05 13:37:39 +04:00
public :
enum EParseResult {
kSuccess ,
kSuccessWithWarnings ,
kFailed
} ;
2015-03-16 13:25:01 +03:00
typedef llvm : : PointerIntPair < Transaction * , 2 , EParseResult >
ParseResultTransaction ;
2019-05-24 10:41:17 +03:00
IncrementalParser ( Interpreter * interp , const char * llvmdir ,
const ModuleFileExtensions & moduleExtensions ) ;
2012-09-05 13:37:39 +04:00
~ IncrementalParser ( ) ;
2016-07-02 07:20:48 +03:00
///\brief Whether the IncrementalParser is valid.
///
///\param[in] initialized - check if IncrementalParser has been initialized.
///
bool isValid ( bool initialized = true ) const ;
bool Initialize ( llvm : : SmallVectorImpl < ParseResultTransaction > & result ,
2016-01-07 19:19:20 +03:00
bool isChildInterpreter ) ;
2012-09-05 13:37:39 +04:00
clang : : CompilerInstance * getCI ( ) const { return m_CI . get ( ) ; }
clang : : Parser * getParser ( ) const { return m_Parser . get ( ) ; }
2018-07-26 13:39:04 +03:00
clang : : CodeGenerator * getCodeGenerator ( ) const { return m_CodeGen ; }
bool hasCodeGenerator ( ) const { return m_CodeGen ; }
2020-02-25 19:13:44 +03:00
2021-07-26 16:37:35 +03:00
void setDiagnosticConsumer ( clang : : DiagnosticConsumer * Consumer , bool Own ) ;
clang : : DiagnosticConsumer * getDiagnosticConsumer ( ) const ;
2020-02-25 19:13:44 +03:00
/// Returns the next available unique source location. It is an offset into
/// the limitless virtual file. Each time this interface is used it bumps
/// an internal counter. This is very useful for using the various API in
/// clang which expect valid source locations.
clang : : SourceLocation getNextAvailableUniqueSourceLoc ( ) ;
2012-09-05 13:37:39 +04:00
/// \{
/// \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.
///
2015-03-16 13:25:01 +03:00
ParseResultTransaction endTransaction ( Transaction * T ) ;
2012-09-05 13:37:39 +04:00
2014-08-04 06:05:42 +04:00
///\brief Commits a transaction if it was complete. I.e pipes it
2012-09-05 13:37:39 +04:00
/// through the consumer chain, including codegen.
///
2017-01-29 22:39:53 +03:00
///\param[in] PRT - the transaction (ParseResultTransaction) to be
2015-03-20 17:38:44 +03:00
/// committed
2017-01-29 22:39:53 +03:00
///\param[in] ClearDiagClient - Reset the DiagnosticsEngine client or not
2013-06-20 20:37:38 +04:00
///
2017-01-29 22:39:53 +03:00
void commitTransaction ( ParseResultTransaction & PRT ,
bool ClearDiagClient = true ) ;
2013-06-25 12:51:58 +04:00
2015-03-16 13:23:01 +03:00
///\brief Runs the consumers (e.g. CodeGen) on a non-parsed transaction.
2013-06-25 12:51:58 +04:00
///
///\param[in] T - the transaction to be consumed
///
2015-03-16 13:23:01 +03:00
void emitTransaction ( Transaction * T ) ;
2012-09-05 13:37:39 +04:00
2016-06-23 20:38:57 +03:00
///\brief Remove a Transaction from the collection of Transactions.
2012-09-05 13:37:39 +04:00
///
///\param[in] T - The transaction to be reverted from the AST
///
2016-06-23 20:38:57 +03:00
void deregisterTransaction ( Transaction & T ) ;
2012-09-05 13:37:39 +04:00
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
///
2013-05-27 17:24:57 +04:00
const Transaction * getFirstTransaction ( ) const {
2015-03-20 12:48:29 +03:00
if ( m_Transactions . empty ( ) )
2013-05-27 17:24:57 +04:00
return 0 ;
return m_Transactions . front ( ) ;
2012-09-05 13:37:39 +04:00
}
///\brief Returns the last transaction the incremental parser saw.
///
2013-05-27 17:24:57 +04:00
Transaction * getLastTransaction ( ) {
2015-03-20 12:48:29 +03:00
if ( m_Transactions . empty ( ) )
2013-05-27 17:24:57 +04:00
return 0 ;
return m_Transactions . back ( ) ;
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
///
2013-05-27 17:24:57 +04:00
const Transaction * getLastTransaction ( ) const {
2015-03-20 12:48:29 +03:00
if ( m_Transactions . empty ( ) )
2013-05-27 17:24:57 +04:00
return 0 ;
return m_Transactions . back ( ) ;
2012-10-19 17:29:03 +04:00
}
2019-08-30 20:00:57 +03:00
///\brief Returns the most recent transaction with an input line wrapper,
/// which could well be the current one.
///
const Transaction * getLastWrapperTransaction ( ) const ;
2014-05-14 16:29:44 +04:00
///\brief Returns the currently active transaction.
///
const Transaction * getCurrentTransaction ( ) const ;
2015-02-10 13:19:35 +03:00
///\brief Add a user-generated transaction.
2015-02-18 16:05:30 +03:00
void addTransaction ( Transaction * T ) ;
2015-02-10 13:19:35 +03: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.
2012-11-20 07:26:52 +04:00
///\returns the declarations that were compiled.
2012-10-15 17:42:09 +04:00
///
2015-03-16 13:25:01 +03:00
ParseResultTransaction Compile ( llvm : : StringRef input , const CompilationOptions & Opts ) ;
2012-09-05 13:37:39 +04:00
2013-07-06 15:02:49 +04:00
void printTransactionStructure ( ) const ;
2012-09-05 13:37:39 +04:00
2013-06-27 16:30:07 +04:00
///\brief Runs the static initializers created by codegening a transaction.
///
///\param[in] T - the transaction for which to run the initializers.
///
bool runStaticInitOnTransaction ( Transaction * T ) const ;
2013-06-25 12:51:58 +04:00
2016-02-09 20:11:01 +03:00
///\brief Add the trnasformers to the Incremental Parser.
///
2016-04-08 16:11:17 +03:00
void SetTransformers ( bool isChildInterpreter ) ;
2016-02-09 20:11:01 +03:00
2012-09-05 13:37:39 +04:00
private :
2015-03-16 13:23:01 +03:00
///\brief Finalizes the consumers (e.g. CodeGen) on a transaction.
///
///\param[in] T - the transaction to be finalized
///
void codeGenTransaction ( Transaction * T ) ;
2013-08-22 17:52:00 +04:00
///\brief Initializes a virtual file, which will be able to produce valid
/// source locations, with the proper offsets.
///
void initializeVirtualFile ( ) ;
///\brief The work horse for parsing. It queries directly clang.
///
///\param[in] input - The incremental input that needs to be parsed.
///
2012-09-05 13:37:39 +04:00
EParseResult ParseInternal ( llvm : : StringRef input ) ;
2013-08-26 19:59:33 +04:00
2017-06-28 14:37:50 +03:00
///\brief Create a unique name for the next llvm::Module
///
std : : string makeModuleName ( ) ;
///\brief Create a new llvm::Module
///
llvm : : Module * StartModule ( ) ;
2012-09-05 13:37:39 +04:00
} ;
} // end namespace cling
# endif // CLING_INCREMENTAL_PARSER_H