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
//------------------------------------------------------------------------------
2015-04-16 03:33:55 -05:00
# include "ClingUtils.h"
2012-09-05 09:37:39 +00:00
# include "DeclCollector.h"
2016-11-11 10:21:52 +01:00
# include <cling-compiledata.h>
2012-09-05 09:37:39 +00:00
2016-09-14 15:49:22 -04:00
# include "cling/Interpreter/CIFactory.h"
# include "cling/Interpreter/InvocationOptions.h"
# include "cling/Utils/Paths.h"
# include "cling/Utils/Platform.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"
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/MemoryBuffer.h"
2013-04-24 19:49:12 +00:00
# include "llvm/Support/Process.h"
2016-09-14 15:49:22 -04:00
# include "llvm/Support/TargetSelect.h"
# include "llvm/Target/TargetOptions.h"
2012-09-05 09:37:39 +00:00
2013-12-18 16:19:30 +01:00
# include <cstdio>
2016-09-14 15:49:22 -04:00
# include <ctime>
2014-08-14 12:29:27 +02:00
# include <memory>
2016-07-05 16:19:41 -04:00
using namespace clang ;
2016-08-08 16:29:06 -04:00
using namespace cling ;
2016-07-05 16:19:41 -04:00
namespace {
2016-08-16 05:46:10 -04:00
// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// GetMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement GetMainExecutable
// without being given the address of a function in the main executable).
std : : string GetExecutablePath ( const char * Argv0 ) {
// This just needs to be some symbol in the binary; C++ doesn't
// allow taking the address of ::main however.
void * MainAddr = ( void * ) intptr_t ( GetExecutablePath ) ;
return llvm : : sys : : fs : : getMainExecutable ( Argv0 , MainAddr ) ;
2016-06-09 04:32:38 -04:00
}
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-08-16 18:05:45 -04:00
AdditionalArgList & Args ,
bool Verbose ) {
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) \\ + \\ + \" " ) ;
2016-08-16 18:05:45 -04:00
if ( Verbose )
llvm : : errs ( ) < < " Looking for C++ headers with: \n " < < CppInclQuery < < " \n " ;
2016-08-16 10:23:42 -04:00
if ( FILE * PF = : : popen ( CppInclQuery . c_str ( ) , " r " ) ) {
2016-06-09 04:32:38 -04:00
Buf . resize ( Buf . capacity_in_bytes ( ) ) ;
2016-08-16 10:23:42 -04:00
while ( fgets ( & Buf [ 0 ] , Buf . capacity_in_bytes ( ) , PF ) & & Buf [ 0 ] ) {
llvm : : StringRef Path ( & Buf [ 0 ] ) ;
// Skip leading and trailing whitespace
Path = Path . trim ( ) ;
if ( ! Path . empty ( ) ) {
2016-08-16 18:05:45 -04:00
if ( ! llvm : : sys : : fs : : is_directory ( Path ) ) {
if ( Verbose )
cling : : utils : : LogNonExistantDirectory ( Path ) ;
}
else
2016-08-16 10:23:42 -04:00
Args . addArgument ( " -I " , Path . str ( ) ) ;
2016-06-09 04:32:38 -04:00
}
}
2016-08-16 10:23:42 -04:00
: : pclose ( PF ) ;
2016-08-16 18:05:45 -04:00
} else {
llvm : : errs ( ) < < " popen failed " ;
// Don't be overly verbose, we already printed the command
if ( ! Verbose )
llvm : : errs ( ) < < " for ' " < < CppInclQuery < < " ' \n " ;
}
2016-06-09 04:32:38 -04:00
// 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 ( ) ) ;
2016-08-16 18:05:45 -04:00
} else if ( Verbose ) {
llvm : : errs ( ) < < " Found: \n " ;
for ( const auto & Arg : Args )
llvm : : errs ( ) < < " " < < Arg . second < < " \n " ;
2016-06-09 04:32:38 -04:00
}
}
2016-08-16 18:05:45 -04:00
static bool AddCxxPaths ( llvm : : StringRef PathStr , AdditionalArgList & Args ,
bool Verbose ) {
if ( Verbose )
llvm : : errs ( ) < < " Looking for C++ headers in \" " < < PathStr < < " \" \n " ;
2016-08-18 13:21:40 -04:00
llvm : : SmallVector < llvm : : StringRef , 6 > Paths ;
if ( ! utils : : SplitPaths ( PathStr , Paths , utils : : kFailNonExistant ,
2016-09-19 14:23:17 -04:00
platform : : kEnvDelim , Verbose ) )
2016-08-18 13:21:40 -04:00
return false ;
2016-08-16 18:05:45 -04:00
2016-08-18 13:21:40 -04:00
if ( Verbose ) {
llvm : : errs ( ) < < " Found: \n " ;
2016-08-11 06:12:20 -04:00
for ( llvm : : StringRef Path : Paths )
2016-08-18 13:21:40 -04:00
llvm : : errs ( ) < < " " < < Path < < " \n " ;
2016-08-11 06:12:20 -04:00
}
2016-08-18 13:21:40 -04:00
for ( llvm : : StringRef Path : Paths )
Args . addArgument ( " -I " , Path . str ( ) ) ;
return true ;
}
2016-06-09 04:32:38 -04:00
# 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-08-16 05:46:10 -04:00
static void AddHostArguments ( llvm : : StringRef clingBin ,
std : : vector < const char * > & args ,
2016-08-08 16:29:06 -04:00
const char * llvmdir , const CompilerOptions & opts ) {
2016-07-05 15:10:04 -04:00
static AdditionalArgList sArguments ;
if ( sArguments . empty ( ) ) {
2016-08-16 18:05:45 -04:00
const bool Verbose = opts . Verbose ;
2014-04-15 10:44:27 +02:00
# ifdef _MSC_VER
// Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
2016-09-07 04:04:29 -04:00
if ( const char * Includes = getenv ( " INCLUDE " ) ) {
2014-04-15 10:44:27 +02:00
SmallVector < StringRef , 8 > Dirs ;
2016-09-07 04:04:29 -04:00
utils : : SplitPaths ( Includes , Dirs , utils : : kAllowNonExistant ,
2016-09-19 14:23:17 -04:00
platform : : kEnvDelim , Verbose ) ;
2016-09-07 04:04:29 -04:00
for ( const llvm : : StringRef & Path : Dirs )
sArguments . addArgument ( " -I " , Path . str ( ) ) ;
2014-04-15 10:44:27 +02:00
}
// When built with access to the proper Windows APIs, try to actually find
2016-09-20 17:54:01 -04:00
// the correct include paths first. Init for UnivSDK.empty check below.
std : : string VSDir , WinSDK ,
UnivSDK ( opts . NoBuiltinInc ? " " : CLING_UCRT_VERSION ) ;
2016-09-14 15:49:22 -04:00
if ( platform : : GetVisualStudioDirs ( VSDir ,
opts . NoBuiltinInc ? nullptr : & WinSDK ,
opts . NoBuiltinInc ? nullptr : & UnivSDK ,
Verbose ) ) {
2016-08-08 16:29:06 -04:00
if ( ! opts . NoCXXInc ) {
2016-09-07 04:04:29 -04:00
const std : : string VSIncl = VSDir + " \\ VC \\ include " ;
if ( Verbose )
llvm : : errs ( ) < < " Adding VisualStudio SDK: ' " < < VSIncl < < " ' \n " ;
sArguments . addArgument ( " -I " , std : : move ( VSIncl ) ) ;
2014-04-24 10:33:09 +02:00
}
2016-08-08 16:29:06 -04:00
if ( ! opts . NoBuiltinInc ) {
2016-09-14 15:49:22 -04:00
if ( ! WinSDK . empty ( ) ) {
WinSDK . append ( " \\ include " ) ;
2016-09-07 04:04:29 -04:00
if ( Verbose )
2016-09-14 15:49:22 -04:00
llvm : : errs ( ) < < " Adding Windows SDK: ' " < < WinSDK < < " ' \n " ;
sArguments . addArgument ( " -I " , std : : move ( WinSDK ) ) ;
} else {
2016-09-07 04:04:29 -04:00
VSDir . append ( " \\ VC \\ PlatformSDK \\ Include " ) ;
if ( Verbose )
llvm : : errs ( ) < < " Adding Platform SDK: ' " < < VSDir < < " ' \n " ;
sArguments . addArgument ( " -I " , std : : move ( VSDir ) ) ;
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-09-07 03:30:39 -04:00
# if LLVM_MSC_PREREQ(1900)
2016-09-14 15:49:22 -04:00
if ( ! UnivSDK . empty ( ) ) {
if ( Verbose )
llvm : : errs ( ) < < " Adding UniversalCRT SDK: ' " < < UnivSDK < < " ' \n " ;
sArguments . addArgument ( " -I " , std : : move ( UnivSDK ) ) ;
2016-09-07 04:04:29 -04:00
}
2016-09-07 03:30:39 -04:00
# endif
2016-07-05 15:10:04 -04:00
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-08-08 16:29:06 -04:00
if ( ! opts . NoCXXInc ) {
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++
2016-08-16 05:46:10 -04:00
std : : string clang = llvm : : sys : : path : : parent_path ( clingBin ) ;
2016-06-21 13:51:48 -04:00
buffer . assign ( clang ) ;
llvm : : sys : : path : : append ( buffer , " clang " ) ;
clang . assign ( & buffer [ 0 ] , buffer . size ( ) ) ;
2016-07-05 16:19:41 -04:00
2016-08-10 16:04:59 -04:00
if ( llvm : : sys : : fs : : is_regular_file ( clang ) ) {
2016-08-08 16:29:06 -04:00
if ( ! opts . StdLib ) {
2016-08-10 16:04:59 -04:00
# if defined(_LIBCPP_VERSION)
clang . append ( " -stdlib=libc++ " ) ;
# elif defined(__GLIBCXX__)
clang . append ( " -stdlib=libstdc++ " ) ;
2016-06-21 13:51:48 -04:00
# endif
2016-08-10 16:04:59 -04:00
}
2016-08-16 18:05:45 -04:00
ReadCompilerIncludePaths ( clang . c_str ( ) , buffer , sArguments , Verbose ) ;
2016-08-10 16:04:59 -04:00
}
# endif // _LIBCPP_VERSION
2015-12-04 18:29:09 +01:00
2016-08-11 06:12:20 -04:00
// first try the include directory cling was built with
# ifdef CLING_CXX_INCL
if ( sArguments . empty ( ) )
2016-08-16 18:05:45 -04:00
AddCxxPaths ( CLING_CXX_INCL , sArguments , Verbose ) ;
2016-08-11 06:12:20 -04:00
# endif
// Then try the absolute path i.e.: '/usr/bin/g++'
# ifdef CLING_CXX_PATH
2016-07-05 15:10:04 -04:00
if ( sArguments . empty ( ) )
2016-08-16 18:05:45 -04:00
ReadCompilerIncludePaths ( CLING_CXX_PATH , buffer , sArguments , Verbose ) ;
2016-08-11 06:12:20 -04:00
# endif
// Finally try the relative path 'g++'
# ifdef CLING_CXX_RLTV
if ( sArguments . empty ( ) )
2016-08-16 18:05:45 -04:00
ReadCompilerIncludePaths ( CLING_CXX_RLTV , buffer , sArguments , Verbose ) ;
2016-08-11 06:12:20 -04:00
# endif
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
2016-08-16 18:05:45 -04:00
llvm : : errs ( ) < < " ERROR in cling::CIFactory::createCI(): cannot extract "
" standard library include paths! \n " ;
# if defined(CLING_CXX_PATH) || defined(CLING_CXX_RLTV)
// Only when ReadCompilerIncludePaths called do we have the command
// Verbose has already printed the command
if ( ! Verbose )
llvm : : errs ( ) < < " Invoking: \n " < < buffer . c_str ( ) < < " \n " ;
llvm : : errs ( ) < < " Results was: \n " ;
const int ExitCode = system ( buffer . c_str ( ) ) ;
llvm : : errs ( ) < < " With exit code " < < ExitCode < < " \n " ;
# elif !defined(CLING_CXX_INCL)
// Technically a valid configuration that just wants to use libClangs
// internal header detection, but for now give a hint about why.
llvm : : errs ( ) < < " CLING_CXX_INCL, CLING_CXX_PATH, and CLING_CXX_RLTV "
" are undefined, there was probably an error during "
2016-08-18 10:48:21 +02:00
" configuration. \n " ;
2016-08-16 18:05:45 -04:00
# endif
2016-06-21 13:51:48 -04:00
} 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-07-05 16:19:41 -04:00
# if defined(__APPLE__)
2016-08-08 16:29:06 -04:00
if ( ! opts . NoBuiltinInc & & ! opts . SysRoot ) {
2016-07-05 16:19:41 -04:00
std : : string sysRoot ;
2016-09-14 15:49:22 -04:00
if ( platform : : GetISysRoot ( sysRoot , Verbose ) ) {
2016-08-16 18:05:45 -04:00
if ( Verbose )
llvm : : errs ( ) < < " Using SDK \" " < < sysRoot < < " \" \n " ;
2016-07-05 16:19:41 -04:00
sArguments . addArgument ( " -isysroot " , std : : move ( sysRoot ) ) ;
2016-08-16 18:05:45 -04:00
}
2016-07-05 16:19:41 -04:00
}
# if defined(__GLIBCXX__)
2016-06-21 13:51:48 -04:00
// Avoid '__float128 is not supported on this target' errors
2016-08-08 16:29:06 -04:00
if ( ! opts . StdVersion )
2016-07-05 15:10:04 -04:00
sArguments . addArgument ( " -std=c++11 " ) ;
2016-07-05 16:19:41 -04:00
# endif //__GLIBCXX__
# endif // __APPLE__
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
2016-08-08 16:29:06 -04:00
if ( ! opts . ResourceDir & & ! opts . NoBuiltinInc ) {
2016-07-05 15:32:13 -04:00
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 " ,
2016-08-16 05:46:10 -04:00
( void * ) intptr_t ( GetExecutablePath ) ) ;
2016-07-05 15:32:13 -04:00
} 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
2016-07-05 16:19:41 -04:00
static void SetClingCustomLangOpts ( LangOptions & Opts ) {
Opts . EmitAllDecls = 0 ; // Otherwise if PCH attached will codegen all decls.
# ifdef _MSC_VER
Opts . Exceptions = 0 ;
if ( Opts . CPlusPlus ) {
Opts . CXXExceptions = 0 ;
}
# else
Opts . Exceptions = 1 ;
if ( Opts . CPlusPlus ) {
Opts . CXXExceptions = 1 ;
}
# endif // _MSC_VER
Opts . Deprecated = 1 ;
//Opts.Modules = 1;
// 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 ;
Opts . MathErrno = 0 ;
# endif
// C++11 is turned on if cling is built with C++11: it's an interpreter;
// 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...
// 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 ;
# endif
# if __cplusplus >= 201103L
if ( Opts . CPlusPlus ) Opts . CPlusPlus11 = 1 ;
# endif
# ifdef _REENTRANT
Opts . POSIXThreads = 1 ;
# endif
}
static void SetClingTargetLangOpts ( LangOptions & Opts ,
const TargetInfo & Target ) {
if ( Target . getTriple ( ) . getOS ( ) = = llvm : : Triple : : Win32 ) {
Opts . MicrosoftExt = 1 ;
# ifdef _MSC_VER
Opts . MSCompatibilityVersion = ( _MSC_VER * 100000 ) ;
# endif
// Should fix http://llvm.org/bugs/show_bug.cgi?id=10528
Opts . DelayedTemplateParsing = 1 ;
} else {
Opts . MicrosoftExt = 0 ;
}
}
// 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 ( ) ;
}
///\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 ;
}
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 ( ) ) ;
}
2016-08-16 05:46:10 -04:00
static void AddRuntimeIncludePaths ( llvm : : StringRef ClingBin ,
clang : : HeaderSearchOptions & HOpts ) {
2016-08-16 18:05:45 -04:00
if ( HOpts . Verbose )
llvm : : errs ( ) < < " Adding runtime include paths: \n " ;
2016-08-16 05:46:10 -04:00
// Add configuration paths to interpreter's include files.
# ifdef CLING_INCLUDE_PATHS
2016-08-16 18:05:45 -04:00
if ( HOpts . Verbose )
llvm : : errs ( ) < < " \" " CLING_INCLUDE_PATHS " \" \n " ;
2016-09-19 14:23:17 -04:00
utils : : AddIncludePaths ( CLING_INCLUDE_PATHS , HOpts ) ;
2016-08-16 05:46:10 -04:00
# endif
llvm : : SmallString < 512 > P ( ClingBin ) ;
if ( ! P . empty ( ) ) {
// Remove /cling from foo/bin/clang
llvm : : StringRef ExeIncl = llvm : : sys : : path : : parent_path ( P ) ;
// Remove /bin from foo/bin
ExeIncl = llvm : : sys : : path : : parent_path ( ExeIncl ) ;
P . resize ( ExeIncl . size ( ) ) ;
// Get foo/include
llvm : : sys : : path : : append ( P , " include " ) ;
if ( llvm : : sys : : fs : : is_directory ( P . str ( ) ) )
2016-08-08 16:29:06 -04:00
utils : : AddIncludePaths ( P . str ( ) , HOpts , nullptr ) ;
2016-08-16 05:46:10 -04:00
}
}
2016-08-08 16:29:06 -04:00
static CompilerInstance *
createCIImpl ( std : : unique_ptr < llvm : : MemoryBuffer > Buffer ,
const CompilerOptions & COpts , const char * LLVMDir ,
bool OnlyLex ) {
2016-08-16 18:05:45 -04:00
// Follow clang -v convention of printing version on first line
if ( COpts . Verbose )
llvm : : errs ( ) < < " cling version " < < ClingStringify ( CLING_VERSION ) < < ' \n ' ;
2016-08-08 16:29:06 -04:00
// Create an instance builder, passing the LLVMDir and arguments.
2012-09-05 09:37:39 +00:00
//
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-08-08 16:29:06 -04:00
const size_t argc = COpts . Remaining . size ( ) ;
const char * const * argv = & COpts . Remaining [ 0 ] ;
2016-07-05 15:32:13 -04:00
std : : vector < const char * > argvCompile ( argv , argv + 1 ) ;
argvCompile . reserve ( argc + 5 ) ;
2016-08-08 16:29:06 -04:00
if ( ! COpts . Language ) {
2016-07-05 15:32:13 -04:00
// 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 16:19:41 -04:00
// Add host specific includes, -resource-dir if necessary, and -isysroot
2016-08-08 16:29:06 -04:00
std : : string ClingBin = GetExecutablePath ( argv [ 0 ] ) ;
AddHostArguments ( ClingBin , argvCompile , LLVMDir , COpts ) ;
2012-09-05 09:37:39 +00:00
2016-08-10 16:04:59 -04:00
// Be explicit about the stdlib on OS X
// Would be nice on Linux but will warn 'argument unused during compilation'
// when -nostdinc++ is passed
# ifdef __APPLE__
2016-08-08 16:29:06 -04:00
if ( ! COpts . StdLib ) {
2016-08-10 16:04:59 -04:00
# ifdef _LIBCPP_VERSION
argvCompile . push_back ( " -stdlib=libc++ " ) ;
# elif defined(__GLIBCXX__)
argvCompile . push_back ( " -stdlib=libstdc++ " ) ;
# endif
}
# endif
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.
2016-09-14 15:49:22 -04:00
FM . getDirectory ( platform : : GetCwd ( ) ) ;
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 ( ) ;
2016-08-08 16:29:06 -04:00
if ( ! Buffer )
2016-11-09 17:53:50 +01:00
Buffer = llvm : : MemoryBuffer : : getMemBuffer ( " /*CLING DEFAULT MEMBUF*/; \n " ) ;
2016-08-08 16:29:06 -04: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 ( ) ) ;
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
2016-08-16 05:46:10 -04:00
if ( ! OnlyLex ) {
// -nobuiltininc
clang : : HeaderSearchOptions & HOpts = CI - > getHeaderSearchOpts ( ) ;
if ( CI - > getHeaderSearchOpts ( ) . UseBuiltinIncludes )
2016-08-08 16:29:06 -04:00
AddRuntimeIncludePaths ( ClingBin , HOpts ) ;
2016-08-16 05:46:10 -04:00
2016-08-16 18:05:45 -04:00
// Write a marker to know the rest of the output is from clang
if ( COpts . Verbose )
llvm : : errs ( ) < < " Setting up system headers with clang: \n " ;
2016-08-16 05:46:10 -04:00
// ### FIXME:
// Want to update LLVM to 3.9 realease and better testing first, but
// ApplyHeaderSearchOptions shouldn't even be called here:
// 1. It's already been called via CI->createPreprocessor(TU_Complete)
// 2. It could corrupt clang's directory cache
// HeaderSearchOptions.::AddSearchPath is a better alternative
clang : : ApplyHeaderSearchOptions ( PP . getHeaderSearchInfo ( ) , HOpts ,
PP . getLangOpts ( ) ,
PP . getTargetInfo ( ) . getTriple ( ) ) ;
}
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
2016-08-16 05:53:04 -04:00
namespace cling {
2016-08-25 15:35:14 +02:00
CompilerInstance * CIFactory : : createCI ( llvm : : StringRef Code ,
const InvocationOptions & Opts ,
const char * LLVMDir ) {
2016-08-08 16:29:06 -04:00
return createCIImpl ( llvm : : MemoryBuffer : : getMemBuffer ( Code ) ,
Opts . CompilerOpts , LLVMDir , false /*OnlyLex*/ ) ;
}
2015-01-21 13:28:30 +01:00
2016-08-25 15:35:14 +02:00
CompilerInstance * CIFactory : : createCI ( MemBufPtr_t Buffer , int argc ,
const char * const * argv ,
const char * LLVMDir , bool OnlyLex ) {
2016-08-08 16:29:06 -04:00
return createCIImpl ( std : : move ( Buffer ) , CompilerOptions ( argc , argv ) ,
LLVMDir , OnlyLex ) ;
}
2016-08-16 05:53:04 -04:00
2016-08-25 15:35:14 +02:00
} // namespace cling
2016-08-16 05:53:04 -04:00