forked from OSchip/llvm-project
167 lines
5.4 KiB
C++
167 lines
5.4 KiB
C++
//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Driver/CC1Options.h"
|
|
#include "clang/Driver/ArgList.h"
|
|
#include "clang/Driver/Arg.h"
|
|
#include "clang/Driver/OptTable.h"
|
|
#include "clang/Driver/Option.h"
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
|
#include "llvm/ADT/OwningPtr.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/System/Host.h"
|
|
|
|
using namespace clang::driver;
|
|
using namespace clang::driver::options;
|
|
using namespace clang::driver::cc1options;
|
|
|
|
static OptTable::Info CC1InfoTable[] = {
|
|
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
|
|
HELPTEXT, METAVAR) \
|
|
{ NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
|
|
OPT_##GROUP, OPT_##ALIAS },
|
|
#include "clang/Driver/CC1Options.inc"
|
|
};
|
|
|
|
namespace {
|
|
|
|
class CC1OptTable : public OptTable {
|
|
public:
|
|
CC1OptTable()
|
|
: OptTable(CC1InfoTable, sizeof(CC1InfoTable) / sizeof(CC1InfoTable[0])) {}
|
|
};
|
|
|
|
}
|
|
|
|
OptTable *clang::driver::createCC1OptTable() {
|
|
return new CC1OptTable();
|
|
}
|
|
|
|
//
|
|
|
|
using namespace clang;
|
|
|
|
static llvm::StringRef getLastArgValue(ArgList &Args, cc1options::ID ID,
|
|
llvm::StringRef Default = "") {
|
|
if (Arg *A = Args.getLastArg(ID))
|
|
return A->getValue(Args);
|
|
return Default;
|
|
}
|
|
|
|
static int getLastArgIntValue(ArgList &Args, cc1options::ID ID,
|
|
int Default = 0) {
|
|
Arg *A = Args.getLastArg(ID);
|
|
if (!A)
|
|
return Default;
|
|
|
|
int Res = Default;
|
|
// FIXME: What to do about argument parsing errors?
|
|
if (llvm::StringRef(A->getValue(Args)).getAsInteger(10, Res))
|
|
llvm::errs() << "error: invalid integral argument in '"
|
|
<< A->getAsString(Args) << "'\n";
|
|
|
|
return Res;
|
|
}
|
|
|
|
static std::vector<std::string>
|
|
getAllArgValues(ArgList &Args, cc1options::ID ID) {
|
|
llvm::SmallVector<const char *, 16> Values;
|
|
Args.AddAllArgValues(Values, ID);
|
|
return std::vector<std::string>(Values.begin(), Values.end());
|
|
}
|
|
|
|
//
|
|
|
|
static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args) {
|
|
// -Os implies -O2
|
|
if (Args.hasArg(cc1options::OPT_Os))
|
|
Opts.OptimizationLevel = 2;
|
|
else
|
|
Opts.OptimizationLevel = getLastArgIntValue(Args, cc1options::OPT_O);
|
|
|
|
// FIXME: What to do about argument parsing errors?
|
|
if (Opts.OptimizationLevel > 3) {
|
|
llvm::errs() << "error: invalid optimization level '"
|
|
<< Opts.OptimizationLevel << "' (out of range)\n";
|
|
Opts.OptimizationLevel = 3;
|
|
}
|
|
|
|
// We must always run at least the always inlining pass.
|
|
Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
|
|
: CodeGenOptions::OnlyAlwaysInlining;
|
|
|
|
Opts.DebugInfo = Args.hasArg(cc1options::OPT_g);
|
|
Opts.DisableLLVMOpts = Args.hasArg(cc1options::OPT_disable_llvm_optzns);
|
|
Opts.DisableRedZone = Args.hasArg(cc1options::OPT_disable_red_zone);
|
|
Opts.MergeAllConstants = !Args.hasArg(cc1options::OPT_fno_merge_all_constants);
|
|
Opts.NoCommon = Args.hasArg(cc1options::OPT_fno_common);
|
|
Opts.NoImplicitFloat = Args.hasArg(cc1options::OPT_no_implicit_float);
|
|
Opts.OptimizeSize = Args.hasArg(cc1options::OPT_Os);
|
|
Opts.SimplifyLibCalls = 1;
|
|
Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize);
|
|
|
|
// FIXME: Implement!
|
|
// FIXME: Eliminate this dependency?
|
|
// if (Lang.NoBuiltin)
|
|
// Opts.SimplifyLibCalls = 0;
|
|
// if (Lang.CPlusPlus)
|
|
// Opts.NoCommon = 1;
|
|
// Opts.TimePasses = TimePasses;
|
|
|
|
// FIXME: Put elsewhere?
|
|
#ifdef NDEBUG
|
|
Opts.VerifyModule = 0;
|
|
#endif
|
|
}
|
|
|
|
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
|
|
ArgList &Args) {
|
|
Opts.OutputFile = getLastArgValue(Args, cc1options::OPT_dependency_file);
|
|
Opts.Targets = getAllArgValues(Args, cc1options::OPT_MT);
|
|
Opts.IncludeSystemHeaders = Args.hasArg(cc1options::OPT_sys_header_deps);
|
|
Opts.UsePhonyTargets = Args.hasArg(cc1options::OPT_MP);
|
|
}
|
|
|
|
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
|
|
Opts.ABI = getLastArgValue(Args, cc1options::OPT_target_abi);
|
|
Opts.CPU = getLastArgValue(Args, cc1options::OPT_mcpu);
|
|
Opts.Triple = getLastArgValue(Args, cc1options::OPT_triple);
|
|
Opts.Features = getAllArgValues(Args, cc1options::OPT_target_feature);
|
|
|
|
// Use the host triple if unspecified.
|
|
if (Opts.Triple.empty())
|
|
Opts.Triple = llvm::sys::getHostTriple();
|
|
}
|
|
|
|
//
|
|
|
|
void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
|
|
const char **ArgBegin,
|
|
const char **ArgEnd) {
|
|
// Parse the arguments.
|
|
llvm::OwningPtr<OptTable> Opts(createCC1OptTable());
|
|
unsigned MissingArgIndex, MissingArgCount;
|
|
llvm::OwningPtr<InputArgList> InputArgs(
|
|
Opts->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
|
|
|
|
// Check for missing argument error.
|
|
if (MissingArgCount) {
|
|
// FIXME: Use proper diagnostics!
|
|
llvm::errs() << "error: argument to '"
|
|
<< InputArgs->getArgString(MissingArgIndex)
|
|
<< "' is missing (expected " << MissingArgCount
|
|
<< " value )\n";
|
|
}
|
|
|
|
ParseCodeGenArgs(Res.getCodeGenOpts(), *InputArgs);
|
|
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *InputArgs);
|
|
ParseTargetArgs(Res.getTargetOpts(), *InputArgs);
|
|
}
|