2012-09-05 13:37:39 +04:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@cern.ch>
2014-01-07 14:08:37 +04:00
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
2012-09-05 13:37:39 +04:00
//------------------------------------------------------------------------------
# include "cling/Interpreter/InvocationOptions.h"
# include "cling/Interpreter/ClingOptions.h"
# include "clang/Driver/Options.h"
# include "llvm/ADT/OwningPtr.h"
2013-09-19 19:01:41 +04:00
# include "llvm/Option/Arg.h"
# include "llvm/Option/ArgList.h"
# include "llvm/Option/Option.h"
# include "llvm/Option/OptTable.h"
2012-09-05 13:37:39 +04:00
# include "llvm/Support/raw_ostream.h"
using namespace clang ;
using namespace cling : : driver : : clingoptions ;
2013-09-19 19:01:41 +04:00
using namespace llvm ;
using namespace llvm : : opt ;
2012-09-05 13:37:39 +04:00
namespace {
2013-04-24 20:28:08 +04:00
# define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
2014-01-15 18:43:38 +04:00
# define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
2013-04-24 20:28:08 +04:00
HELPTEXT , METAVAR )
# include "cling/Interpreter/ClingOptions.inc"
# undef OPTION
# undef PREFIX
2012-09-05 13:37:39 +04:00
static const OptTable : : Info ClingInfoTable [ ] = {
2013-04-24 20:28:08 +04:00
# define PREFIX(NAME, VALUE)
2014-01-15 18:43:38 +04:00
# define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
2013-04-24 20:28:08 +04:00
HELPTEXT , METAVAR ) \
{ PREFIX , NAME , HELPTEXT , METAVAR , OPT_ # # ID , Option : : KIND # # Class , PARAM , \
2014-01-15 18:43:38 +04:00
FLAGS , OPT_ # # GROUP , OPT_ # # ALIAS , ALIASARGS } ,
2012-09-05 13:37:39 +04:00
# include "cling/Interpreter/ClingOptions.inc"
# undef OPTION
2013-04-24 20:28:08 +04:00
# undef PREFIX
2012-09-05 13:37:39 +04:00
} ;
class ClingOptTable : public OptTable {
public :
ClingOptTable ( )
: OptTable ( ClingInfoTable ,
sizeof ( ClingInfoTable ) / sizeof ( ClingInfoTable [ 0 ] ) ) { }
} ;
static OptTable * CreateClingOptTable ( ) {
return new ClingOptTable ( ) ;
}
static void ParseStartupOpts ( cling : : InvocationOptions & Opts ,
InputArgList & Args /* , Diags */ ) {
2013-12-02 13:49:37 +04:00
Opts . ErrorOut = Args . hasArg ( OPT__errorout ) ;
2012-09-05 13:37:39 +04:00
Opts . NoLogo = Args . hasArg ( OPT__nologo ) ;
Opts . ShowVersion = Args . hasArg ( OPT_version ) ;
Opts . Verbose = Args . hasArg ( OPT_v ) ;
Opts . Help = Args . hasArg ( OPT_help ) ;
if ( Args . hasArg ( OPT__metastr , OPT__metastr_EQ ) ) {
Arg * MetaStringArg = Args . getLastArg ( OPT__metastr , OPT__metastr_EQ ) ;
2013-04-24 20:28:08 +04:00
Opts . MetaString = MetaStringArg - > getValue ( ) ;
2012-09-05 13:37:39 +04:00
if ( Opts . MetaString . length ( ) = = 0 ) {
llvm : : errs ( ) < < " ERROR: meta string must be non-empty! Defaulting to '.'. \n " ;
Opts . MetaString = " . " ;
}
}
}
static void ParseLinkerOpts ( cling : : InvocationOptions & Opts ,
InputArgList & Args /* , Diags */ ) {
Opts . LibsToLoad = Args . getAllArgValues ( OPT_l ) ;
std : : vector < std : : string > LibPaths = Args . getAllArgValues ( OPT_L ) ;
for ( size_t i = 0 ; i < LibPaths . size ( ) ; + + i )
2013-02-25 17:14:24 +04:00
Opts . LibSearchPath . push_back ( LibPaths [ i ] ) ;
2012-09-05 13:37:39 +04:00
}
}
cling : : InvocationOptions
cling : : InvocationOptions : : CreateFromArgs ( int argc , const char * const argv [ ] ,
std : : vector < unsigned > & leftoverArgs
/* , Diagnostic &Diags */ ) {
InvocationOptions ClingOpts ;
llvm : : OwningPtr < OptTable > Opts ( CreateClingOptTable ( ) ) ;
unsigned MissingArgIndex , MissingArgCount ;
llvm : : OwningPtr < InputArgList > Args (
Opts - > ParseArgs ( argv , argv + argc , MissingArgIndex , MissingArgCount ) ) ;
//if (MissingArgCount)
// Diags.Report(diag::err_drv_missing_argument)
// << Args->getArgString(MissingArgIndex) << MissingArgCount;
// Forward unknown arguments.
for ( ArgList : : const_iterator it = Args - > begin ( ) ,
ie = Args - > end ( ) ; it ! = ie ; + + it ) {
if ( ( * it ) - > getOption ( ) . getKind ( ) = = Option : : UnknownClass
| | ( * it ) - > getOption ( ) . getKind ( ) = = Option : : InputClass ) {
leftoverArgs . push_back ( ( * it ) - > getIndex ( ) ) ;
}
}
ParseStartupOpts ( ClingOpts , * Args /* , Diags */ ) ;
ParseLinkerOpts ( ClingOpts , * Args /* , Diags */ ) ;
return ClingOpts ;
}
void cling : : InvocationOptions : : PrintHelp ( ) {
llvm : : OwningPtr < OptTable > Opts ( CreateClingOptTable ( ) ) ;
2013-01-17 19:27:14 +04:00
// We need stream that doesn't close its file descriptor, thus we are not
// using llvm::outs. Keeping file descriptor open we will be able to use
// the results in pipes (Savannah #99234).
Opts - > PrintHelp ( llvm : : errs ( ) , " cling " ,
2012-09-05 13:37:39 +04:00
" cling: LLVM/clang C++ Interpreter: http://cern.ch/cling " ) ;
2013-09-20 20:20:51 +04:00
llvm : : OwningPtr < OptTable > OptsC1 ( clang : : driver : : createDriverOptTable ( ) ) ;
2013-01-17 19:27:14 +04:00
OptsC1 - > PrintHelp ( llvm : : errs ( ) , " clang -cc1 " ,
2012-09-05 13:37:39 +04:00
" LLVM 'Clang' Compiler: http://clang.llvm.org " ) ;
}