2012-09-05 09:37:39 +00:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@cern.ch>
2014-01-07 11:08:37 +01: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 09:37:39 +00:00
//------------------------------------------------------------------------------
# include "cling/Interpreter/CIFactory.h"
2015-04-16 03:33:55 -05:00
# include "ClingUtils.h"
2012-09-05 09:37:39 +00:00
# include "DeclCollector.h"
2014-01-13 17:43:45 +01:00
# include "cling-compiledata.h"
2012-09-05 09:37:39 +00:00
# include "clang/AST/ASTContext.h"
# include "clang/Basic/TargetInfo.h"
# include "clang/Basic/Version.h"
# include "clang/Driver/Compilation.h"
# include "clang/Driver/Driver.h"
# include "clang/Driver/Job.h"
# include "clang/Driver/Tool.h"
# include "clang/Frontend/TextDiagnosticPrinter.h"
2014-03-28 12:39:38 +01:00
# include "clang/Frontend/VerifyDiagnosticConsumer.h"
2012-09-05 09:37:39 +00:00
# include "clang/Lex/Preprocessor.h"
2013-11-18 16:49:19 +01:00
# include "clang/Sema/Sema.h"
2014-03-27 14:49:01 +01:00
# include "clang/Sema/SemaDiagnostic.h"
2015-07-03 17:42:10 +02:00
# include "clang/Serialization/ASTReader.h"
2012-09-05 09:37:39 +00:00
2016-06-17 11:23:43 +02:00
# include "llvm/Config/llvm-config.h"
2013-04-24 16:28:08 +00:00
# include "llvm/IR/LLVMContext.h"
2013-09-19 16:57:16 +02:00
# include "llvm/Option/ArgList.h"
2012-09-05 09:37:39 +00:00
# include "llvm/Target/TargetOptions.h"
2013-09-20 18:20:20 +02:00
# include "llvm/Support/FileSystem.h"
2012-09-05 09:37:39 +00:00
# include "llvm/Support/Host.h"
# include "llvm/Support/TargetSelect.h"
# include "llvm/Support/MemoryBuffer.h"
2013-04-24 19:49:12 +00:00
# include "llvm/Support/Process.h"
2012-09-05 09:37:39 +00:00
2013-04-08 15:40:32 +00:00
# include <ctime>
2013-12-18 16:19:30 +01:00
# include <cstdio>
2013-04-08 15:40:32 +00:00
2014-08-14 12:29:27 +02:00
# include <memory>
2014-04-15 10:44:27 +02:00
// Include the necessary headers to interface with the Windows registry and
// environment.
# ifdef _MSC_VER
2016-02-05 17:22:42 +01:00
# define WIN32_LEAN_AND_MEAN
# define NOGDI
2016-07-21 11:34:43 +02:00
# ifndef NOMINMAX
# define NOMINMAX
# endif
2016-02-05 17:22:42 +01:00
# include <Windows.h>
# include <direct.h>
# include <sstream>
# define popen _popen
# define pclose _pclose
# define getcwd_func _getcwd
# pragma comment(lib, "Advapi32.lib")
2015-03-25 11:55:22 +01:00
# else
2016-02-05 17:22:42 +01:00
# include <unistd.h>
# define getcwd_func getcwd
2013-12-20 13:50:43 +01:00
# endif
2012-09-05 09:37:39 +00:00
using namespace clang ;
2014-04-15 10:44:27 +02:00
// FIXME: This code has been taken (copied from) llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
// and should probably go to some platform utils place.
2014-08-03 21:05:42 -05:00
// the code for VS 11.0 and 12.0 common tools (vs110comntools and vs120comntools)
2014-04-15 10:44:27 +02:00
// has been implemented (added) in getVisualStudioDir()
# ifdef _MSC_VER
/// \brief Read registry string.
/// This also supports a means to look for high-versioned keys by use
/// of a $VERSION placeholder in the key path.
/// $VERSION in the key path is a placeholder for the version number,
/// causing the highest value path to be searched for and used.
/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
/// There can be additional characters in the component. Only the numberic
/// characters are compared.
static bool getSystemRegistryString ( const char * keyPath , const char * valueName ,
char * value , size_t maxLength ) {
HKEY hRootKey = NULL ;
HKEY hKey = NULL ;
const char * subKey = NULL ;
DWORD valueType ;
DWORD valueSize = maxLength - 1 ;
long lResult ;
bool returnValue = false ;
if ( strncmp ( keyPath , " HKEY_CLASSES_ROOT \\ " , 18 ) = = 0 ) {
hRootKey = HKEY_CLASSES_ROOT ;
subKey = keyPath + 18 ;
} else if ( strncmp ( keyPath , " HKEY_USERS \\ " , 11 ) = = 0 ) {
hRootKey = HKEY_USERS ;
subKey = keyPath + 11 ;
} else if ( strncmp ( keyPath , " HKEY_LOCAL_MACHINE \\ " , 19 ) = = 0 ) {
hRootKey = HKEY_LOCAL_MACHINE ;
subKey = keyPath + 19 ;
} else if ( strncmp ( keyPath , " HKEY_CURRENT_USER \\ " , 18 ) = = 0 ) {
hRootKey = HKEY_CURRENT_USER ;
subKey = keyPath + 18 ;
} else {
return false ;
}
const char * placeHolder = strstr ( subKey , " $VERSION " ) ;
char bestName [ 256 ] ;
bestName [ 0 ] = ' \0 ' ;
// If we have a $VERSION placeholder, do the highest-version search.
if ( placeHolder ) {
const char * keyEnd = placeHolder - 1 ;
const char * nextKey = placeHolder ;
// Find end of previous key.
while ( ( keyEnd > subKey ) & & ( * keyEnd ! = ' \\ ' ) )
keyEnd - - ;
// Find end of key containing $VERSION.
while ( * nextKey & & ( * nextKey ! = ' \\ ' ) )
nextKey + + ;
size_t partialKeyLength = keyEnd - subKey ;
char partialKey [ 256 ] ;
if ( partialKeyLength > sizeof ( partialKey ) )
partialKeyLength = sizeof ( partialKey ) ;
strncpy ( partialKey , subKey , partialKeyLength ) ;
partialKey [ partialKeyLength ] = ' \0 ' ;
HKEY hTopKey = NULL ;
lResult = RegOpenKeyEx ( hRootKey , partialKey , 0 , KEY_READ | KEY_WOW64_32KEY ,
& hTopKey ) ;
if ( lResult = = ERROR_SUCCESS ) {
char keyName [ 256 ] ;
int bestIndex = - 1 ;
double bestValue = 0.0 ;
DWORD index , size = sizeof ( keyName ) - 1 ;
for ( index = 0 ; RegEnumKeyEx ( hTopKey , index , keyName , & size , NULL ,
NULL , NULL , NULL ) = = ERROR_SUCCESS ; index + + ) {
const char * sp = keyName ;
while ( * sp & & ! isDigit ( * sp ) )
sp + + ;
if ( ! * sp )
continue ;
const char * ep = sp + 1 ;
while ( * ep & & ( isDigit ( * ep ) | | ( * ep = = ' . ' ) ) )
ep + + ;
char numBuf [ 32 ] ;
strncpy ( numBuf , sp , sizeof ( numBuf ) - 1 ) ;
numBuf [ sizeof ( numBuf ) - 1 ] = ' \0 ' ;
double dvalue = strtod ( numBuf , NULL ) ;
if ( dvalue > bestValue ) {
// Test that InstallDir is indeed there before keeping this index.
// Open the chosen key path remainder.
strcpy ( bestName , keyName ) ;
// Append rest of key.
strncat ( bestName , nextKey , sizeof ( bestName ) - 1 ) ;
bestName [ sizeof ( bestName ) - 1 ] = ' \0 ' ;
lResult = RegOpenKeyEx ( hTopKey , bestName , 0 ,
KEY_READ | KEY_WOW64_32KEY , & hKey ) ;
if ( lResult = = ERROR_SUCCESS ) {
lResult = RegQueryValueEx ( hKey , valueName , NULL , & valueType ,
( LPBYTE ) value , & valueSize ) ;
if ( lResult = = ERROR_SUCCESS ) {
bestIndex = ( int ) index ;
bestValue = dvalue ;
returnValue = true ;
}
RegCloseKey ( hKey ) ;
}
}
size = sizeof ( keyName ) - 1 ;
}
RegCloseKey ( hTopKey ) ;
}
} else {
lResult = RegOpenKeyEx ( hRootKey , subKey , 0 , KEY_READ | KEY_WOW64_32KEY ,
& hKey ) ;
if ( lResult = = ERROR_SUCCESS ) {
lResult = RegQueryValueEx ( hKey , valueName , NULL , & valueType ,
( LPBYTE ) value , & valueSize ) ;
if ( lResult = = ERROR_SUCCESS )
returnValue = true ;
RegCloseKey ( hKey ) ;
}
}
return returnValue ;
}
/// \brief Get Windows SDK installation directory.
static bool getWindowsSDKDir ( std : : string & path ) {
char windowsSDKInstallDir [ 256 ] ;
// Try the Windows registry.
bool hasSDKDir = getSystemRegistryString (
" HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ Microsoft SDKs \\ Windows \\ $VERSION " ,
" InstallationFolder " ,
windowsSDKInstallDir ,
sizeof ( windowsSDKInstallDir ) - 1 ) ;
// If we have both vc80 and vc90, pick version we were compiled with.
if ( hasSDKDir & & windowsSDKInstallDir [ 0 ] ) {
path = windowsSDKInstallDir ;
return true ;
}
return false ;
}
2016-08-08 12:12:25 +02:00
// Find the most recent version of Universal CRT or Windows 10 SDK.
// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
// directory by name and uses the last one of the list.
// So we compare entry names lexicographically to find the greatest one.
static bool getWindows10SDKVersion ( const std : : string & SDKPath ,
std : : string & SDKVersion ) {
SDKVersion . clear ( ) ;
std : : error_code EC ;
llvm : : SmallString < 128 > IncludePath ( SDKPath ) ;
llvm : : sys : : path : : append ( IncludePath , " Include " ) ;
for ( llvm : : sys : : fs : : directory_iterator DirIt ( IncludePath , EC ) , DirEnd ;
DirIt ! = DirEnd & & ! EC ; DirIt . increment ( EC ) ) {
if ( ! llvm : : sys : : fs : : is_directory ( DirIt - > path ( ) ) )
continue ;
StringRef CandidateName = llvm : : sys : : path : : filename ( DirIt - > path ( ) ) ;
// If WDK is installed, there could be subfolders like "wdf" in the
// "Include" directory.
// Allow only directories which names start with "10.".
if ( ! CandidateName . startswith ( " 10. " ) )
continue ;
if ( CandidateName > SDKVersion )
SDKVersion = CandidateName ;
}
return ! SDKVersion . empty ( ) ;
}
static bool getUniversalCRTSdkDir ( std : : string & Path ,
std : : string & UCRTVersion ) {
// vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
// for the specific key "KitsRoot10". So do we.
char sPath [ 256 ] ;
if ( ! getSystemRegistryString (
" HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ Windows Kits \\ Installed Roots " ,
" KitsRoot10 " , sPath , sizeof ( sPath ) ) )
return false ;
Path = sPath ;
return getWindows10SDKVersion ( Path , UCRTVersion ) ;
}
2014-04-15 10:44:27 +02:00
// Get Visual Studio installation directory.
static bool getVisualStudioDir ( std : : string & path ) {
// First check the environment variables that vsvars32.bat sets.
const char * vcinstalldir = getenv ( " VCINSTALLDIR " ) ;
if ( vcinstalldir ) {
char * p = const_cast < char * > ( strstr ( vcinstalldir , " \\ VC " ) ) ;
if ( p )
* p = ' \0 ' ;
path = vcinstalldir ;
return true ;
}
2014-04-24 10:33:09 +02:00
int VSVersion = ( _MSC_VER / 100 ) - 6 ;
std : : stringstream keyName ;
keyName < < " HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ VisualStudio \\ " < < VSVersion < < " .0 " ;
2014-04-15 10:44:27 +02:00
char vsIDEInstallDir [ 256 ] ;
char vsExpressIDEInstallDir [ 256 ] ;
// Then try the windows registry.
2014-04-24 10:33:09 +02:00
bool hasVCDir = getSystemRegistryString ( keyName . str ( ) . c_str ( ) ,
2014-04-15 10:44:27 +02:00
" InstallDir " , vsIDEInstallDir , sizeof ( vsIDEInstallDir ) - 1 ) ;
2014-04-24 10:33:09 +02:00
keyName . str ( std : : string ( ) ) ;
keyName < < " HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ VCExpress \\ " < < VSVersion < < " .0 " ;
bool hasVCExpressDir = getSystemRegistryString ( keyName . str ( ) . c_str ( ) ,
2014-04-15 10:44:27 +02:00
" InstallDir " , vsExpressIDEInstallDir , sizeof ( vsExpressIDEInstallDir ) - 1 ) ;
// If we have both vc80 and vc90, pick version we were compiled with.
if ( hasVCDir & & vsIDEInstallDir [ 0 ] ) {
char * p = ( char * ) strstr ( vsIDEInstallDir , " \\ Common7 \\ IDE " ) ;
if ( p )
* p = ' \0 ' ;
path = vsIDEInstallDir ;
return true ;
}
if ( hasVCExpressDir & & vsExpressIDEInstallDir [ 0 ] ) {
char * p = ( char * ) strstr ( vsExpressIDEInstallDir , " \\ Common7 \\ IDE " ) ;
if ( p )
* p = ' \0 ' ;
path = vsExpressIDEInstallDir ;
return true ;
}
// Try the environment.
2016-05-18 18:52:52 +02:00
const char * vs140comntools = getenv ( " VS140COMNTOOLS " ) ;
2014-04-15 10:44:27 +02:00
const char * vs120comntools = getenv ( " VS120COMNTOOLS " ) ;
const char * vs110comntools = getenv ( " VS110COMNTOOLS " ) ;
const char * vs100comntools = getenv ( " VS100COMNTOOLS " ) ;
const char * vs90comntools = getenv ( " VS90COMNTOOLS " ) ;
const char * vs80comntools = getenv ( " VS80COMNTOOLS " ) ;
const char * vscomntools = NULL ;
// Try to find the version that we were compiled with
if ( false ) { }
2016-05-18 18:52:52 +02:00
# if (_MSC_VER >= 1900) // VC140
else if ( vs140comntools ) {
vscomntools = vs140comntools ;
}
# elif (_MSC_VER >= 1800) // VC120
2014-04-15 10:44:27 +02:00
else if ( vs120comntools ) {
vscomntools = vs120comntools ;
}
# elif (_MSC_VER >= 1700) // VC110
else if ( vs110comntools ) {
vscomntools = vs110comntools ;
}
# elif (_MSC_VER >= 1600) // VC100
else if ( vs100comntools ) {
vscomntools = vs100comntools ;
}
# elif (_MSC_VER == 1500) // VC80
else if ( vs90comntools ) {
vscomntools = vs90comntools ;
}
# elif (_MSC_VER == 1400) // VC80
else if ( vs80comntools ) {
vscomntools = vs80comntools ;
}
# endif
// Otherwise find any version we can
2016-05-18 18:52:52 +02:00
else if ( vs140comntools )
vscomntools = vs140comntools ;
2014-04-15 10:44:27 +02:00
else if ( vs120comntools )
vscomntools = vs120comntools ;
else if ( vs110comntools )
vscomntools = vs110comntools ;
else if ( vs100comntools )
vscomntools = vs100comntools ;
else if ( vs90comntools )
vscomntools = vs90comntools ;
else if ( vs80comntools )
vscomntools = vs80comntools ;
if ( vscomntools & & * vscomntools ) {
const char * p = strstr ( vscomntools , " \\ Common7 \\ Tools " ) ;
path = p ? std : : string ( vscomntools , p ) : vscomntools ;
return true ;
}
return false ;
}
# endif // _MSC_VER
2014-10-14 08:58:40 +02:00
namespace {
static void SetClingCustomLangOpts ( LangOptions & Opts ) {
Opts . EmitAllDecls = 0 ; // Otherwise if PCH attached will codegen all decls.
2014-12-17 14:00:31 +01:00
# ifdef _MSC_VER
Opts . Exceptions = 0 ;
if ( Opts . CPlusPlus ) {
Opts . CXXExceptions = 0 ;
}
# else
2014-10-14 08:58:40 +02:00
Opts . Exceptions = 1 ;
if ( Opts . CPlusPlus ) {
Opts . CXXExceptions = 1 ;
2012-09-05 09:37:39 +00:00
}
2014-12-17 14:00:31 +01:00
# endif // _MSC_VER
2014-10-14 08:58:40 +02:00
Opts . Deprecated = 1 ;
//Opts.Modules = 1;
2012-09-05 09:37:39 +00:00
2014-10-21 20:02:21 +02:00
// See test/CodeUnloading/PCH/VTables.cpp which implicitly compares clang
// to cling lang options. They should be the same, we should not have to
// give extra lang options to their invocations on any platform.
// Except -fexceptions -fcxx-exceptions.
Opts . Deprecated = 1 ;
Opts . GNUKeywords = 0 ;
Opts . Trigraphs = 1 ; // o no??! but clang has it on by default...
# ifdef __APPLE__
Opts . Blocks = 1 ;
2014-10-22 11:34:22 +02:00
Opts . MathErrno = 0 ;
2014-10-21 20:02:21 +02:00
# endif
2015-09-30 16:36:21 -05:00
// C++11 is turned on if cling is built with C++11: it's an interpreter;
2014-10-14 08:58:40 +02:00
// cross-language compilation doesn't make sense.
// Extracted from Boost/config/compiler.
// SunProCC has no C++11.
// VisualC's support is not obvious to extract from Boost...
2015-07-22 17:23:54 +02:00
2015-09-30 16:36:21 -05:00
// The value of __cplusplus in GCC < 5.0 (e.g. 4.9.3) when
// either -std=c++1y or -std=c++14 is specified is 201300L, which fails
// the test for C++14 or more (201402L) as previously specified.
// I would claim that the check should be relaxed to:
# if __cplusplus > 201103L
if ( Opts . CPlusPlus ) Opts . CPlusPlus14 = 1 ;
2015-07-22 17:23:54 +02:00
# endif
# if __cplusplus >= 201103L
2015-09-30 16:36:21 -05:00
if ( Opts . CPlusPlus ) Opts . CPlusPlus11 = 1 ;
2014-10-14 08:58:40 +02:00
# endif
2012-09-05 09:37:39 +00:00
2015-06-05 08:38:02 +02:00
# ifdef _REENTRANT
Opts . POSIXThreads = 1 ;
# endif
2012-09-05 09:37:39 +00:00
}
2014-10-14 08:58:40 +02:00
static void SetClingTargetLangOpts ( LangOptions & Opts ,
const TargetInfo & Target ) {
if ( Target . getTriple ( ) . getOS ( ) = = llvm : : Triple : : Win32 ) {
Opts . MicrosoftExt = 1 ;
2016-05-18 18:52:52 +02:00
# ifdef _MSC_VER
Opts . MSCompatibilityVersion = ( _MSC_VER * 100000 ) ;
# endif
2014-10-14 08:58:40 +02:00
// Should fix http://llvm.org/bugs/show_bug.cgi?id=10528
Opts . DelayedTemplateParsing = 1 ;
} else {
Opts . MicrosoftExt = 0 ;
}
2012-09-05 09:37:39 +00:00
}
2014-03-18 09:14:24 +01:00
// This must be a copy of clang::getClangToolFullVersion(). Luckily
// we'll notice quickly if it ever changes! :-)
static std : : string CopyOfClanggetClangToolFullVersion ( StringRef ToolName ) {
std : : string buf ;
llvm : : raw_string_ostream OS ( buf ) ;
# ifdef CLANG_VENDOR
OS < < CLANG_VENDOR ;
# endif
OS < < ToolName < < " version " CLANG_VERSION_STRING " "
< < getClangFullRepositoryVersion ( ) ;
// If vendor supplied, include the base LLVM version as well.
# ifdef CLANG_VENDOR
OS < < " (based on LLVM " < < PACKAGE_VERSION < < " ) " ;
# endif
return OS . str ( ) ;
}
2016-06-09 04:32:38 -04:00
//
// Dummy function so we can use dladdr to find the executable path.
//
void locate_cling_executable ( )
{
}
2014-03-18 09:14:24 +01:00
///\brief Check the compile-time clang version vs the run-time clang version,
/// a mismatch could cause havoc. Reports if clang versions differ.
static void CheckClangCompatibility ( ) {
if ( clang : : getClangToolFullVersion ( " cling " )
! = CopyOfClanggetClangToolFullVersion ( " cling " ) )
llvm : : errs ( )
< < " Warning in cling::CIFactory::createCI(): \n "
" Using incompatible clang library! "
" Please use the one provided by cling! \n " ;
return ;
}
2016-07-05 15:32:13 -04:00
static bool strEqual ( const char * a , const char * b , size_t n ) {
return ! strncmp ( a , b , n ) & & ! a [ n ] ;
}
struct CompilerOpts {
bool hasMinusX , noBuiltinInc , noCXXIncludes , haveRsrcPath ;
void parse ( const char * arg ) {
if ( ! hasMinusX & & ! strncmp ( arg , " -x " , 2 ) )
hasMinusX = true ;
else if ( ! noBuiltinInc & & strEqual ( arg , " -nobuiltininc " , 13 ) )
noBuiltinInc = true ;
else if ( ! noCXXIncludes & & strEqual ( arg , " -nostdinc++ " , 11 ) )
noCXXIncludes = true ;
else if ( ! haveRsrcPath & & strEqual ( arg , " -resource-dir " , 13 ) )
haveRsrcPath = true ;
}
CompilerOpts ( const char * const * iarg , const char * const * earg ) :
hasMinusX ( false ) , noBuiltinInc ( false ) , noCXXIncludes ( false ) ,
haveRsrcPath ( false ) {
while ( iarg < earg & &
( ! hasMinusX | | ! noBuiltinInc | | ! noCXXIncludes | | ! haveRsrcPath ) ) {
if ( strEqual ( * iarg , " -Xclang " , 7 ) ) {
// goto next arg if there is one
if ( + + iarg < earg )
parse ( * iarg ) ;
}
else
parse ( * iarg ) ;
+ + iarg ;
}
}
} ;
2016-07-05 15:10:04 -04:00
class AdditionalArgList {
typedef std : : vector < std : : pair < const char * , std : : string > > container_t ;
container_t m_Saved ;
public :
void addArgument ( const char * arg , std : : string value = std : : string ( ) ) {
m_Saved . push_back ( std : : make_pair ( arg , std : : move ( value ) ) ) ;
}
container_t : : const_iterator begin ( ) const { return m_Saved . begin ( ) ; }
container_t : : const_iterator end ( ) const { return m_Saved . end ( ) ; }
bool empty ( ) const { return m_Saved . empty ( ) ; }
} ;
2016-06-09 04:32:38 -04:00
# ifndef _MSC_VER
static void ReadCompilerIncludePaths ( const char * Compiler ,
llvm : : SmallVectorImpl < char > & Buf ,
2016-07-05 15:10:04 -04:00
AdditionalArgList & Args ) {
2016-06-09 04:32:38 -04:00
std : : string CppInclQuery ( " LC_ALL=C " ) ;
CppInclQuery . append ( Compiler ) ;
CppInclQuery . append ( " -xc++ -E -v /dev/null 2>&1 >/dev/null "
" | awk '/^#include </,/^End of search "
" /{if (!/^#include </ && !/^End of search/){ print }}' "
" | GREP_OPTIONS= grep -E \" (c|g) \\ + \\ + \" " ) ;
if ( FILE * pf = : : popen ( CppInclQuery . c_str ( ) , " r " ) ) {
Buf . resize ( Buf . capacity_in_bytes ( ) ) ;
while ( fgets ( & Buf [ 0 ] , Buf . capacity_in_bytes ( ) , pf ) & & Buf [ 0 ] ) {
const size_t lenbuf = strlen ( & Buf [ 0 ] ) ;
Buf [ lenbuf - 1 ] = 0 ; // remove trailing \n
// Skip leading whitespace:
const char * start = & Buf [ 0 ] ;
while ( start < ( & Buf [ 0 ] + lenbuf ) & & : : isspace ( * start ) )
+ + start ;
if ( * start ) {
2016-07-05 15:10:04 -04:00
if ( llvm : : sys : : fs : : is_directory ( start ) )
Args . addArgument ( " -I " , start ) ;
2016-06-09 04:32:38 -04:00
}
}
: : pclose ( pf ) ;
} else
llvm : : errs ( ) < < " popen failed for ' " < < CppInclQuery < < " ' \n " ;
// Return the query in Buf on failure
2016-07-05 15:10:04 -04:00
if ( Args . empty ( ) ) {
2016-06-09 04:32:38 -04:00
Buf . resize ( 0 ) ;
Buf . insert ( Buf . begin ( ) , CppInclQuery . begin ( ) , CppInclQuery . end ( ) ) ;
}
}
# endif
2016-07-05 15:10:04 -04:00
2013-12-18 16:19:30 +01:00
///\brief Adds standard library -I used by whatever compiler is found in PATH.
2016-07-05 15:32:13 -04:00
static void AddHostArguments ( std : : vector < const char * > & args ,
const char * llvmdir , const CompilerOpts & opts ) {
2016-07-05 15:10:04 -04:00
static AdditionalArgList sArguments ;
if ( sArguments . empty ( ) ) {
2014-04-15 10:44:27 +02:00
# ifdef _MSC_VER
// Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
if ( const char * cl_include_dir = getenv ( " INCLUDE " ) ) {
SmallVector < StringRef , 8 > Dirs ;
StringRef ( cl_include_dir ) . split ( Dirs , " ; " ) ;
for ( SmallVectorImpl < StringRef > : : iterator I = Dirs . begin ( ) , E = Dirs . end ( ) ;
I ! = E ; + + I ) {
StringRef d = * I ;
if ( d . size ( ) = = 0 )
continue ;
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -I " , d ) ;
2014-04-15 10:44:27 +02:00
}
}
std : : string VSDir ;
std : : string WindowsSDKDir ;
// When built with access to the proper Windows APIs, try to actually find
// the correct include paths first.
if ( getVisualStudioDir ( VSDir ) ) {
2016-07-05 15:32:13 -04:00
if ( ! opts . noCXXIncludes ) {
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -I " , VSDir + " \\ VC \\ include " ) ;
2014-04-24 10:33:09 +02:00
}
2016-07-05 15:32:13 -04:00
if ( ! opts . noBuiltinInc ) {
2016-06-21 13:51:48 -04:00
if ( getWindowsSDKDir ( WindowsSDKDir ) ) {
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -I " , WindowsSDKDir + " \\ include " ) ;
2016-06-21 13:51:48 -04:00
}
else {
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -I " , VSDir + " \\ VC \\ PlatformSDK \\ Include " ) ;
2016-06-21 13:51:48 -04:00
}
2014-04-24 10:33:09 +02:00
}
2014-04-15 10:44:27 +02:00
}
2016-08-08 12:12:25 +02:00
std : : string UniversalCRTSdkPath ;
std : : string UCRTVersion ;
2016-07-05 15:10:04 -04:00
if ( getUniversalCRTSdkDir ( UniversalCRTSdkPath , UCRTVersion ) )
sArguments . addArgument ( " -I " ,
UniversalCRTSdkPath + " \\ Include \\ " + UCRTVersion + " \\ ucrt " ) ;
2014-04-15 10:44:27 +02:00
# else // _MSC_VER
2016-06-21 13:51:48 -04:00
2015-12-04 18:29:09 +01:00
// Skip LLVM_CXX execution if -nostdinc++ was provided.
2016-07-05 15:32:13 -04:00
if ( ! opts . noCXXIncludes ) {
2016-07-05 15:10:04 -04:00
// Need sArguments.empty as a check condition later
assert ( sArguments . empty ( ) & & " Arguments not empty " ) ;
2016-06-21 13:51:48 -04:00
SmallString < 2048 > buffer ;
# ifdef _LIBCPP_VERSION
// Try to use a version of clang that is located next to cling
// in case cling was built with a new/custom libc++
std : : string clang = llvm : : sys : : fs : : getMainExecutable (
" cling " , ( void * ) ( uintptr_t ( locate_cling_executable ) ) ) ;
clang = llvm : : sys : : path : : parent_path ( clang ) ;
buffer . assign ( clang ) ;
llvm : : sys : : path : : append ( buffer , " clang " ) ;
clang . assign ( & buffer [ 0 ] , buffer . size ( ) ) ;
if ( llvm : : sys : : fs : : is_regular_file ( clang ) )
2016-07-05 15:10:04 -04:00
ReadCompilerIncludePaths ( clang . c_str ( ) , buffer , sArguments ) ;
2016-06-21 13:51:48 -04:00
# endif
2015-12-04 18:29:09 +01:00
2016-07-05 15:10:04 -04:00
if ( sArguments . empty ( ) )
ReadCompilerIncludePaths ( LLVM_CXX , buffer , sArguments ) ;
2016-06-21 13:51:48 -04:00
2016-07-05 15:10:04 -04:00
if ( sArguments . empty ( ) ) {
2016-06-21 13:51:48 -04:00
// buffer is a copy of the query string that failed
llvm : : errs ( ) < < " ERROR in cling::CIFactory::createCI(): cannot extract "
" standard library include paths! \n "
" Invoking: \n "
" " < < buffer . c_str ( ) < < " \n "
" results in \n " ;
int ExitCode = system ( buffer . c_str ( ) ) ;
llvm : : errs ( ) < < " with exit code " < < ExitCode < < " \n " ;
} else
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -nostdinc++ " ) ;
2016-06-21 13:51:48 -04:00
}
2016-06-09 04:32:38 -04:00
2016-06-21 13:51:48 -04:00
# if defined(__GLIBCXX__) && defined(__APPLE__)
// Avoid '__float128 is not supported on this target' errors
bool haveCXXVers = false , haveCXXLib = false ;
for ( const auto arg : args ) {
if ( ! strncmp ( arg , " -std= " , 5 ) )
haveCXXVers = true ;
if ( ! strncmp ( arg , " -stdlib= " , 8 ) )
haveCXXLib = true ;
}
if ( ! haveCXXVers )
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -std=c++11 " ) ;
2016-06-21 13:51:48 -04:00
if ( ! haveCXXLib )
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -stdlib=libstdc++ " ) ;
2016-06-21 13:51:48 -04:00
# endif
2016-08-12 20:07:55 -04:00
2014-04-15 10:44:27 +02:00
# endif // _MSC_VER
2016-07-05 15:32:13 -04:00
if ( ! opts . haveRsrcPath & & ! opts . noBuiltinInc ) {
std : : string resourcePath ;
if ( ! llvmdir ) {
// FIXME: The first arg really does need to be argv[0] on FreeBSD.
//
// Note: The second arg is not used for Apple, FreeBSD, Linux,
// or cygwin, and can only be used on systems which support
// the use of dladdr().
//
// Note: On linux and cygwin this uses /proc/self/exe to find the path
// Note: On Apple it uses _NSGetExecutablePath().
// Note: On FreeBSD it uses getprogpath().
// Note: Otherwise it uses dladdr().
//
resourcePath
= CompilerInvocation : : GetResourcesPath ( " cling " ,
( void * ) ( intptr_t ) locate_cling_executable ) ;
} else {
llvm : : SmallString < 512 > tmp ( llvmdir ) ;
llvm : : sys : : path : : append ( tmp , " lib " , " clang " , CLANG_VERSION_STRING ) ;
resourcePath . assign ( & tmp [ 0 ] , tmp . size ( ) ) ;
}
// FIXME: Handle cases, where the cling is part of a library/framework.
// There we can't rely on the find executable logic.
if ( ! llvm : : sys : : fs : : is_directory ( resourcePath ) ) {
llvm : : errs ( )
< < " ERROR in cling::CIFactory::createCI(): \n resource directory "
< < resourcePath < < " not found! \n " ;
resourcePath = " " ;
} else {
sArguments . addArgument ( " -resource-dir " , std : : move ( resourcePath ) ) ;
}
}
2013-12-18 16:19:30 +01:00
}
2016-07-05 15:10:04 -04:00
for ( auto & arg : sArguments ) {
args . push_back ( arg . first ) ;
args . push_back ( arg . second . c_str ( ) ) ;
}
2013-12-18 16:19:30 +01:00
}
2014-10-14 08:58:40 +02:00
/// \brief Retrieves the clang CC1 specific flags out of the compilation's
/// jobs. Returns NULL on error.
static const llvm : : opt : : ArgStringList
* GetCC1Arguments ( clang : : DiagnosticsEngine * Diagnostics ,
clang : : driver : : Compilation * Compilation ) {
// We expect to get back exactly one Command job, if we didn't something
// failed. Extract that job from the Compilation.
const clang : : driver : : JobList & Jobs = Compilation - > getJobs ( ) ;
if ( ! Jobs . size ( ) | | ! isa < clang : : driver : : Command > ( * Jobs . begin ( ) ) ) {
// diagnose this...
return NULL ;
}
// The one job we find should be to invoke clang again.
const clang : : driver : : Command * Cmd
2015-01-15 15:13:14 +01:00
= cast < clang : : driver : : Command > ( & ( * Jobs . begin ( ) ) ) ;
2014-10-14 08:58:40 +02:00
if ( llvm : : StringRef ( Cmd - > getCreator ( ) . getName ( ) ) ! = " clang " ) {
// diagnose this...
return NULL ;
}
return & Cmd - > getArguments ( ) ;
}
2015-05-07 14:21:14 -05:00
/// Set cling's preprocessor defines to match the cling binary.
static void SetPreprocessorFromBinary ( PreprocessorOptions & PPOpts ) {
# ifdef _MSC_VER
PPOpts . addMacroDef ( " _HAS_EXCEPTIONS=0 " ) ;
2016-07-21 11:34:43 +02:00
# ifdef _DEBUG
PPOpts . addMacroDef ( " _DEBUG=1 " ) ;
# elif defined(NDEBUG)
PPOpts . addMacroDef ( " NDEBUG=1 " ) ;
# else // well, what else?
PPOpts . addMacroDef ( " NDEBUG=1 " ) ;
# endif
2015-05-07 14:21:14 -05:00
# endif
// Since cling, uses clang instead, macros always sees __CLANG__ defined
// In addition, clang also defined __GNUC__, we add the following two macros
// to allow scripts, and more important, dictionary generation to know which
// of the two is the underlying compiler.
# ifdef __clang__
PPOpts . addMacroDef ( " __CLING__clang__= " ClingStringify ( __clang__ ) ) ;
# elif defined(__GNUC__)
PPOpts . addMacroDef ( " __CLING__GNUC__= " ClingStringify ( __GNUC__ ) ) ;
# endif
2015-05-07 18:00:15 -05:00
// https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
# ifdef _GLIBCXX_USE_CXX11_ABI
PPOpts . addMacroDef ( " _GLIBCXX_USE_CXX11_ABI= "
ClingStringify ( _GLIBCXX_USE_CXX11_ABI ) ) ;
# endif
2015-05-07 14:21:14 -05:00
}
/// Set target-specific preprocessor defines.
static void SetPreprocessorFromTarget ( PreprocessorOptions & PPOpts ,
const llvm : : Triple & TTriple ) {
if ( TTriple . getEnvironment ( ) = = llvm : : Triple : : Cygnus ) {
// clang "forgets" the basic arch part needed by winnt.h:
if ( TTriple . getArch ( ) = = llvm : : Triple : : x86 ) {
PPOpts . addMacroDef ( " _X86_=1 " ) ;
} else if ( TTriple . getArch ( ) = = llvm : : Triple : : x86_64 ) {
PPOpts . addMacroDef ( " __x86_64=1 " ) ;
} else {
llvm : : errs ( ) < < " Warning in cling::CIFactory::createCI(): \n "
" unhandled target architecture "
< < TTriple . getArchName ( ) < < ' \n ' ;
}
}
}
2016-04-28 14:18:35 +02:00
template < class CONTAINER >
static void insertBehind ( CONTAINER & To , const CONTAINER & From ) {
To . insert ( To . end ( ) , From . begin ( ) , From . end ( ) ) ;
}
2015-01-21 13:28:30 +01:00
static CompilerInstance * createCIImpl (
2015-01-15 15:13:14 +01:00
std : : unique_ptr < llvm : : MemoryBuffer > buffer ,
2012-09-05 09:37:39 +00:00
int argc ,
const char * const * argv ,
2013-11-18 16:49:19 +01:00
const char * llvmdir ,
2015-01-21 13:28:30 +01:00
bool OnlyLex ) {
2012-09-05 09:37:39 +00:00
// Create an instance builder, passing the llvmdir and arguments.
//
2014-03-18 09:14:24 +01:00
CheckClangCompatibility ( ) ;
2012-09-05 09:37:39 +00:00
// Initialize the llvm library.
llvm : : InitializeNativeTarget ( ) ;
2015-02-25 11:14:36 +01:00
llvm : : InitializeNativeTargetAsmParser ( ) ;
2014-03-08 13:14:33 +01:00
llvm : : InitializeNativeTargetAsmPrinter ( ) ;
2012-09-05 09:37:39 +00:00
2016-07-05 15:32:13 -04:00
CompilerOpts copts ( argv , argv + argc ) ;
std : : vector < const char * > argvCompile ( argv , argv + 1 ) ;
argvCompile . reserve ( argc + 5 ) ;
if ( ! copts . hasMinusX ) {
// We do C++ by default; append right after argv[0] if no "-x" given
argvCompile . push_back ( " -x " ) ;
argvCompile . push_back ( " c++ " ) ;
2012-09-05 09:37:39 +00:00
}
2016-07-05 15:32:13 -04:00
// argv[0] already inserted, get the rest
argvCompile . insert ( argvCompile . end ( ) , argv + 1 , argv + argc ) ;
2014-10-02 14:39:25 +02:00
2016-07-05 15:32:13 -04:00
// Add host specific and -resource-dir if necessary
AddHostArguments ( argvCompile , llvmdir , copts ) ;
2012-09-05 09:37:39 +00:00
2016-07-05 15:32:13 -04:00
argvCompile . push_back ( " -c " ) ;
argvCompile . push_back ( " - " ) ;
2014-10-02 14:39:25 +02:00
2014-03-28 10:50:27 +01:00
clang : : CompilerInvocation *
Invocation = new clang : : CompilerInvocation ;
// The compiler invocation is the owner of the diagnostic options.
// Everything else points to them.
DiagnosticOptions & DiagOpts = Invocation - > getDiagnosticOpts ( ) ;
TextDiagnosticPrinter * DiagnosticPrinter
= new TextDiagnosticPrinter ( llvm : : errs ( ) , & DiagOpts ) ;
llvm : : IntrusiveRefCntPtr < clang : : DiagnosticIDs > DiagIDs ( new DiagnosticIDs ( ) ) ;
llvm : : IntrusiveRefCntPtr < DiagnosticsEngine >
Diags ( new DiagnosticsEngine ( DiagIDs , & DiagOpts ,
DiagnosticPrinter , /*Owns it*/ true ) ) ;
2012-09-05 09:37:39 +00:00
clang : : driver : : Driver Driver ( argv [ 0 ] , llvm : : sys : : getDefaultTargetTriple ( ) ,
2014-03-27 15:12:07 +01:00
* Diags ) ;
2012-09-05 09:37:39 +00:00
//Driver.setWarnMissingInput(false);
Driver . setCheckInputsExist ( false ) ; // think foo.C(12)
llvm : : ArrayRef < const char * > RF ( & ( argvCompile [ 0 ] ) , argvCompile . size ( ) ) ;
2014-08-14 12:29:27 +02:00
std : : unique_ptr < clang : : driver : : Compilation >
2012-09-05 09:37:39 +00:00
Compilation ( Driver . BuildCompilation ( RF ) ) ;
const clang : : driver : : ArgStringList * CC1Args
2014-07-31 16:54:29 +02:00
= GetCC1Arguments ( Diags . get ( ) , Compilation . get ( ) ) ;
2012-09-05 09:37:39 +00:00
if ( CC1Args = = NULL ) {
2015-06-02 21:54:47 +02:00
delete Invocation ;
2012-09-05 09:37:39 +00:00
return 0 ;
}
2015-11-02 16:52:52 -06:00
2012-09-05 09:37:39 +00:00
clang : : CompilerInvocation : : CreateFromArgs ( * Invocation , CC1Args - > data ( ) + 1 ,
CC1Args - > data ( ) + CC1Args - > size ( ) ,
2014-03-27 15:12:07 +01:00
* Diags ) ;
2015-11-02 16:52:52 -06:00
// We appreciate the error message about an unknown flag (or do we? if not
// we should switch to a different DiagEngine for parsing the flags).
// But in general we'll happily go on.
Diags - > Reset ( ) ;
2015-07-03 17:42:10 +02:00
// Create and setup a compiler instance.
std : : unique_ptr < CompilerInstance > CI ( new CompilerInstance ( ) ) ;
CI - > createFileManager ( ) ;
llvm : : StringRef PCHFileName
= Invocation - > getPreprocessorOpts ( ) . ImplicitPCHInclude ;
if ( ! PCHFileName . empty ( ) ) {
// Load target options etc from PCH.
struct PCHListener : public ASTReaderListener {
CompilerInvocation & m_Invocation ;
PCHListener ( CompilerInvocation & I ) : m_Invocation ( I ) { }
bool ReadLanguageOptions ( const LangOptions & LangOpts ,
bool /*Complain*/ ,
bool /*AllowCompatibleDifferences*/ ) override {
* m_Invocation . getLangOpts ( ) = LangOpts ;
return true ;
}
bool ReadTargetOptions ( const TargetOptions & TargetOpts ,
2016-04-22 15:11:18 +02:00
bool /*Complain*/ ,
2015-07-03 17:42:10 +02:00
bool /*AllowCompatibleDifferences*/ ) override {
m_Invocation . getTargetOpts ( ) = TargetOpts ;
return true ;
}
bool ReadPreprocessorOptions ( const PreprocessorOptions & PPOpts ,
bool /*Complain*/ ,
std : : string & /*SuggestedPredefines*/ ) override {
2016-04-28 14:18:35 +02:00
// Import selected options, e.g. don't overwrite ImplicitPCHInclude.
PreprocessorOptions & myPP = m_Invocation . getPreprocessorOpts ( ) ;
insertBehind ( myPP . Macros , PPOpts . Macros ) ;
insertBehind ( myPP . Includes , PPOpts . Includes ) ;
insertBehind ( myPP . MacroIncludes , PPOpts . MacroIncludes ) ;
2015-07-03 17:42:10 +02:00
return true ;
}
} ;
PCHListener listener ( * Invocation ) ;
ASTReader : : readASTFileControlBlock ( PCHFileName ,
CI - > getFileManager ( ) ,
2016-04-22 15:11:18 +02:00
CI - > getPCHContainerReader ( ) ,
false /*FindModuleFileExtensions*/ ,
2015-07-03 17:42:10 +02:00
listener ) ;
}
2012-09-05 09:37:39 +00:00
Invocation - > getFrontendOpts ( ) . DisableFree = true ;
2014-03-28 12:39:38 +01:00
// Copied from CompilerInstance::createDiagnostics:
// Chain in -verify checker, if requested.
if ( DiagOpts . VerifyDiagnostics )
Diags - > setClient ( new clang : : VerifyDiagnosticConsumer ( * Diags ) ) ;
// Configure our handling of diagnostics.
ProcessWarningOptions ( * Diags , DiagOpts ) ;
2012-09-05 09:37:39 +00:00
CI - > setInvocation ( Invocation ) ;
2014-07-31 16:54:29 +02:00
CI - > setDiagnostics ( Diags . get ( ) ) ;
2012-09-05 09:37:39 +00:00
2015-07-03 17:42:10 +02:00
if ( PCHFileName . empty ( ) ) {
// Set the language options, which cling needs
SetClingCustomLangOpts ( CI - > getLangOpts ( ) ) ;
}
2015-05-07 14:21:14 -05:00
2016-08-10 21:23:47 -04:00
PreprocessorOptions & PPOpts = CI - > getInvocation ( ) . getPreprocessorOpts ( ) ;
2015-05-07 14:21:14 -05:00
SetPreprocessorFromBinary ( PPOpts ) ;
2013-06-13 13:57:54 +02:00
2015-05-07 14:21:14 -05:00
PPOpts . addMacroDef ( " __CLING__ " ) ;
if ( CI - > getLangOpts ( ) . CPlusPlus11 = = 1 ) {
// http://llvm.org/bugs/show_bug.cgi?id=13530
PPOpts . addMacroDef ( " __CLING__CXX11 " ) ;
2012-09-05 09:37:39 +00:00
}
2015-05-07 14:21:14 -05:00
if ( CI - > getDiagnostics ( ) . hasErrorOccurred ( ) )
return 0 ;
2012-09-05 09:37:39 +00:00
CI - > setTarget ( TargetInfo : : CreateTargetInfo ( CI - > getDiagnostics ( ) ,
2014-07-31 17:05:05 +02:00
Invocation - > TargetOpts ) ) ;
2015-07-03 17:42:10 +02:00
if ( ! CI - > hasTarget ( ) )
2012-09-05 09:37:39 +00:00
return 0 ;
2015-07-03 17:42:10 +02:00
2014-07-31 17:05:35 +02:00
CI - > getTarget ( ) . adjust ( CI - > getLangOpts ( ) ) ;
2015-07-03 17:42:10 +02:00
if ( PCHFileName . empty ( ) )
SetClingTargetLangOpts ( CI - > getLangOpts ( ) , CI - > getTarget ( ) ) ;
2015-05-07 14:21:14 -05:00
SetPreprocessorFromTarget ( PPOpts , CI - > getTarget ( ) . getTriple ( ) ) ;
2012-09-05 09:37:39 +00:00
2015-07-03 17:42:10 +02:00
// Set up source managers
2013-09-17 16:25:52 +02:00
SourceManager * SM = new SourceManager ( CI - > getDiagnostics ( ) ,
CI - > getFileManager ( ) ,
2014-01-17 17:20:25 +01:00
/*UserFilesAreVolatile*/ true ) ;
2013-09-17 16:25:52 +02:00
CI - > setSourceManager ( SM ) ; // FIXME: SM leaks.
2012-09-05 09:37:39 +00:00
2013-11-25 10:57:00 +01:00
// As main file we want
2014-01-17 17:20:25 +01:00
// * a virtual file that is claiming to be huge
2013-11-25 10:57:00 +01:00
// * with an empty memory buffer attached (to bring the content)
FileManager & FM = SM - > getFileManager ( ) ;
2015-03-25 11:55:22 +01:00
// When asking for the input file below (which does not have a directory
// name), clang will call $PWD "." which is terrible if we ever change
// directories (see ROOT-7114). By asking for $PWD (and not ".") it will
// be registered as $PWD instead, which is stable even after chdirs.
char cwdbuf [ 2048 ] ;
2016-07-10 14:45:24 -04:00
if ( ! getcwd_func ( cwdbuf , sizeof ( cwdbuf ) ) ) {
// getcwd can fail, but that shouldn't mean we have to.
: : perror ( " Could not get current working directory " ) ;
} else
FM . getDirectory ( cwdbuf ) ;
2016-08-10 14:45:17 -04:00
// Build the virtual file, Give it a name that's likely not to ever
// be #included (so we won't get a clash in clangs cache).
const char * Filename = " <<< cling interactive line includer >>> " ;
const FileEntry * FE = FM . getVirtualFile ( Filename , 1U < < 15U , time ( 0 ) ) ;
2016-05-18 16:03:22 +02:00
// Tell ASTReader to create a FileID even if this file does not exist:
SM - > setFileIsTransient ( FE ) ;
2014-06-06 09:38:12 +02:00
FileID MainFileID = SM - > createFileID ( FE , SourceLocation ( ) , SrcMgr : : C_User ) ;
SM - > setMainFileID ( MainFileID ) ;
2013-11-25 10:57:00 +01:00
const SrcMgr : : SLocEntry & MainFileSLocE = SM - > getSLocEntry ( MainFileID ) ;
const SrcMgr : : ContentCache * MainFileCC
= MainFileSLocE . getFile ( ) . getContentCache ( ) ;
if ( ! buffer )
buffer = llvm : : MemoryBuffer : : getMemBuffer ( " /*CLING DEFAULT MEMBUF*/ \n " ) ;
2015-01-15 15:13:14 +01:00
const_cast < SrcMgr : : ContentCache * > ( MainFileCC ) - > setBuffer ( std : : move ( buffer ) ) ;
2012-09-05 09:37:39 +00:00
// Set up the preprocessor
2014-06-06 09:38:35 +02:00
CI - > createPreprocessor ( TU_Complete ) ;
2012-09-05 09:37:39 +00:00
Preprocessor & PP = CI - > getPreprocessor ( ) ;
2016-04-22 15:11:18 +02:00
PP . getBuiltinInfo ( ) . initializeBuiltins ( PP . getIdentifierTable ( ) ,
2012-09-05 09:37:39 +00:00
PP . getLangOpts ( ) ) ;
// Set up the ASTContext
2014-06-06 09:38:35 +02:00
CI - > createASTContext ( ) ;
2012-09-05 09:37:39 +00:00
2015-01-21 13:28:30 +01:00
if ( OnlyLex ) {
class IgnoreConsumer : public clang : : ASTConsumer {
} ;
std : : unique_ptr < clang : : ASTConsumer > ignoreConsumer ( new IgnoreConsumer ( ) ) ;
CI - > setASTConsumer ( std : : move ( ignoreConsumer ) ) ;
} else {
std : : unique_ptr < cling : : DeclCollector >
stateCollector ( new cling : : DeclCollector ( ) ) ;
// Set up the ASTConsumers
CI - > getASTContext ( ) . setASTMutationListener ( stateCollector . get ( ) ) ;
2013-11-18 16:49:19 +01:00
// Add the callback keeping track of the macro definitions
2016-03-24 11:49:59 +01:00
PP . addPPCallbacks ( stateCollector - > MakePPAdapter ( ) ) ;
2015-01-21 13:28:30 +01:00
CI - > setASTConsumer ( std : : move ( stateCollector ) ) ;
2013-11-18 16:49:19 +01:00
}
2012-09-05 09:37:39 +00:00
// Set up Sema
CodeCompleteConsumer * CCC = 0 ;
2012-12-04 15:22:10 +00:00
CI - > createSema ( TU_Complete , CCC ) ;
2012-09-05 09:37:39 +00:00
// Set CodeGen options
2015-02-24 14:26:42 +01:00
// want debug info
2015-03-20 12:39:33 +01:00
//CI->getCodeGenOpts().setDebugInfo(clang::CodeGenOptions::FullDebugInfo);
2012-09-05 09:37:39 +00:00
// CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later
2012-12-14 22:23:19 +00:00
CI - > getCodeGenOpts ( ) . CXXCtorDtorAliases = 0 ; // aliasing the complete
// ctor to the base ctor causes
// the JIT to crash
2014-03-28 10:50:05 +01:00
CI - > getCodeGenOpts ( ) . VerifyModule = 0 ; // takes too long
2013-06-13 13:57:54 +02:00
2014-08-14 12:29:27 +02:00
return CI . release ( ) ; // Passes over the ownership to the caller.
2012-09-05 09:37:39 +00:00
}
2015-01-21 13:28:30 +01:00
} // unnamed namespace
namespace cling {
CompilerInstance * CIFactory : : createCI ( llvm : : StringRef code ,
int argc ,
const char * const * argv ,
const char * llvmdir ) {
return createCIImpl ( llvm : : MemoryBuffer : : getMemBuffer ( code ) , argc , argv , llvmdir , false /*OnlyLex*/ ) ;
}
CompilerInstance * CIFactory : : createCI ( MemBufPtr_t buffer ,
int argc ,
const char * const * argv ,
const char * llvmdir ,
bool OnlyLex ) {
return createCIImpl ( std : : move ( buffer ) , argc , argv , llvmdir , OnlyLex ) ;
}
2012-09-05 09:37:39 +00:00
} // end namespace