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"
2016-09-10 15:04:39 -04:00
# include "cling/Utils/Output.h"
2016-09-14 15:49:22 -04:00
# 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"
2016-07-21 18:29:10 -04:00
# include "clang/Frontend/FrontendDiagnostic.h"
2012-09-05 09:37:39 +00:00
# include "clang/Frontend/TextDiagnosticPrinter.h"
2014-03-28 12:39:38 +01:00
# include "clang/Frontend/VerifyDiagnosticConsumer.h"
2016-07-21 18:29:10 -04:00
# include "clang/Serialization/SerializationDiagnostic.h"
2012-09-05 09:37:39 +00:00
# include "clang/Lex/Preprocessor.h"
2017-05-18 15:16:30 +02:00
# include "clang/Lex/PreprocessorOptions.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"
2017-05-18 15:16:30 +02:00
# include "llvm/Support/Path.h"
2013-04-24 19:49:12 +00:00
# include "llvm/Support/Process.h"
2017-05-10 08:18:54 +02:00
# include "llvm/Support/TargetSelect.h"
2016-09-14 15:49:22 -04:00
# 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 {
2017-06-14 10:49:07 -04:00
static constexpr unsigned CxxStdCompiledWith ( ) {
// 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 > 201402L
return 17 ;
# elif __cplusplus > 201103L
return 14 ;
# elif __cplusplus >= 201103L
return 11 ;
# else
# error "Unknown __cplusplus version"
# endif
}
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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Looking for C++ headers with: \n " < < CppInclQuery < < " \n " ;
2016-08-16 18:05:45 -04:00
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 {
2016-07-01 22:50:33 -04:00
: : perror ( " popen failure " ) ;
2016-08-16 18:05:45 -04:00
// Don't be overly verbose, we already printed the command
if ( ! Verbose )
2016-09-10 15:04:39 -04:00
cling : : errs ( ) < < " for ' " < < CppInclQuery < < " ' \n " ;
2016-08-16 18:05:45 -04:00
}
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 ) {
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Found: \n " ;
2016-08-16 18:05:45 -04:00
for ( const auto & Arg : Args )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " " < < 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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Looking for C++ headers in \" " < < PathStr < < " \" \n " ;
2016-08-16 18:05:45 -04:00
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 ) {
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Found: \n " ;
2016-08-11 06:12:20 -04:00
for ( llvm : : StringRef Path : Paths )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " " < < 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
// 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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Adding VisualStudio SDK: ' " < < VSIncl < < " ' \n " ;
2016-09-07 04:04:29 -04:00
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-10 15:04:39 -04:00
cling : : log ( ) < < " Adding Windows SDK: ' " < < WinSDK < < " ' \n " ;
2016-09-14 15:49:22 -04:00
sArguments . addArgument ( " -I " , std : : move ( WinSDK ) ) ;
} else {
2016-09-07 04:04:29 -04:00
VSDir . append ( " \\ VC \\ PlatformSDK \\ Include " ) ;
if ( Verbose )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Adding Platform SDK: ' " < < VSDir < < " ' \n " ;
2016-09-07 04:04:29 -04:00
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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Adding UniversalCRT SDK: ' " < < UnivSDK < < " ' \n " ;
2016-09-14 15:49:22 -04:00
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
2016-11-30 12:24:59 -05:00
// Windows headers use '__declspec(dllexport) __cdecl' for most funcs
// causing a lot of warnings for different redeclarations (eg. coming from
// the test suite).
// Do not warn about such cases.
sArguments . addArgument ( " -Wno-dll-attribute-on-redeclaration " ) ;
sArguments . addArgument ( " -Wno-inconsistent-dllimport " ) ;
2017-02-14 20:41:58 -05:00
// Assume Windows.h might be included, and don't spew a ton of warnings
sArguments . addArgument ( " -Wno-ignored-attributes " ) ;
sArguments . addArgument ( " -Wno-nonportable-include-path " ) ;
sArguments . addArgument ( " -Wno-microsoft-enum-value " ) ;
sArguments . addArgument ( " -Wno-expansion-to-defined " ) ;
2016-11-30 12:24:59 -05:00
//sArguments.addArgument("-Wno-dllimport-static-field-def");
//sArguments.addArgument("-Wno-microsoft-template");
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-09-10 15:04:39 -04:00
cling : : errs ( ) < < " ERROR in cling::CIFactory::createCI(): cannot extract "
2016-08-16 18:05:45 -04:00
" 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 )
2016-09-10 15:04:39 -04:00
cling : : errs ( ) < < " Invoking: \n " < < buffer . c_str ( ) < < " \n " ;
2016-08-16 18:05:45 -04:00
2016-09-10 15:04:39 -04:00
cling : : errs ( ) < < " Results was: \n " ;
2016-08-16 18:05:45 -04:00
const int ExitCode = system ( buffer . c_str ( ) ) ;
2016-09-10 15:04:39 -04:00
cling : : errs ( ) < < " With exit code " < < ExitCode < < " \n " ;
2016-08-16 18:05:45 -04:00
# 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.
2016-09-10 15:04:39 -04:00
cling : : errs ( ) < < " CLING_CXX_INCL, CLING_CXX_PATH, and CLING_CXX_RLTV "
2016-08-16 18:05:45 -04:00
" 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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " 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
}
# 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 ) ) {
2016-09-10 15:04:39 -04:00
cling : : errs ( )
2016-07-05 15:32:13 -04:00
< < " 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
2017-06-26 23:55:40 -04:00
static void SetClingCustomLangOpts ( LangOptions & Opts ,
const CompilerOptions & CompilerOpts ) {
2016-07-05 16:19:41 -04:00
Opts . EmitAllDecls = 0 ; // Otherwise if PCH attached will codegen all decls.
# ifdef _MSC_VER
2016-11-29 16:08:23 +01:00
# ifdef _DEBUG
2016-11-30 17:37:09 -05:00
// FIXME: This requires bufferoverflowu.lib, but adding:
// #pragma comment(lib, "bufferoverflowu.lib") still gives errors!
// Opts.setStackProtector(clang::LangOptions::SSPStrong);
2017-03-03 06:47:34 -05:00
# endif // _DEBUG
# ifdef _CPPRTTI
Opts . RTTIData = 1 ;
2016-07-05 16:19:41 -04:00
# else
2017-03-03 06:47:34 -05:00
Opts . RTTIData = 0 ;
# endif // _CPPRTTI
Opts . Trigraphs = 0 ;
Opts . setDefaultCallingConv ( clang : : LangOptions : : DCC_CDecl ) ;
# else // !_MSC_VER
2016-11-29 16:08:23 +01:00
Opts . Trigraphs = 1 ;
// Opts.RTTIData = 1;
// Opts.DefaultCallingConventions = 1;
// Opts.StackProtector = 0;
2016-07-05 16:19:41 -04:00
# endif // _MSC_VER
2017-03-03 06:47:34 -05:00
2017-03-03 06:55:01 -05:00
Opts . Exceptions = 1 ;
if ( Opts . CPlusPlus ) {
Opts . CXXExceptions = 1 ;
}
2016-07-05 16:19:41 -04:00
//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 ;
# 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.
2016-12-06 21:29:16 -05:00
if ( Opts . CPlusPlus ) {
2017-06-14 10:49:07 -04:00
switch ( CxxStdCompiledWith ( ) ) {
case 17 : Opts . CPlusPlus1z = 1 ;
case 14 : Opts . CPlusPlus14 = 1 ;
case 11 : Opts . CPlusPlus11 = 1 ;
default : break ;
}
2016-12-06 21:29:16 -05:00
}
2016-07-05 16:19:41 -04:00
# ifdef _REENTRANT
Opts . POSIXThreads = 1 ;
2017-05-18 08:46:22 +02:00
# endif
# ifdef __FAST_MATH__
Opts . FastMath = 1 ;
2016-07-05 16:19:41 -04:00
# endif
2017-06-26 23:55:40 -04:00
if ( CompilerOpts . DefaultLanguage ( ) ) {
# ifdef __STRICT_ANSI__
Opts . GNUMode = 0 ;
# else
Opts . GNUMode = 1 ;
# endif
Opts . GNUKeywords = 0 ;
}
2016-07-05 16:19:41 -04:00
}
static void SetClingTargetLangOpts ( LangOptions & Opts ,
2017-06-26 23:55:40 -04:00
const TargetInfo & Target ,
const CompilerOptions & CompilerOpts ) {
2016-07-05 16:19:41 -04:00
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 ;
}
2017-06-26 23:55:40 -04:00
if ( CompilerOpts . DefaultLanguage ( ) ) {
2017-06-26 20:52:46 +02:00
# if _GLIBCXX_USE_FLOAT128
2017-06-26 23:55:40 -04:00
// We are compiling with libstdc++ with __float128 enabled.
if ( ! Target . hasFloat128Type ( ) ) {
// clang currently supports native __float128 only on few targets, and
// this target does not have it. The most visible consequence of this is a
// specialization
// __is_floating_point_helper<__float128>
// in include/c++/6.3.0/type_traits:344 that clang then rejects. The
// specialization is protected by !if _GLIBCXX_USE_FLOAT128 (which is
// unconditionally set in c++config.h) and #if !__STRICT_ANSI__. Tweak the
// latter by disabling GNUMode:
2017-06-26 20:52:46 +02:00
# warning "Disabling gnu++: clang has no __float128 support on this target!"
2017-06-26 23:55:40 -04:00
Opts . GNUMode = 0 ;
}
# endif //_GLIBCXX_USE_FLOAT128
2017-06-26 22:11:01 +02:00
}
2016-07-05 16:19:41 -04:00
}
// This must be a copy of clang::getClangToolFullVersion(). Luckily
// we'll notice quickly if it ever changes! :-)
static std : : string CopyOfClanggetClangToolFullVersion ( StringRef ToolName ) {
2016-12-14 15:32:18 -05:00
cling : : stdstrstream OS ;
2016-07-05 16:19:41 -04:00
# 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 " ) )
2016-09-10 15:04:39 -04:00
cling : : errs ( )
2016-07-05 16:19:41 -04:00
< < " 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.
2016-07-01 22:50:33 -04:00
static const llvm : : opt : : ArgStringList *
GetCC1Arguments ( clang : : driver : : Compilation * Compilation ,
clang : : DiagnosticsEngine * = nullptr ) {
2014-10-14 08:58:40 +02:00
// 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 ( ) ) ) {
2016-07-01 22:50:33 -04:00
// diagnose this better...
cling : : errs ( ) < < " No Command jobs were built. \n " ;
return nullptr ;
2014-10-14 08:58:40 +02:00
}
// 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 " ) {
2016-07-01 22:50:33 -04:00
// diagnose this better...
cling : : errs ( ) < < " Clang wasn't the first job. \n " ;
return nullptr ;
2014-10-14 08:58:40 +02:00
}
return & Cmd - > getArguments ( ) ;
}
2016-12-14 15:50:39 -05:00
# if defined(_MSC_VER) || defined(NDEBUG)
2016-12-14 15:32:18 -05:00
static void stringifyPreprocSetting ( PreprocessorOptions & PPOpts ,
const char * Name , int Val ) {
smallstream Strm ;
Strm < < Name < < " = " < < Val ;
PPOpts . addMacroDef ( Strm . str ( ) ) ;
2016-11-29 16:08:23 +01:00
}
2016-12-14 15:32:18 -05:00
# define STRINGIFY_PREPROC_SETTING(PP, name) \
stringifyPreprocSetting ( PP , # name , name )
2016-12-01 10:03:22 +01:00
# endif
2016-11-29 16:08:23 +01:00
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
2017-02-07 14:46:58 +01:00
// FIXME: Stay consistent with the _HAS_EXCEPTIONS flag settings in SetClingCustomLangOpts
// STRINGIFY_PREPROC_SETTING(PPOpts, _HAS_EXCEPTIONS);
2016-07-21 11:34:43 +02:00
# ifdef _DEBUG
2016-12-14 15:32:18 -05:00
STRINGIFY_PREPROC_SETTING ( PPOpts , _DEBUG ) ;
2016-11-29 16:08:23 +01:00
# endif
2016-12-14 15:50:39 -05:00
# endif
2016-11-29 16:08:23 +01:00
# ifdef NDEBUG
2016-12-14 15:32:18 -05:00
STRINGIFY_PREPROC_SETTING ( PPOpts , NDEBUG ) ;
2016-07-21 11:34:43 +02:00
# endif
2015-05-07 14:21:14 -05:00
// 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__ ) ) ;
2017-03-10 04:34:57 -05:00
PPOpts . addMacroDef ( " __CLING__GNUC_MINOR__= " ClingStringify ( __GNUC_MINOR__ ) ) ;
2017-02-08 01:05:23 -05:00
# elif defined(_MSC_VER)
PPOpts . addMacroDef ( " __CLING__MSVC__= " ClingStringify ( _MSC_VER ) ) ;
2015-05-07 14:21:14 -05:00
# 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
2016-09-20 19:59:19 -04:00
# if defined(LLVM_ON_WIN32)
PPOpts . addMacroDef ( " CLING_EXPORT=__declspec(dllimport) " ) ;
# else
PPOpts . addMacroDef ( " CLING_EXPORT= " ) ;
# 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 {
2016-09-10 15:04:39 -04:00
cling : : errs ( ) < < " Warning in cling::CIFactory::createCI(): \n "
" unhandled target architecture "
< < TTriple . getArchName ( ) < < ' \n ' ;
2015-05-07 14:21:14 -05:00
}
}
}
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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " 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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " \" " 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-07-01 22:50:33 -04:00
static llvm : : IntrusiveRefCntPtr < DiagnosticsEngine >
SetupDiagnostics ( DiagnosticOptions & DiagOpts ) {
// The compiler invocation is the owner of the diagnostic options.
// Everything else points to them.
llvm : : IntrusiveRefCntPtr < clang : : DiagnosticIDs > DiagIDs ( new DiagnosticIDs ( ) ) ;
std : : unique_ptr < TextDiagnosticPrinter >
DiagnosticPrinter ( new TextDiagnosticPrinter ( cling : : errs ( ) , & DiagOpts ) ) ;
llvm : : IntrusiveRefCntPtr < DiagnosticsEngine >
Diags ( new DiagnosticsEngine ( DiagIDs , & DiagOpts ,
DiagnosticPrinter . get ( ) , /*Owns it*/ true ) ) ;
DiagnosticPrinter . release ( ) ;
return Diags ;
}
2017-01-29 18:16:31 -05:00
static bool
2017-06-26 23:55:40 -04:00
SetupCompiler ( CompilerInstance * CI , const CompilerOptions & CompilerOpts ,
bool Lang = true , bool Targ = true ) {
2016-07-21 18:29:10 -04:00
// Set the language options, which cling needs.
// This may have already been done via a precompiled header
2017-01-29 18:16:31 -05:00
if ( Lang )
2017-06-26 23:55:40 -04:00
SetClingCustomLangOpts ( CI - > getLangOpts ( ) , CompilerOpts ) ;
2016-07-21 18:29:10 -04:00
PreprocessorOptions & PPOpts = CI - > getInvocation ( ) . getPreprocessorOpts ( ) ;
SetPreprocessorFromBinary ( PPOpts ) ;
PPOpts . addMacroDef ( " __CLING__ " ) ;
if ( CI - > getLangOpts ( ) . CPlusPlus11 = = 1 ) {
// http://llvm.org/bugs/show_bug.cgi?id=13530
PPOpts . addMacroDef ( " __CLING__CXX11 " ) ;
}
if ( CI - > getDiagnostics ( ) . hasErrorOccurred ( ) ) {
cling : : errs ( ) < < " Compiler error to early in initialization. \n " ;
return false ;
}
CI - > setTarget ( TargetInfo : : CreateTargetInfo ( CI - > getDiagnostics ( ) ,
CI - > getInvocation ( ) . TargetOpts ) ) ;
if ( ! CI - > hasTarget ( ) ) {
cling : : errs ( ) < < " Could not determine compiler target. \n " ;
return false ;
}
CI - > getTarget ( ) . adjust ( CI - > getLangOpts ( ) ) ;
// This may have already been done via a precompiled header
2017-01-29 18:16:31 -05:00
if ( Targ )
2017-06-26 23:55:40 -04:00
SetClingTargetLangOpts ( CI - > getLangOpts ( ) , CI - > getTarget ( ) , CompilerOpts ) ;
2016-07-21 18:29:10 -04:00
SetPreprocessorFromTarget ( PPOpts , CI - > getTarget ( ) . getTriple ( ) ) ;
return true ;
}
class ActionScan {
std : : set < const clang : : driver : : Action * > m_Visited ;
2016-08-08 19:02:10 -04:00
llvm : : SmallVector < clang : : driver : : Action : : ActionClass , 2 > m_Kinds ;
2016-07-21 18:29:10 -04:00
bool find ( const clang : : driver : : Action * A ) {
if ( A & & ! m_Visited . count ( A ) ) {
2016-08-08 19:02:10 -04:00
if ( std : : find ( m_Kinds . begin ( ) , m_Kinds . end ( ) , A - > getKind ( ) ) ! =
m_Kinds . end ( ) )
2016-07-21 18:29:10 -04:00
return true ;
m_Visited . insert ( A ) ;
return find ( * A - > input_begin ( ) ) ;
}
return false ;
}
public :
2016-08-08 19:02:10 -04:00
ActionScan ( clang : : driver : : Action : : ActionClass a , int b = - 1 ) {
m_Kinds . push_back ( a ) ;
if ( b ! = - 1 )
m_Kinds . push_back ( clang : : driver : : Action : : ActionClass ( b ) ) ;
}
2016-07-21 18:29:10 -04:00
bool find ( clang : : driver : : Compilation * C ) {
for ( clang : : driver : : Action * A : C - > getActions ( ) ) {
if ( find ( A ) )
return true ;
}
return false ;
}
} ;
2017-05-10 08:18:54 +02:00
2016-08-08 16:29:06 -04:00
static CompilerInstance *
createCIImpl ( std : : unique_ptr < llvm : : MemoryBuffer > Buffer ,
const CompilerOptions & COpts , const char * LLVMDir ,
2016-08-08 19:02:10 -04:00
bool OnlyLex , bool HasInput = false ) {
2016-08-16 18:05:45 -04:00
// Follow clang -v convention of printing version on first line
if ( COpts . Verbose )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " cling version " < < ClingStringify ( CLING_VERSION ) < < ' \n ' ;
2016-08-16 18:05:45 -04:00
2017-05-10 08:18:54 +02:00
llvm : : InitializeAllTargetInfos ( ) ;
llvm : : InitializeAllTargets ( ) ;
llvm : : InitializeAllAsmParsers ( ) ;
llvm : : InitializeAllAsmPrinters ( ) ;
llvm : : InitializeAllTargetMCs ( ) ;
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 ( ) ;
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-08-08 19:02:10 -04:00
if ( ! COpts . HasOutput | | ! HasInput ) {
2016-07-21 18:29:10 -04:00
argvCompile . push_back ( " -c " ) ;
argvCompile . push_back ( " - " ) ;
}
2014-10-02 14:39:25 +02:00
2017-05-18 15:16:30 +02:00
auto InvocationPtr = std : : make_shared < clang : : CompilerInvocation > ( ) ;
2016-07-01 22:50:33 -04:00
2014-03-28 10:50:27 +01:00
// The compiler invocation is the owner of the diagnostic options.
// Everything else points to them.
2016-07-01 22:50:33 -04:00
DiagnosticOptions & DiagOpts = InvocationPtr - > getDiagnosticOpts ( ) ;
llvm : : IntrusiveRefCntPtr < DiagnosticsEngine > Diags =
SetupDiagnostics ( DiagOpts ) ;
if ( ! Diags ) {
cling : : errs ( ) < < " Could not setup diagnostic engine. \n " ;
return nullptr ;
}
2017-03-01 17:17:26 +01:00
llvm : : Triple TheTriple ( llvm : : sys : : getProcessTriple ( ) ) ;
# ifdef LLVM_ON_WIN32
// COFF format currently needs a few changes in LLVM to function properly.
TheTriple . setObjectFormat ( llvm : : Triple : : ELF ) ;
# endif
clang : : driver : : Driver Drvr ( argv [ 0 ] , TheTriple . getTriple ( ) , * Diags ) ;
2016-07-01 22:50:33 -04:00
//Drvr.setWarnMissingInput(false);
Drvr . setCheckInputsExist ( false ) ; // think foo.C(12)
2012-09-05 09:37:39 +00:00
llvm : : ArrayRef < const char * > RF ( & ( argvCompile [ 0 ] ) , argvCompile . size ( ) ) ;
2014-08-14 12:29:27 +02:00
std : : unique_ptr < clang : : driver : : Compilation >
2016-07-01 22:50:33 -04:00
Compilation ( Drvr . BuildCompilation ( RF ) ) ;
if ( ! Compilation ) {
cling : : errs ( ) < < " Couldn't create clang::driver::Compilation. \n " ;
return nullptr ;
}
const driver : : ArgStringList * CC1Args = GetCC1Arguments ( Compilation . get ( ) ) ;
if ( ! CC1Args ) {
cling : : errs ( ) < < " Could not get cc1 arguments. \n " ;
return nullptr ;
2012-09-05 09:37:39 +00:00
}
2015-11-02 16:52:52 -06:00
2016-07-01 22:50:33 -04:00
clang : : CompilerInvocation : : CreateFromArgs ( * InvocationPtr , CC1Args - > data ( ) + 1 ,
2012-09-05 09:37:39 +00:00
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 ( ) ) ;
2017-05-18 15:16:30 +02:00
CI - > setInvocation ( InvocationPtr ) ;
2016-07-01 22:50:33 -04:00
CI - > setDiagnostics ( Diags . get ( ) ) ; // Diags is ref-counted
2017-01-28 19:46:30 -05:00
if ( ! OnlyLex )
CI - > getDiagnosticOpts ( ) . ShowColors = cling : : utils : : ColorizeOutput ( ) ;
2015-07-03 17:42:10 +02:00
2017-01-29 18:00:15 -05: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 ) ;
2016-08-08 19:02:10 -04:00
if ( COpts . HasOutput & & ! OnlyLex ) {
ActionScan scan ( clang : : driver : : Action : : PrecompileJobClass ,
clang : : driver : : Action : : PreprocessJobClass ) ;
2016-07-21 18:29:10 -04:00
if ( ! scan . find ( Compilation . get ( ) ) ) {
2016-08-08 19:02:10 -04:00
cling : : errs ( ) < < " Only precompiled header or preprocessor "
" output is supported. \n " ;
2016-07-21 18:29:10 -04:00
return nullptr ;
}
2017-06-26 23:55:40 -04:00
if ( ! SetupCompiler ( CI . get ( ) , COpts ) )
2016-07-21 18:29:10 -04:00
return nullptr ;
ProcessWarningOptions ( * Diags , DiagOpts ) ;
return CI . release ( ) ;
}
2016-07-01 22:50:33 -04:00
CI - > createFileManager ( ) ;
clang : : CompilerInvocation & Invocation = CI - > getInvocation ( ) ;
2017-01-29 18:16:31 -05:00
std : : string & PCHFile = Invocation . getPreprocessorOpts ( ) . ImplicitPCHInclude ;
bool InitLang = true , InitTarget = true ;
if ( ! PCHFile . empty ( ) ) {
if ( cling : : utils : : LookForFile ( argvCompile , PCHFile ,
2016-09-08 17:15:38 -04:00
& CI - > getFileManager ( ) ,
COpts . Verbose ? " Precompiled header " : nullptr ) ) {
// Load target options etc from PCH.
struct PCHListener : public ASTReaderListener {
CompilerInvocation & m_Invocation ;
2017-01-29 18:16:31 -05:00
bool m_ReadLang , m_ReadTarget ;
2016-09-08 17:15:38 -04:00
2017-01-29 18:16:31 -05:00
PCHListener ( CompilerInvocation & I ) :
m_Invocation ( I ) , m_ReadLang ( false ) , m_ReadTarget ( false ) { }
2016-09-08 17:15:38 -04:00
bool ReadLanguageOptions ( const LangOptions & LangOpts ,
bool /*Complain*/ ,
bool /*AllowCompatibleDifferences*/ ) override {
* m_Invocation . getLangOpts ( ) = LangOpts ;
2017-01-29 18:16:31 -05:00
m_ReadLang = true ;
2016-09-08 17:15:38 -04:00
return false ;
}
bool ReadTargetOptions ( const TargetOptions & TargetOpts ,
2015-07-03 17:42:10 +02:00
bool /*Complain*/ ,
bool /*AllowCompatibleDifferences*/ ) override {
2016-09-08 17:15:38 -04:00
m_Invocation . getTargetOpts ( ) = TargetOpts ;
2017-01-29 18:16:31 -05:00
m_ReadTarget = true ;
2016-09-08 17:15:38 -04:00
return false ;
}
bool ReadPreprocessorOptions ( const PreprocessorOptions & PPOpts ,
bool /*Complain*/ ,
std : : string & /*SuggestedPredefines*/ ) override {
// 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 ) ;
return false ;
}
} ;
2016-07-01 22:50:33 -04:00
PCHListener listener ( Invocation ) ;
2017-01-29 18:16:31 -05:00
if ( ASTReader : : readASTFileControlBlock ( PCHFile ,
CI - > getFileManager ( ) ,
CI - > getPCHContainerReader ( ) ,
false /*FindModuleFileExt*/ ,
2017-05-18 15:16:30 +02:00
listener ,
/*ValidateDiagnosticOptions=*/ false ) ) {
2017-01-29 18:16:31 -05:00
// When running interactively pass on the info that the PCH
// has failed so that IncrmentalParser::Initialize won't try again.
if ( ! HasInput & & llvm : : sys : : Process : : StandardInIsUserInput ( ) ) {
const unsigned ID = Diags - > getCustomDiagID (
clang : : DiagnosticsEngine : : Level : : Error ,
" Problems loading PCH: '%0'. " ) ;
Diags - > Report ( ID ) < < PCHFile ;
// If this was the only error, then don't let it stop anything
if ( Diags - > getClient ( ) - > getNumErrors ( ) = = 1 )
Diags - > Reset ( true ) ;
// Clear the include so no one else uses it.
std : : string ( ) . swap ( PCHFile ) ;
}
}
// All we care about is if Language and Target options were successful.
InitLang = ! listener . m_ReadLang ;
InitTarget = ! listener . m_ReadTarget ;
2016-09-08 17:15:38 -04:00
}
2015-07-03 17:42:10 +02:00
}
2016-07-01 22:50:33 -04:00
Invocation . getFrontendOpts ( ) . DisableFree = true ;
2012-09-05 09:37:39 +00:00
2016-07-21 18:29:10 -04:00
// Set up compiler language and target
2017-06-26 23:55:40 -04:00
if ( ! SetupCompiler ( CI . get ( ) , COpts , InitLang , InitTarget ) )
2016-07-01 22:50:33 -04:00
return nullptr ;
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 ) ;
2016-07-01 22:50:33 -04:00
CI - > setSourceManager ( SM ) ; // CI now owns SM
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
2016-12-19 11:57:06 +01:00
// be #included (so we won't get a clash in clang's cache).
2016-08-10 14:45:17 -04:00
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 ) {
2016-07-01 22:50:33 -04:00
class IgnoreConsumer : public clang : : ASTConsumer { } ;
CI - > setASTConsumer (
std : : unique_ptr < clang : : ASTConsumer > ( new IgnoreConsumer ( ) ) ) ;
2015-01-21 13:28:30 +01:00
} 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
2017-03-27 16:41:26 +02:00
// Set CodeGen options.
CodeGenOptions & CGOpts = CI - > getCodeGenOpts ( ) ;
2016-11-29 16:08:23 +01:00
# ifdef _MSC_VER
2017-03-27 16:41:26 +02:00
CGOpts . MSVolatile = 1 ;
CGOpts . RelaxedAliasing = 1 ;
CGOpts . EmitCodeView = 1 ;
CGOpts . CXXCtorDtorAliases = 1 ;
2016-11-29 16:08:23 +01:00
# endif
2017-03-27 16:41:26 +02:00
// Reduce amount of emitted symbols by optimizing more.
CGOpts . OptimizationLevel = 2 ;
2017-03-27 16:18:15 +02:00
// Taken from a -O2 run of clang:
2017-03-27 16:41:26 +02:00
CGOpts . DiscardValueNames = 1 ;
CGOpts . OmitLeafFramePointer = 1 ;
CGOpts . UnrollLoops = 1 ;
CGOpts . VectorizeLoop = 1 ;
CGOpts . VectorizeSLP = 1 ;
// CGOpts.setDebugInfo(clang::CodeGenOptions::FullDebugInfo);
// CGOpts.EmitDeclMetadata = 1; // For unloading, for later
// aliasing the complete ctor to the base ctor causes the JIT to crash
CGOpts . CXXCtorDtorAliases = 0 ;
CGOpts . 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 )
2016-09-10 15:04:39 -04:00
cling : : log ( ) < < " Setting up system headers with clang: \n " ;
2016-08-16 18:05:45 -04:00
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 ) ,
2016-08-08 19:02:10 -04:00
Opts . CompilerOpts , LLVMDir , false /*OnlyLex*/ ,
2017-01-29 18:13:48 -05:00
! Opts . IsInteractive ( ) ) ;
2016-08-08 16:29:06 -04:00
}
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