2012-09-05 13:37:39 +04:00
//------------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------------
# include "IncrementalParser.h"
2014-03-27 20:30:09 +04:00
2013-02-27 19:28:38 +04:00
# include "AutoSynthesizer.h"
2015-02-11 23:58:21 +03:00
# include "BackendPasses.h"
2013-10-24 20:54:06 +04:00
# include "CheckEmptyTransactionTransformer.h"
2012-09-05 13:37:39 +04:00
# include "DeclCollector.h"
# include "DeclExtractor.h"
# include "DynamicLookup.h"
2015-01-07 12:22:52 +03:00
# include "IncrementalExecutor.h"
2013-07-15 00:35:00 +04:00
# include "NullDerefProtectionTransformer.h"
2014-02-18 14:34:18 +04:00
# include "ValueExtractionSynthesizer.h"
2013-08-01 14:27:40 +04:00
# include "TransactionPool.h"
2014-03-27 20:30:09 +04:00
# include "TransactionUnloader.h"
2012-09-05 13:37:39 +04:00
# include "ValuePrinterSynthesizer.h"
# include "cling/Interpreter/CIFactory.h"
# include "cling/Interpreter/Interpreter.h"
2012-10-02 14:30:25 +04:00
# include "cling/Interpreter/InterpreterCallbacks.h"
2012-10-02 14:34:22 +04:00
# include "cling/Interpreter/Transaction.h"
2012-09-05 13:37:39 +04:00
2014-01-15 18:40:52 +04:00
# include "clang/AST/Attr.h"
2012-09-05 13:37:39 +04:00
# include "clang/AST/ASTContext.h"
# include "clang/AST/Decl.h"
# include "clang/AST/DeclGroup.h"
2013-03-01 19:15:31 +04:00
# include "clang/AST/RecursiveASTVisitor.h"
2012-09-05 13:37:39 +04:00
# include "clang/Basic/FileManager.h"
# include "clang/CodeGen/ModuleBuilder.h"
# include "clang/Parse/Parser.h"
# include "clang/Lex/Preprocessor.h"
# include "clang/Frontend/CompilerInstance.h"
2014-12-02 19:43:18 +03:00
# include "clang/Sema/Sema.h"
2015-01-23 12:49:18 +03:00
# include "clang/Sema/SemaDiagnostic.h"
2012-09-05 13:37:39 +04:00
# include "clang/Serialization/ASTWriter.h"
2013-04-24 20:28:08 +04:00
# include "llvm/IR/LLVMContext.h"
# include "llvm/IR/Module.h"
2012-09-05 13:37:39 +04:00
# include "llvm/Support/CrashRecoveryContext.h"
# include "llvm/Support/MemoryBuffer.h"
# include "llvm/Support/raw_os_ostream.h"
# include <iostream>
# include <stdio.h>
# include <sstream>
2014-10-14 10:58:40 +04:00
// Include the necessary headers to interface with the Windows registry and
// environment.
# ifdef _MSC_VER
# define WIN32_LEAN_AND_MEAN
# define NOGDI
# define NOMINMAX
# include <Windows.h>
# include <sstream>
# define popen _popen
# define pclose _pclose
# pragma comment(lib, "Advapi32.lib")
# endif
2012-09-05 13:37:39 +04:00
using namespace clang ;
2014-10-14 10:58:40 +04:00
namespace {
///\brief Check the compile-time C++ ABI version vs the run-time ABI version,
/// a mismatch could cause havoc. Reports if ABI versions differ.
static void CheckABICompatibility ( clang : : CompilerInstance * CI ) {
# ifdef __GLIBCXX__
# define CLING_CXXABIV __GLIBCXX__
# define CLING_CXXABIS "__GLIBCXX__"
# elif _LIBCPP_VERSION
# define CLING_CXXABIV _LIBCPP_VERSION
# define CLING_CXXABIS "_LIBCPP_VERSION"
# elif defined (_MSC_VER)
// For MSVC we do not use CLING_CXXABI*
# else
# define CLING_CXXABIV -1 // intentionally invalid macro name
# define CLING_CXXABIS "-1" // intentionally invalid macro name
llvm : : errs ( )
< < " Warning in cling::CIFactory::createCI(): \n "
" C++ ABI check not implemented for this standard library \n " ;
return ;
# endif
# ifdef _MSC_VER
HKEY regVS ;
int VSVersion = ( _MSC_VER / 100 ) - 6 ;
std : : stringstream subKey ;
subKey < < " VisualStudio.DTE. " < < VSVersion < < " .0 " ;
if ( RegOpenKeyEx ( HKEY_CLASSES_ROOT , subKey . str ( ) . c_str ( ) , 0 , KEY_READ , & regVS ) = = ERROR_SUCCESS ) {
RegCloseKey ( regVS ) ;
}
else {
llvm : : errs ( )
< < " Warning in cling::CIFactory::createCI(): \n "
" Possible C++ standard library mismatch, compiled with Visual Studio v "
< < VSVersion < < " .0, \n "
" but this version of Visual Studio was not found in your system's registry. \n " ;
}
# else
struct EarlyReturnWarn {
bool shouldWarn = true ;
~ EarlyReturnWarn ( ) {
if ( shouldWarn ) {
llvm : : errs ( )
< < " Warning in cling::IncrementalParser::CheckABICompatibility(): \n "
" Possible C++ standard library mismatch, compiled with "
CLING_CXXABIS " v " < < CLING_CXXABIV
< < " but extraction of runtime standard library version failed. \n " ;
}
}
} warnAtReturn ;
clang : : Preprocessor & PP = CI - > getPreprocessor ( ) ;
clang : : IdentifierInfo * II = PP . getIdentifierInfo ( CLING_CXXABIS ) ;
if ( ! II )
return ;
const clang : : DefMacroDirective * MD
= llvm : : dyn_cast < clang : : DefMacroDirective > ( PP . getMacroDirective ( II ) ) ;
if ( ! MD )
return ;
const clang : : MacroInfo * MI = MD - > getMacroInfo ( ) ;
if ( ! MI | | MI - > getNumTokens ( ) ! = 1 )
return ;
const clang : : Token & Tok = * MI - > tokens_begin ( ) ;
if ( ! Tok . isLiteral ( ) )
return ;
2014-12-15 17:00:10 +03:00
if ( ! Tok . getLength ( ) | | ! Tok . getLiteralData ( ) )
2014-10-14 10:58:40 +04:00
return ;
std : : string cxxabivStr ;
{
llvm : : raw_string_ostream cxxabivStrStrm ( cxxabivStr ) ;
cxxabivStrStrm < < CLING_CXXABIV ;
}
2014-12-15 17:00:10 +03:00
llvm : : StringRef tokStr ( Tok . getLiteralData ( ) , Tok . getLength ( ) ) ;
2014-10-14 10:58:40 +04:00
warnAtReturn . shouldWarn = false ;
2014-12-15 17:00:10 +03:00
if ( ! tokStr . equals ( cxxabivStr ) ) {
2014-10-14 10:58:40 +04:00
llvm : : errs ( )
< < " Warning in cling::IncrementalParser::CheckABICompatibility(): \n "
" C++ ABI mismatch, compiled with "
CLING_CXXABIS " v " < < CLING_CXXABIV
< < " running with v " < < tokStr < < " \n " ;
}
# endif
# undef CLING_CXXABIV
# undef CLING_CXXABIS
}
} // unnamed namespace
2012-09-05 13:37:39 +04:00
namespace cling {
IncrementalParser : : IncrementalParser ( Interpreter * interp ,
int argc , const char * const * argv ,
const char * llvmdir ) :
2015-01-07 12:22:52 +03:00
m_Interpreter ( interp ) , m_Consumer ( 0 ) , m_ModuleNo ( 0 ) {
2012-09-05 13:37:39 +04:00
2013-11-18 19:49:19 +04:00
CompilerInstance * CI = CIFactory : : createCI ( " " , argc , argv , llvmdir ) ;
2012-09-05 13:37:39 +04:00
assert ( CI & & " CompilerInstance is (null)! " ) ;
2013-11-18 19:49:19 +04:00
m_Consumer = dyn_cast < DeclCollector > ( & CI - > getSema ( ) . getASTConsumer ( ) ) ;
2012-09-05 13:37:39 +04:00
assert ( m_Consumer & & " Expected ChainedConsumer! " ) ;
m_CI . reset ( CI ) ;
if ( CI - > getFrontendOpts ( ) . ProgramAction ! = clang : : frontend : : ParseSyntaxOnly ) {
2015-01-07 12:22:52 +03:00
m_CodeGen . reset ( CreateLLVMCodeGen ( CI - > getDiagnostics ( ) , " cling-module-0 " ,
2012-09-05 13:37:39 +04:00
CI - > getCodeGenOpts ( ) ,
* m_Interpreter - > getLLVMContext ( )
) ) ;
}
2013-08-22 16:11:12 +04:00
initializeVirtualFile ( ) ;
2012-09-05 13:37:39 +04:00
// Add transformers to the IncrementalParser, which owns them
2013-02-27 19:28:38 +04:00
Sema * TheSema = & CI - > getSema ( ) ;
2013-06-26 22:51:05 +04:00
// Register the AST Transformers
2013-10-11 18:23:01 +04:00
m_ASTTransformers . push_back ( new AutoSynthesizer ( TheSema ) ) ;
2013-06-26 22:51:05 +04:00
m_ASTTransformers . push_back ( new EvaluateTSynthesizer ( TheSema ) ) ;
m_ASTTransformers . push_back ( new ValuePrinterSynthesizer ( TheSema , 0 ) ) ;
m_ASTTransformers . push_back ( new DeclExtractor ( TheSema ) ) ;
2014-02-18 14:34:18 +04:00
m_ASTTransformers . push_back ( new ValueExtractionSynthesizer ( TheSema ) ) ;
2013-09-11 15:31:14 +04:00
m_ASTTransformers . push_back ( new NullDerefProtectionTransformer ( TheSema ) ) ;
2014-02-27 13:37:10 +04:00
m_ASTTransformers . push_back ( new CheckEmptyTransactionTransformer ( TheSema ) ) ;
2013-03-11 17:11:15 +04:00
}
2013-06-26 22:51:05 +04:00
2014-03-04 22:02:42 +04:00
void
IncrementalParser : : Initialize ( llvm : : SmallVectorImpl < Transaction * > & result ) {
2014-03-28 17:53:34 +04:00
m_TransactionPool . reset ( new TransactionPool ( getCI ( ) - > getSema ( ) ) ) ;
2015-02-11 23:58:21 +03:00
if ( hasCodeGenerator ( ) ) {
2013-03-11 17:11:15 +04:00
getCodeGenerator ( ) - > Initialize ( getCI ( ) - > getASTContext ( ) ) ;
2015-02-11 23:58:21 +03:00
m_BackendPasses . reset ( new BackendPasses ( getCI ( ) - > getCodeGenOpts ( ) ,
getCI ( ) - > getTargetOpts ( ) ,
getCI ( ) - > getLangOpts ( ) ) ) ;
}
2013-05-23 13:05:02 +04:00
2013-03-26 13:59:19 +04:00
CompilationOptions CO ;
CO . DeclarationExtraction = 0 ;
CO . ValuePrinting = CompilationOptions : : VPDisabled ;
CO . CodeGeneration = hasCodeGenerator ( ) ;
2013-05-23 16:44:52 +04:00
// pull in PCHs
const std : : string & PCHFileName
= m_CI - > getInvocation ( ) . getPreprocessorOpts ( ) . ImplicitPCHInclude ;
2013-03-11 17:11:15 +04:00
if ( ! PCHFileName . empty ( ) ) {
2013-04-27 03:52:55 +04:00
Transaction * CurT = beginTransaction ( CO ) ;
2013-03-11 17:11:15 +04:00
m_CI - > createPCHExternalASTSource ( PCHFileName ,
true /*DisablePCHValidation*/ ,
true /*AllowPCHWithCompilerErrors*/ ,
2014-06-06 12:19:14 +04:00
0 /*DeserializationListener*/ ,
true /*OwnsDeserializationListener*/ ) ;
2013-07-06 15:04:31 +04:00
if ( Transaction * EndedT = endTransaction ( CurT ) )
2014-03-04 22:02:42 +04:00
result . push_back ( EndedT ) ;
2013-03-11 17:11:15 +04:00
}
2012-09-05 13:37:39 +04:00
2013-04-27 03:52:55 +04:00
Transaction * CurT = beginTransaction ( CO ) ;
2013-03-11 17:11:15 +04:00
Sema * TheSema = & m_CI - > getSema ( ) ;
m_Parser . reset ( new Parser ( m_CI - > getPreprocessor ( ) , * TheSema ,
2012-09-05 13:37:39 +04:00
false /*skipFuncBodies*/ ) ) ;
2013-03-11 17:11:15 +04:00
m_CI - > getPreprocessor ( ) . EnterMainSourceFile ( ) ;
2012-09-05 13:37:39 +04:00
// Initialize the parser after we have entered the main source file.
m_Parser - > Initialize ( ) ;
// Perform initialization that occurs after the parser has been initialized
// but before it parses anything. Initializes the consumers too.
2013-08-19 17:48:00 +04:00
// No - already done by m_Parser->Initialize().
// TheSema->Initialize();
2013-03-11 17:11:15 +04:00
ExternalASTSource * External = TheSema - > getASTContext ( ) . getExternalSource ( ) ;
if ( External )
External - > StartTranslationUnit ( m_Consumer ) ;
2013-04-27 03:52:55 +04:00
2014-10-14 10:58:40 +04:00
// <new> is needed by the ValuePrinter so it's a good thing to include it.
// We need to include it to determine the version number of the standard
// library implementation.
ParseInternal ( " #include <new> " ) ;
CheckABICompatibility ( m_CI . get ( ) ) ;
2014-03-24 00:08:48 +04:00
// DO NOT commit the transactions here: static initialization in these
// transactions requires gCling through local_cxa_atexit(), but that has not
// been defined yet!
2013-07-06 15:04:31 +04:00
if ( Transaction * EndedT = endTransaction ( CurT ) )
2014-03-04 22:02:42 +04:00
result . push_back ( EndedT ) ;
2012-09-05 13:37:39 +04:00
}
2014-05-14 16:29:44 +04:00
const Transaction * IncrementalParser : : getCurrentTransaction ( ) const {
return m_Consumer - > getTransaction ( ) ;
}
2014-04-01 18:44:59 +04:00
SourceLocation IncrementalParser : : getLastMemoryBufferEndLoc ( ) const {
const SourceManager & SM = getCI ( ) - > getSourceManager ( ) ;
SourceLocation Result = SM . getLocForStartOfFile ( m_VirtualFileID ) ;
return Result . getLocWithOffset ( m_MemoryBuffers . size ( ) + 1 ) ;
}
2012-09-05 13:37:39 +04:00
IncrementalParser : : ~ IncrementalParser ( ) {
2012-11-20 17:21:00 +04:00
const Transaction * T = getFirstTransaction ( ) ;
const Transaction * nextT = 0 ;
while ( T ) {
2013-09-15 22:18:49 +04:00
assert ( ( T - > getState ( ) = = Transaction : : kCommitted
2014-08-04 06:05:42 +04:00
| | T - > getState ( ) = = Transaction : : kRolledBackWithErrors
2013-11-27 17:28:40 +04:00
| | T - > getState ( ) = = Transaction : : kNumStates // reset from the pool
2013-06-17 14:45:18 +04:00
| | T - > getState ( ) = = Transaction : : kRolledBack )
& & " Not committed? " ) ;
2012-11-20 17:21:00 +04:00
nextT = T - > getNext ( ) ;
delete T ;
T = nextT ;
}
2013-06-26 22:51:05 +04:00
for ( size_t i = 0 ; i < m_ASTTransformers . size ( ) ; + + i )
delete m_ASTTransformers [ i ] ;
for ( size_t i = 0 ; i < m_IRTransformers . size ( ) ; + + i )
delete m_IRTransformers [ i ] ;
2012-09-05 13:37:39 +04:00
}
2014-08-04 06:05:42 +04:00
Transaction * IncrementalParser : : beginTransaction ( const CompilationOptions &
2012-11-15 02:06:58 +04:00
Opts ) {
2012-09-05 13:37:39 +04:00
Transaction * OldCurT = m_Consumer - > getTransaction ( ) ;
2013-07-06 15:04:31 +04:00
Transaction * NewCurT = m_TransactionPool - > takeTransaction ( ) ;
NewCurT - > setCompilationOpts ( Opts ) ;
2014-08-04 06:05:42 +04:00
// If we are in the middle of transaction and we see another begin
2012-09-05 13:37:39 +04:00
// transaction - it must be nested transaction.
2014-08-04 06:05:42 +04:00
if ( OldCurT & & OldCurT ! = NewCurT
2013-08-04 20:17:41 +04:00
& & ( OldCurT - > getState ( ) = = Transaction : : kCollecting
| | OldCurT - > getState ( ) = = Transaction : : kCompleted ) ) {
2013-07-06 15:04:31 +04:00
OldCurT - > addNestedTransaction ( NewCurT ) ; // takes the ownership
2012-09-05 13:37:39 +04:00
}
2013-04-24 10:55:38 +04:00
m_Consumer - > setTransaction ( NewCurT ) ;
2012-11-15 02:06:58 +04:00
return NewCurT ;
2012-09-05 13:37:39 +04:00
}
2013-07-06 15:04:31 +04:00
Transaction * IncrementalParser : : endTransaction ( Transaction * T ) {
2013-04-27 03:52:55 +04:00
assert ( T & & " Null transaction!? " ) ;
assert ( T - > getState ( ) = = Transaction : : kCollecting ) ;
2013-06-27 14:34:05 +04:00
# ifndef NDEBUG
if ( T - > hasNestedTransactions ( ) ) {
for ( Transaction : : const_nested_iterator I = T - > nested_begin ( ) ,
E = T - > nested_end ( ) ; I ! = E ; + + I )
assert ( ( * I ) - > isCompleted ( ) & & " Nested transaction not completed!? " ) ;
}
# endif
2013-04-27 03:52:55 +04:00
T - > setState ( Transaction : : kCompleted ) ;
2013-07-06 15:04:31 +04:00
// Empty transaction send it back to the pool.
if ( T - > empty ( ) ) {
2014-08-04 06:05:42 +04:00
assert ( ( ! m_Consumer - > getTransaction ( )
2013-08-05 17:15:37 +04:00
| | ( m_Consumer - > getTransaction ( ) = = T ) )
2013-08-04 20:18:27 +04:00
& & " Cannot release different T " ) ;
2014-08-04 06:05:42 +04:00
// If a nested transaction the active one should be its parent
2013-08-04 20:18:27 +04:00
// from now on. FIXME: Merge conditional with commitTransaction
if ( T - > isNestedTransaction ( ) )
m_Consumer - > setTransaction ( T - > getParent ( ) ) ;
else
m_Consumer - > setTransaction ( ( Transaction * ) 0 ) ;
2013-07-06 15:04:31 +04:00
m_TransactionPool - > releaseTransaction ( T ) ;
return 0 ;
}
2014-08-04 06:05:42 +04:00
2013-10-24 20:54:06 +04:00
transformTransactionAST ( T ) ;
if ( T - > empty ( ) ) {
m_TransactionPool - > releaseTransaction ( T ) ;
return 0 ;
}
2013-07-06 15:04:31 +04:00
2012-09-05 13:37:39 +04:00
const DiagnosticsEngine & Diags = getCI ( ) - > getSema ( ) . getDiagnostics ( ) ;
//TODO: Make the enum orable.
if ( Diags . getNumWarnings ( ) > 0 )
2013-04-27 03:52:55 +04:00
T - > setIssuedDiags ( Transaction : : kWarnings ) ;
2012-09-05 13:37:39 +04:00
if ( Diags . hasErrorOccurred ( ) | | Diags . hasFatalErrorOccurred ( ) )
2013-04-27 03:52:55 +04:00
T - > setIssuedDiags ( Transaction : : kErrors ) ;
2012-09-05 13:37:39 +04:00
2013-07-06 15:04:31 +04:00
if ( ! T - > isNestedTransaction ( ) & & T ! = getLastTransaction ( ) ) {
if ( getLastTransaction ( ) )
m_Transactions . back ( ) - > setNext ( T ) ;
m_Transactions . push_back ( T ) ;
}
2013-04-27 03:52:55 +04:00
return T ;
2012-09-05 13:37:39 +04:00
}
2013-06-25 12:51:58 +04:00
void IncrementalParser : : commitTransaction ( Transaction * T ) {
2012-11-15 02:06:58 +04:00
//Transaction* CurT = m_Consumer->getTransaction();
assert ( T - > isCompleted ( ) & & " Transaction not ended!? " ) ;
2013-04-09 19:30:16 +04:00
assert ( T - > getState ( ) ! = Transaction : : kCommitted
& & " Committing an already committed transaction. " ) ;
2013-07-06 15:04:31 +04:00
assert ( ! T - > empty ( ) & & " Transactions must not be empty; " ) ;
2012-09-05 13:37:39 +04:00
2013-06-25 11:19:15 +04:00
// If committing a nested transaction the active one should be its parent
// from now on.
2013-06-25 12:51:58 +04:00
if ( T - > isNestedTransaction ( ) )
2013-06-25 11:19:15 +04:00
m_Consumer - > setTransaction ( T - > getParent ( ) ) ;
2012-09-05 13:37:39 +04:00
// Check for errors...
2012-11-15 02:06:58 +04:00
if ( T - > getIssuedDiags ( ) = = Transaction : : kErrors ) {
rollbackTransaction ( T ) ;
2012-09-05 13:37:39 +04:00
return ;
}
2012-11-15 02:06:58 +04:00
if ( T - > hasNestedTransactions ( ) ) {
2013-07-06 15:03:21 +04:00
for ( Transaction : : const_nested_iterator I = T - > nested_begin ( ) ,
2013-04-08 18:35:35 +04:00
E = T - > nested_end ( ) ; I ! = E ; + + I )
2013-04-09 19:30:16 +04:00
if ( ( * I ) - > getState ( ) ! = Transaction : : kCommitted )
commitTransaction ( * I ) ;
2012-11-15 02:06:58 +04:00
}
2013-07-06 15:01:48 +04:00
// If there was an error coming from the transformers.
if ( T - > getIssuedDiags ( ) = = Transaction : : kErrors ) {
rollbackTransaction ( T ) ;
2013-06-25 12:51:58 +04:00
return ;
2013-07-06 15:01:48 +04:00
}
2012-09-05 13:37:39 +04:00
2013-06-13 16:53:58 +04:00
// Here we expect a template instantiation. We need to open the transaction
// that we are currently work with.
2013-07-06 15:04:31 +04:00
{
2014-04-16 13:59:36 +04:00
Transaction * prevConsumerT = m_Consumer - > getTransaction ( ) ;
m_Consumer - > setTransaction ( T ) ;
2013-07-06 15:04:31 +04:00
Transaction * nestedT = beginTransaction ( CompilationOptions ( ) ) ;
// Pull all template instantiations in that came from the consumers.
getCI ( ) - > getSema ( ) . PerformPendingInstantiations ( ) ;
if ( Transaction * T = endTransaction ( nestedT ) )
commitTransaction ( T ) ;
2014-04-16 13:59:36 +04:00
m_Consumer - > setTransaction ( prevConsumerT ) ;
2013-07-06 15:04:31 +04:00
}
2013-06-13 16:53:58 +04:00
m_Consumer - > HandleTranslationUnit ( getCI ( ) - > getASTContext ( ) ) ;
2013-04-10 19:15:49 +04:00
2013-06-25 12:51:58 +04:00
// The static initializers might run anything and can thus cause more
// decls that need to end up in a transaction. But this one is done
// with CodeGen...
2013-07-06 15:04:31 +04:00
if ( T - > getCompilationOpts ( ) . CodeGeneration & & hasCodeGenerator ( ) ) {
2014-04-16 13:59:36 +04:00
Transaction * prevConsumerT = m_Consumer - > getTransaction ( ) ;
m_Consumer - > setTransaction ( T ) ;
2013-07-06 15:04:31 +04:00
codeGenTransaction ( T ) ;
transformTransactionIR ( T ) ;
T - > setState ( Transaction : : kCommitted ) ;
2014-04-16 14:01:44 +04:00
if ( ! T - > getParent ( ) ) {
2015-02-03 23:32:09 +03:00
if ( m_Interpreter - > executeTransaction ( * T )
2014-04-16 14:01:44 +04:00
> = Interpreter : : kExeFirstError ) {
2015-01-09 11:42:00 +03:00
// Roll back on error in initializers
//assert(0 && "Error on inits.");
rollbackTransaction ( T ) ;
T - > setState ( Transaction : : kRolledBackWithErrors ) ;
2014-04-16 14:01:44 +04:00
return ;
}
2013-07-06 15:04:31 +04:00
}
2014-04-16 13:59:36 +04:00
m_Consumer - > setTransaction ( prevConsumerT ) ;
2013-07-06 15:04:31 +04:00
}
2013-06-25 12:51:58 +04:00
T - > setState ( Transaction : : kCommitted ) ;
2013-04-09 19:30:16 +04:00
2013-08-02 18:20:54 +04:00
if ( InterpreterCallbacks * callbacks = m_Interpreter - > getCallbacks ( ) )
2013-06-25 12:51:58 +04:00
callbacks - > TransactionCommitted ( * T ) ;
2013-08-02 18:20:54 +04:00
2012-09-05 13:37:39 +04:00
}
2013-06-27 16:30:07 +04:00
void IncrementalParser : : markWholeTransactionAsUsed ( Transaction * T ) const {
2014-03-28 17:53:34 +04:00
ASTContext & C = m_CI - > getASTContext ( ) ;
2013-11-25 17:26:15 +04:00
for ( Transaction : : const_iterator I = T - > decls_begin ( ) , E = T - > decls_end ( ) ;
I ! = E ; + + I ) {
// Copy DCI; it might get relocated below.
Transaction : : DelayCallInfo DCI = * I ;
2013-06-25 12:51:58 +04:00
// FIXME: implement for multiple decls in a DGR.
2013-11-25 17:26:15 +04:00
assert ( DCI . m_DGR . isSingleDecl ( ) ) ;
Decl * D = DCI . m_DGR . getSingleDecl ( ) ;
2013-06-25 12:51:58 +04:00
if ( ! D - > hasAttr < clang : : UsedAttr > ( ) )
D - > addAttr ( : : new ( D - > getASTContext ( ) )
clang : : UsedAttr ( D - > getSourceRange ( ) , D - > getASTContext ( ) ,
0 /*AttributeSpellingListIndex*/ ) ) ;
}
2014-08-04 06:05:42 +04:00
for ( Transaction : : iterator I = T - > deserialized_decls_begin ( ) ,
2013-08-07 16:26:15 +04:00
E = T - > deserialized_decls_end ( ) ; I ! = E ; + + I ) {
// FIXME: implement for multiple decls in a DGR.
assert ( I - > m_DGR . isSingleDecl ( ) ) ;
Decl * D = I - > m_DGR . getSingleDecl ( ) ;
if ( ! D - > hasAttr < clang : : UsedAttr > ( ) )
D - > addAttr ( : : new ( C ) clang : : UsedAttr ( D - > getSourceRange ( ) , C ,
0 /*AttributeSpellingListIndex*/ ) ) ;
}
2013-06-25 12:51:58 +04:00
}
void IncrementalParser : : codeGenTransaction ( Transaction * T ) {
// codegen the transaction
assert ( T - > getCompilationOpts ( ) . CodeGeneration & & " CodeGen turned off " ) ;
2013-07-31 11:04:30 +04:00
assert ( T - > getState ( ) = = Transaction : : kCompleted & & " Must be completed " ) ;
2013-06-25 12:51:58 +04:00
assert ( hasCodeGenerator ( ) & & " No CodeGen " ) ;
2013-08-04 20:39:41 +04:00
// Could trigger derserialization of decls.
Transaction * deserT = beginTransaction ( CompilationOptions ( ) ) ;
2013-11-25 17:26:15 +04:00
for ( Transaction : : const_iterator TI = T - > decls_begin ( ) , TE = T - > decls_end ( ) ;
TI ! = TE ; + + TI ) {
2013-06-25 12:51:58 +04:00
// Copy DCI; it might get relocated below.
2013-11-25 17:26:15 +04:00
Transaction : : DelayCallInfo I = * TI ;
2013-06-25 12:51:58 +04:00
if ( I . m_Call = = Transaction : : kCCIHandleTopLevelDecl )
getCodeGenerator ( ) - > HandleTopLevelDecl ( I . m_DGR ) ;
else if ( I . m_Call = = Transaction : : kCCIHandleInterestingDecl ) {
// Usually through BackendConsumer which doesn't implement
// HandleInterestingDecl() and thus calls
// ASTConsumer::HandleInterestingDecl()
getCodeGenerator ( ) - > HandleTopLevelDecl ( I . m_DGR ) ;
} else if ( I . m_Call = = Transaction : : kCCIHandleTagDeclDefinition ) {
TagDecl * TD = cast < TagDecl > ( I . m_DGR . getSingleDecl ( ) ) ;
getCodeGenerator ( ) - > HandleTagDeclDefinition ( TD ) ;
}
else if ( I . m_Call = = Transaction : : kCCIHandleVTable ) {
CXXRecordDecl * CXXRD = cast < CXXRecordDecl > ( I . m_DGR . getSingleDecl ( ) ) ;
2015-01-21 15:29:31 +03:00
getCodeGenerator ( ) - > HandleVTable ( CXXRD ) ;
2013-06-25 12:51:58 +04:00
}
else if ( I . m_Call
= = Transaction : : kCCIHandleCXXImplicitFunctionInstantiation ) {
FunctionDecl * FD = cast < FunctionDecl > ( I . m_DGR . getSingleDecl ( ) ) ;
getCodeGenerator ( ) - > HandleCXXImplicitFunctionInstantiation ( FD ) ;
}
else if ( I . m_Call
= = Transaction : : kCCIHandleCXXStaticMemberVarInstantiation ) {
VarDecl * VD = cast < VarDecl > ( I . m_DGR . getSingleDecl ( ) ) ;
getCodeGenerator ( ) - > HandleCXXStaticMemberVarInstantiation ( VD ) ;
}
2014-01-29 18:48:13 +04:00
else if ( I . m_Call = = Transaction : : kCCICompleteTentativeDefinition ) {
VarDecl * VD = cast < VarDecl > ( I . m_DGR . getSingleDecl ( ) ) ;
getCodeGenerator ( ) - > CompleteTentativeDefinition ( VD ) ;
}
2013-06-25 12:51:58 +04:00
else if ( I . m_Call = = Transaction : : kCCINone )
; // We use that internally as delimiter in the Transaction.
else
llvm_unreachable ( " We shouldn't have decl without call info. " ) ;
}
2013-08-26 19:59:33 +04:00
// Treat the deserialized decls differently.
2014-08-04 06:05:42 +04:00
for ( Transaction : : iterator I = T - > deserialized_decls_begin ( ) ,
2013-08-07 16:26:15 +04:00
E = T - > deserialized_decls_end ( ) ; I ! = E ; + + I ) {
2013-08-26 19:59:33 +04:00
2013-09-13 12:37:54 +04:00
for ( DeclGroupRef : : iterator DI = I - > m_DGR . begin ( ) , DE = I - > m_DGR . end ( ) ;
DI ! = DE ; + + DI ) {
DeclGroupRef SplitDGR ( * DI ) ;
if ( I - > m_Call = = Transaction : : kCCIHandleTopLevelDecl ) {
// FIXME: The special namespace treatment (not sending itself to
// CodeGen, but only its content - if the contained decl should be
// emitted) works around issue with the static initialization when
// having a PCH and loading a library. We don't want to generate
// code for the static that will come through the library.
//
// This will be fixed with the clang::Modules. Make sure we remember.
assert ( ! getCI ( ) - > getLangOpts ( ) . Modules & & " Please revisit! " ) ;
2013-08-26 19:59:33 +04:00
if ( NamespaceDecl * ND = dyn_cast < NamespaceDecl > ( * DI ) ) {
2014-12-10 11:16:54 +03:00
for ( NamespaceDecl : : decl_iterator NDI = ND - > decls_begin ( ) ,
EN = ND - > decls_end ( ) ; NDI ! = EN ; + + NDI ) {
2013-08-26 19:59:33 +04:00
// Recurse over decls inside the namespace, like
// CodeGenModule::EmitNamespace() does.
2014-12-10 11:16:54 +03:00
if ( ! shouldIgnore ( * NDI ) )
getCodeGenerator ( ) - > HandleTopLevelDecl ( DeclGroupRef ( * NDI ) ) ;
2013-08-26 19:59:33 +04:00
}
2013-09-13 12:37:54 +04:00
} else if ( ! shouldIgnore ( * DI ) ) {
getCodeGenerator ( ) - > HandleTopLevelDecl ( SplitDGR ) ;
2013-08-26 19:59:33 +04:00
}
continue ;
2013-09-13 12:37:54 +04:00
} // HandleTopLevel
2013-08-26 19:59:33 +04:00
2013-09-13 12:37:54 +04:00
if ( shouldIgnore ( * DI ) )
continue ;
if ( I - > m_Call = = Transaction : : kCCIHandleInterestingDecl ) {
// Usually through BackendConsumer which doesn't implement
// HandleInterestingDecl() and thus calls
// ASTConsumer::HandleInterestingDecl()
getCodeGenerator ( ) - > HandleTopLevelDecl ( SplitDGR ) ;
} else if ( I - > m_Call = = Transaction : : kCCIHandleTagDeclDefinition ) {
TagDecl * TD = cast < TagDecl > ( * DI ) ;
getCodeGenerator ( ) - > HandleTagDeclDefinition ( TD ) ;
}
else if ( I - > m_Call = = Transaction : : kCCIHandleVTable ) {
CXXRecordDecl * CXXRD = cast < CXXRecordDecl > ( * DI ) ;
2015-01-21 15:29:31 +03:00
getCodeGenerator ( ) - > HandleVTable ( CXXRD ) ;
2013-09-13 12:37:54 +04:00
}
else if ( I - > m_Call
= = Transaction : : kCCIHandleCXXImplicitFunctionInstantiation ) {
FunctionDecl * FD = cast < FunctionDecl > ( * DI ) ;
getCodeGenerator ( ) - > HandleCXXImplicitFunctionInstantiation ( FD ) ;
}
else if ( I - > m_Call
= = Transaction : : kCCIHandleCXXStaticMemberVarInstantiation ) {
VarDecl * VD = cast < VarDecl > ( * DI ) ;
getCodeGenerator ( ) - > HandleCXXStaticMemberVarInstantiation ( VD ) ;
}
2014-01-29 18:48:13 +04:00
else if ( I - > m_Call = = Transaction : : kCCICompleteTentativeDefinition ) {
VarDecl * VD = cast < VarDecl > ( I - > m_DGR . getSingleDecl ( ) ) ;
getCodeGenerator ( ) - > CompleteTentativeDefinition ( VD ) ;
}
2013-09-13 12:37:54 +04:00
else if ( I - > m_Call = = Transaction : : kCCINone )
; // We use that internally as delimiter in the Transaction.
else
llvm_unreachable ( " We shouldn't have decl without call info. " ) ;
} // for decls in DGR
} // for deserialized DGRs
2013-08-07 16:26:15 +04:00
2015-02-03 23:32:09 +03:00
// The initializers are emitted to the symbol "_GLOBAL__sub_I_" + filename.
// Make that unique!
ASTContext & Context = getCI ( ) - > getASTContext ( ) ;
SourceManager & SM = Context . getSourceManager ( ) ;
const FileEntry * MainFile = SM . getFileEntryForID ( SM . getMainFileID ( ) ) ;
FileEntry * NcMainFile = const_cast < FileEntry * > ( MainFile ) ;
// Hack to temporarily set the file entry's name to a unique name.
assert ( MainFile - > getName ( ) = = * ( const char * * ) MainFile
& & " FileEntry does not start with the name " ) ;
const char * & FileName = * ( const char * * ) NcMainFile ;
const char * OldName = FileName ;
std : : string ModName = getCodeGenerator ( ) - > GetModule ( ) - > getName ( ) . str ( ) ;
FileName = ModName . c_str ( ) ;
getCodeGenerator ( ) - > HandleTranslationUnit ( Context ) ;
FileName = OldName ;
2015-01-07 12:22:52 +03:00
2015-02-04 17:34:59 +03:00
// Commit this transaction first - T might need symbols from it, so
// trigger emission of weak symbols by providing use.
if ( ( deserT = endTransaction ( deserT ) ) )
commitTransaction ( deserT ) ;
2015-01-07 12:22:52 +03:00
// This llvm::Module is done; finalize it and pass it to the execution
// engine.
if ( ! T - > isNestedTransaction ( ) & & hasCodeGenerator ( ) ) {
2015-01-15 17:13:14 +03:00
std : : unique_ptr < llvm : : Module > M ( getCodeGenerator ( ) - > ReleaseModule ( ) ) ;
2015-02-03 23:32:09 +03:00
2015-01-15 17:13:14 +03:00
if ( M ) {
2015-02-10 13:13:59 +03:00
m_Interpreter - > addModule ( M . get ( ) ) ;
2015-02-03 23:32:09 +03:00
T - > setModule ( std : : move ( M ) ) ;
2015-01-07 12:22:52 +03:00
}
// Create a new module.
std : : string ModuleName ;
{
llvm : : raw_string_ostream strm ( ModuleName ) ;
strm < < " cling-module- " < < + + m_ModuleNo ;
}
getCodeGenerator ( ) - > StartModule ( ModuleName ,
* m_Interpreter - > getLLVMContext ( ) ) ;
}
2013-06-25 12:51:58 +04:00
}
2013-08-08 13:22:29 +04:00
void IncrementalParser : : transformTransactionAST ( Transaction * T ) {
2013-06-27 16:30:07 +04:00
bool success = true ;
// We are sure it's safe to pipe it through the transformers
2013-08-08 13:22:29 +04:00
// Consume late transformers init
Transaction * initT = beginTransaction ( CompilationOptions ( ) ) ;
2013-06-27 16:30:07 +04:00
for ( size_t i = 0 ; success & & i < m_ASTTransformers . size ( ) ; + + i )
success = m_ASTTransformers [ i ] - > TransformTransaction ( * T ) ;
2013-08-08 13:22:29 +04:00
if ( endTransaction ( initT ) )
commitTransaction ( initT ) ;
2013-06-27 16:30:07 +04:00
if ( ! success )
2013-07-06 15:01:48 +04:00
T - > setIssuedDiags ( Transaction : : kErrors ) ;
2013-06-25 12:51:58 +04:00
}
2014-03-24 15:02:41 +04:00
bool IncrementalParser : : transformTransactionIR ( Transaction * T ) {
2013-06-25 12:51:58 +04:00
// Transform IR
2013-06-27 16:30:07 +04:00
bool success = true ;
for ( size_t i = 0 ; success & & i < m_IRTransformers . size ( ) ; + + i )
2013-06-25 12:51:58 +04:00
success = m_IRTransformers [ i ] - > TransformTransaction ( * T ) ;
2013-06-27 16:30:07 +04:00
if ( ! success )
rollbackTransaction ( T ) ;
2015-02-11 23:58:21 +03:00
if ( m_BackendPasses & & T - > getModule ( ) )
m_BackendPasses - > runOnModule ( * T - > getModule ( ) ) ;
2013-06-27 16:30:07 +04:00
return success ;
2013-06-25 12:51:58 +04:00
}
2014-03-24 15:02:41 +04:00
void IncrementalParser : : rollbackTransaction ( Transaction * T ) {
assert ( T & & " Must have value " ) ;
assert ( T = = getLastTransaction ( ) & & " We always must revert the last T " ) ;
assert ( ( T - > getState ( ) ! = Transaction : : kRolledBack | |
T - > getState ( ) ! = Transaction : : kRolledBackWithErrors ) & &
" Transaction already rolled back. " ) ;
2013-12-02 13:49:37 +04:00
if ( m_Interpreter - > getOptions ( ) . ErrorOut )
return ;
2014-03-24 15:02:41 +04:00
2015-02-03 23:32:09 +03:00
TransactionUnloader U ( & getCI ( ) - > getSema ( ) , m_CodeGen . get ( ) ) ;
2012-09-05 13:37:39 +04:00
2014-03-27 20:30:09 +04:00
if ( U . RevertTransaction ( T ) )
2012-09-05 13:37:39 +04:00
T - > setState ( Transaction : : kRolledBack ) ;
else
T - > setState ( Transaction : : kRolledBackWithErrors ) ;
2014-03-24 15:02:41 +04:00
// Remove from the queue
m_Transactions . pop_back ( ) ;
//m_TransactionPool->releaseTransaction(T);
2012-09-05 13:37:39 +04:00
}
2012-11-15 02:06:58 +04:00
std : : vector < const Transaction * > IncrementalParser : : getAllTransactions ( ) {
2013-08-18 12:48:11 +04:00
std : : vector < const Transaction * > result ( m_Transactions . size ( ) ) ;
2012-11-15 02:06:58 +04:00
const cling : : Transaction * T = getFirstTransaction ( ) ;
while ( T ) {
result . push_back ( T ) ;
T = T - > getNext ( ) ;
}
return result ;
}
2012-09-05 13:37:39 +04:00
// Each input line is contained in separate memory buffer. The SourceManager
// assigns sort-of invalid FileID for each buffer, i.e there is no FileEntry
// for the MemoryBuffer's FileID. That in turn is problem because invalid
// SourceLocations are given to the diagnostics. Thus the diagnostics cannot
// order the overloads, for example
//
// Our work-around is creating a virtual file, which doesn't exist on the disk
// with enormous size (no allocation is done). That file has valid FileEntry
// and so on... We use it for generating valid SourceLocations with valid
// offsets so that it doesn't cause any troubles to the diagnostics.
//
// +---------------------+
// | Main memory buffer |
// +---------------------+
// | Virtual file SLoc |
// | address space |<-----------------+
// | ... |<------------+ |
// | ... | | |
// | ... |<----+ | |
// | ... | | | |
// +~~~~~~~~~~~~~~~~~~~~~+ | | |
// | input_line_1 | ....+.......+..--+
// +---------------------+ | |
// | input_line_2 | ....+.....--+
// +---------------------+ |
// | ... | |
// +---------------------+ |
// | input_line_N | ..--+
// +---------------------+
//
2013-08-22 16:11:12 +04:00
void IncrementalParser : : initializeVirtualFile ( ) {
2012-09-05 13:37:39 +04:00
SourceManager & SM = getCI ( ) - > getSourceManager ( ) ;
2013-03-11 17:11:15 +04:00
m_VirtualFileID = SM . getMainFileID ( ) ;
2012-09-05 13:37:39 +04:00
assert ( ! m_VirtualFileID . isInvalid ( ) & & " No VirtualFileID created? " ) ;
}
2012-11-20 07:26:52 +04:00
Transaction * IncrementalParser : : Compile ( llvm : : StringRef input ,
const CompilationOptions & Opts ) {
Transaction * CurT = beginTransaction ( Opts ) ;
EParseResult ParseRes = ParseInternal ( input ) ;
2012-09-05 13:37:39 +04:00
2012-11-20 07:26:52 +04:00
if ( ParseRes = = kSuccessWithWarnings )
CurT - > setIssuedDiags ( Transaction : : kWarnings ) ;
else if ( ParseRes = = kFailed )
CurT - > setIssuedDiags ( Transaction : : kErrors ) ;
2013-10-24 20:54:06 +04:00
if ( ( CurT = endTransaction ( CurT ) ) ) {
2013-07-06 15:04:31 +04:00
commitTransaction ( CurT ) ;
2013-06-27 16:29:44 +04:00
}
2012-11-20 07:26:52 +04:00
return CurT ;
2012-09-05 13:37:39 +04:00
}
2012-10-15 17:42:09 +04:00
Transaction * IncrementalParser : : Parse ( llvm : : StringRef input ,
const CompilationOptions & Opts ) {
2013-04-27 03:52:55 +04:00
Transaction * CurT = beginTransaction ( Opts ) ;
2012-09-05 13:37:39 +04:00
ParseInternal ( input ) ;
2013-04-27 03:52:55 +04:00
Transaction * EndedT = endTransaction ( CurT ) ;
return EndedT ;
2012-09-05 13:37:39 +04:00
}
// Add the input to the memory buffer, parse it, and add it to the AST.
IncrementalParser : : EParseResult
IncrementalParser : : ParseInternal ( llvm : : StringRef input ) {
if ( input . empty ( ) ) return IncrementalParser : : kSuccess ;
Sema & S = getCI ( ) - > getSema ( ) ;
2013-04-10 11:09:57 +04:00
2015-01-23 12:49:18 +03:00
const CompilationOptions & CO
= m_Consumer - > getTransaction ( ) - > getCompilationOpts ( ) ;
2013-04-10 11:14:37 +04:00
assert ( ! ( S . getLangOpts ( ) . Modules
2015-01-23 12:49:18 +03:00
& & CO . CodeGenerationForModule )
2014-02-20 13:16:47 +04:00
& & " CodeGenerationForModule to be removed once PCMs are available! " ) ;
2013-04-10 11:09:57 +04:00
2012-09-05 13:37:39 +04:00
// Recover resources if we crash before exiting this method.
llvm : : CrashRecoveryContextCleanupRegistrar < Sema > CleanupSema ( & S ) ;
Preprocessor & PP = m_CI - > getPreprocessor ( ) ;
if ( ! PP . getCurrentLexer ( ) ) {
PP . EnterSourceFile ( m_CI - > getSourceManager ( ) . getMainFileID ( ) ,
0 , SourceLocation ( ) ) ;
}
2012-10-04 17:09:52 +04:00
assert ( PP . isIncrementalProcessingEnabled ( ) & & " Not in incremental mode!? " ) ;
2012-09-05 13:37:39 +04:00
PP . enableIncrementalProcessing ( ) ;
std : : ostringstream source_name ;
source_name < < " input_line_ " < < ( m_MemoryBuffers . size ( ) + 1 ) ;
// Create an uninitialized memory buffer, copy code in and append "\n"
size_t InputSize = input . size ( ) ; // don't include trailing 0
// MemBuffer size should *not* include terminating zero
2015-01-15 17:13:14 +03:00
std : : unique_ptr < llvm : : MemoryBuffer >
MB ( llvm : : MemoryBuffer : : getNewUninitMemBuffer ( InputSize + 1 ,
source_name . str ( ) ) ) ;
2012-09-05 13:37:39 +04:00
char * MBStart = const_cast < char * > ( MB - > getBufferStart ( ) ) ;
memcpy ( MBStart , input . data ( ) , InputSize ) ;
memcpy ( MBStart + InputSize , " \n " , 2 ) ;
SourceManager & SM = getCI ( ) - > getSourceManager ( ) ;
// Create SourceLocation, which will allow clang to order the overload
// candidates for example
2014-04-01 18:44:59 +04:00
SourceLocation NewLoc = getLastMemoryBufferEndLoc ( ) . getLocWithOffset ( 1 ) ;
2012-09-05 13:37:39 +04:00
2015-02-10 13:18:15 +03:00
llvm : : MemoryBuffer * MBNonOwn = MB . get ( ) ;
2012-09-05 13:37:39 +04:00
// Create FileID for the current buffer
2015-01-15 17:13:14 +03:00
FileID FID = SM . createFileID ( std : : move ( MB ) , SrcMgr : : C_User ,
/*LoadedID*/ 0 ,
2014-06-06 12:22:05 +04:00
/*LoadedOffset*/ 0 , NewLoc ) ;
2012-09-05 13:37:39 +04:00
2015-02-10 13:18:15 +03:00
m_MemoryBuffers . push_back ( std : : make_pair ( MBNonOwn , FID ) ) ;
2015-01-23 18:18:01 +03:00
2012-09-05 13:37:39 +04:00
PP . EnterSourceFile ( FID , /*DirLookup*/ 0 , NewLoc ) ;
2013-12-03 18:31:31 +04:00
m_Consumer - > getTransaction ( ) - > setBufferFID ( FID ) ;
2012-09-05 13:37:39 +04:00
2015-01-23 12:49:18 +03:00
DiagnosticsEngine & Diags = getCI ( ) - > getDiagnostics ( ) ;
bool IgnorePromptDiags = CO . IgnorePromptDiags ;
if ( IgnorePromptDiags ) {
// Disable warnings which doesn't make sense when using the prompt
// This gets reset with the clang::Diagnostics().Reset(/*soft*/=false)
// using clang's API we simulate:
// #pragma warning push
// #pragma warning ignore ...
// #pragma warning ignore ...
// #pragma warning pop
SourceLocation Loc = SM . getLocForStartOfFile ( FID ) ;
Diags . pushMappings ( Loc ) ;
// The source locations of #pragma warning ignore must be greater than
// the ones from #pragma push
auto setIgnore = [ & ] ( clang : : diag : : kind Diag ) {
Diags . setSeverity ( Diag , diag : : Severity : : Ignored , SourceLocation ( ) ) ;
} ;
setIgnore ( clang : : diag : : warn_unused_expr ) ;
setIgnore ( clang : : diag : : warn_unused_call ) ;
setIgnore ( clang : : diag : : warn_unused_comparison ) ;
setIgnore ( clang : : diag : : ext_return_has_expr ) ;
}
2014-12-02 19:43:18 +03:00
Sema : : SavePendingInstantiationsRAII SavedPendingInstantiations ( S ) ;
2012-09-05 13:37:39 +04:00
Parser : : DeclGroupPtrTy ADecl ;
while ( ! m_Parser - > ParseTopLevelDecl ( ADecl ) ) {
// If we got a null return and something *was* parsed, ignore it. This
// is due to a top-level semicolon, an action override, or a parse error
// skipping something.
if ( ADecl )
2013-09-23 17:36:32 +04:00
m_Consumer - > HandleTopLevelDecl ( ADecl . get ( ) ) ;
2012-09-05 13:37:39 +04:00
} ;
2015-01-23 12:49:18 +03:00
if ( IgnorePromptDiags ) {
2015-01-23 18:18:01 +03:00
SourceLocation Loc = SM . getLocForEndOfFile ( m_MemoryBuffers . back ( ) . second ) ;
2015-01-23 12:49:18 +03:00
Diags . popMappings ( Loc ) ;
}
2012-09-05 13:37:39 +04:00
// Process any TopLevelDecls generated by #pragma weak.
for ( llvm : : SmallVector < Decl * , 2 > : : iterator I = S . WeakTopLevelDecls ( ) . begin ( ) ,
E = S . WeakTopLevelDecls ( ) . end ( ) ; I ! = E ; + + I ) {
m_Consumer - > HandleTopLevelDecl ( DeclGroupRef ( * I ) ) ;
}
2015-01-23 12:49:18 +03:00
if ( Diags . hasErrorOccurred ( ) )
2012-09-05 13:37:39 +04:00
return IncrementalParser : : kFailed ;
2015-01-23 12:49:18 +03:00
else if ( Diags . getNumWarnings ( ) )
2012-09-05 13:37:39 +04:00
return IncrementalParser : : kSuccessWithWarnings ;
return IncrementalParser : : kSuccess ;
}
2013-07-06 15:02:49 +04:00
void IncrementalParser : : printTransactionStructure ( ) const {
for ( size_t i = 0 , e = m_Transactions . size ( ) ; i < e ; + + i ) {
m_Transactions [ i ] - > printStructureBrief ( ) ;
}
}
2013-09-13 12:37:54 +04:00
bool IncrementalParser : : shouldIgnore ( const Decl * D ) const {
2014-01-14 22:05:35 +04:00
// This function is called for all "deserialized" decls, where the
// "deserialized" decl either really comes from an AST file or from
// a header that's loaded to import the AST for a library with a dictionary
// (the non-PCM case).
//
2013-08-26 19:59:33 +04:00
// Functions that are inlined must be sent to CodeGen - they will not have a
// symbol in the library.
if ( const FunctionDecl * FD = dyn_cast < FunctionDecl > ( D ) ) {
2014-01-14 22:05:35 +04:00
if ( D - > isFromASTFile ( ) ) {
2013-08-26 19:59:33 +04:00
return ! FD - > hasBody ( ) ;
2014-01-14 22:05:35 +04:00
} else {
// If the decl must be emitted then it will be in the library.
// If not, we must expose it to CodeGen now because it might
// not be in the library. Does this correspond to a weak symbol
// by definition?
return ! ( FD - > isInlined ( ) | | FD - > isTemplateInstantiation ( ) ) ;
}
2013-08-26 19:59:33 +04:00
}
// Don't codegen statics coming in from a module; they are already part of
// the library.
2014-02-14 13:17:21 +04:00
// We do need to expose static variables from template instantiations.
2013-08-26 19:59:33 +04:00
if ( const VarDecl * VD = dyn_cast < VarDecl > ( D ) )
2014-02-14 13:17:21 +04:00
if ( VD - > hasGlobalStorage ( ) & & ! VD - > getType ( ) . isConstQualified ( )
& & VD - > getTemplateSpecializationKind ( ) = = TSK_Undeclared )
2013-11-21 19:44:59 +04:00
return true ;
2013-08-26 19:59:33 +04:00
return false ;
}
2012-09-05 13:37:39 +04:00
} // namespace cling