blob: 7655770ccca117debf7181ae7237a21b8b31b959 [file] [log] [blame]
Daniel Dunbarbe6ef382009-11-19 07:19:04 +00001//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Driver/CC1Options.h"
Daniel Dunbarf7535122009-11-20 01:46:44 +000011#include "clang/Driver/ArgList.h"
12#include "clang/Driver/Arg.h"
Daniel Dunbarbe6ef382009-11-19 07:19:04 +000013#include "clang/Driver/OptTable.h"
14#include "clang/Driver/Option.h"
Daniel Dunbar84e8a242009-11-19 20:54:59 +000015#include "clang/Frontend/CompilerInvocation.h"
Daniel Dunbarf7535122009-11-20 01:46:44 +000016#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar84e8a242009-11-19 20:54:59 +000017#include "llvm/ADT/SmallVector.h"
Daniel Dunbarf7535122009-11-20 01:46:44 +000018#include "llvm/Support/raw_ostream.h"
19#include "llvm/System/Host.h"
Daniel Dunbarbe6ef382009-11-19 07:19:04 +000020
21using namespace clang::driver;
22using namespace clang::driver::options;
23using namespace clang::driver::cc1options;
24
25static OptTable::Info CC1InfoTable[] = {
Daniel Dunbarbe6ef382009-11-19 07:19:04 +000026#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
27 HELPTEXT, METAVAR) \
28 { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
29 OPT_##GROUP, OPT_##ALIAS },
30#include "clang/Driver/CC1Options.inc"
31};
32
33namespace {
34
35class CC1OptTable : public OptTable {
36public:
37 CC1OptTable()
38 : OptTable(CC1InfoTable, sizeof(CC1InfoTable) / sizeof(CC1InfoTable[0])) {}
39};
40
41}
42
43OptTable *clang::driver::createCC1OptTable() {
44 return new CC1OptTable();
45}
Daniel Dunbar84e8a242009-11-19 20:54:59 +000046
47//
48
49using namespace clang;
50
Daniel Dunbarf7535122009-11-20 01:46:44 +000051static llvm::StringRef getLastArgValue(ArgList &Args, cc1options::ID ID,
52 llvm::StringRef Default = "") {
53 if (Arg *A = Args.getLastArg(ID))
54 return A->getValue(Args);
55 return Default;
56}
57
Daniel Dunbar69fd86d2009-11-20 17:23:30 +000058static int getLastArgIntValue(ArgList &Args, cc1options::ID ID,
59 int Default = 0) {
60 Arg *A = Args.getLastArg(ID);
61 if (!A)
62 return Default;
63
64 int Res = Default;
65 // FIXME: What to do about argument parsing errors?
66 if (llvm::StringRef(A->getValue(Args)).getAsInteger(10, Res))
67 llvm::errs() << "error: invalid integral argument in '"
68 << A->getAsString(Args) << "'\n";
69
70 return Res;
71}
72
Daniel Dunbarf7535122009-11-20 01:46:44 +000073static std::vector<std::string>
74getAllArgValues(ArgList &Args, cc1options::ID ID) {
75 llvm::SmallVector<const char *, 16> Values;
76 Args.AddAllArgValues(Values, ID);
77 return std::vector<std::string>(Values.begin(), Values.end());
78}
79
Daniel Dunbar69fd86d2009-11-20 17:23:30 +000080//
81
82static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args) {
83 // -Os implies -O2
84 if (Args.hasArg(cc1options::OPT_Os))
85 Opts.OptimizationLevel = 2;
86 else
87 Opts.OptimizationLevel = getLastArgIntValue(Args, cc1options::OPT_O);
88
89 // FIXME: What to do about argument parsing errors?
90 if (Opts.OptimizationLevel > 3) {
91 llvm::errs() << "error: invalid optimization level '"
92 << Opts.OptimizationLevel << "' (out of range)\n";
93 Opts.OptimizationLevel = 3;
94 }
95
96 // We must always run at least the always inlining pass.
97 Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
98 : CodeGenOptions::OnlyAlwaysInlining;
99
100 Opts.DebugInfo = Args.hasArg(cc1options::OPT_g);
101 Opts.DisableLLVMOpts = Args.hasArg(cc1options::OPT_disable_llvm_optzns);
102 Opts.DisableRedZone = Args.hasArg(cc1options::OPT_disable_red_zone);
103 Opts.MergeAllConstants = !Args.hasArg(cc1options::OPT_fno_merge_all_constants);
104 Opts.NoCommon = Args.hasArg(cc1options::OPT_fno_common);
105 Opts.NoImplicitFloat = Args.hasArg(cc1options::OPT_no_implicit_float);
106 Opts.OptimizeSize = Args.hasArg(cc1options::OPT_Os);
107 Opts.SimplifyLibCalls = 1;
108 Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize);
109
110 // FIXME: Implement!
111 // FIXME: Eliminate this dependency?
112// if (Lang.NoBuiltin)
113// Opts.SimplifyLibCalls = 0;
114// if (Lang.CPlusPlus)
115// Opts.NoCommon = 1;
116// Opts.TimePasses = TimePasses;
117
118 // FIXME: Put elsewhere?
119#ifdef NDEBUG
120 Opts.VerifyModule = 0;
121#endif
122}
123
Daniel Dunbarf7535122009-11-20 01:46:44 +0000124static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
125 Opts.ABI = getLastArgValue(Args, cc1options::OPT_target_abi);
126 Opts.CPU = getLastArgValue(Args, cc1options::OPT_mcpu);
127 Opts.Triple = getLastArgValue(Args, cc1options::OPT_triple);
128 Opts.Features = getAllArgValues(Args, cc1options::OPT_target_feature);
129
130 // Use the host triple if unspecified.
131 if (Opts.Triple.empty())
132 Opts.Triple = llvm::sys::getHostTriple();
133}
134
Daniel Dunbar69fd86d2009-11-20 17:23:30 +0000135//
136
Daniel Dunbar84e8a242009-11-19 20:54:59 +0000137void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
138 const llvm::SmallVectorImpl<llvm::StringRef> &Args) {
Daniel Dunbarf7535122009-11-20 01:46:44 +0000139 // This is gratuitous, but until we switch the driver to using StringRe we
140 // need to get C strings.
141 llvm::SmallVector<std::string, 16> StringArgs(Args.begin(), Args.end());
142 llvm::SmallVector<const char *, 16> CStringArgs;
143 for (unsigned i = 0, e = Args.size(); i != e; ++i)
144 CStringArgs.push_back(StringArgs[i].c_str());
145
146 // Parse the arguments.
147 llvm::OwningPtr<OptTable> Opts(createCC1OptTable());
148 unsigned MissingArgIndex, MissingArgCount;
149 llvm::OwningPtr<InputArgList> InputArgs(
150 Opts->ParseArgs(CStringArgs.begin(), CStringArgs.end(),
151 MissingArgIndex, MissingArgCount));
152
153 // Check for missing argument error.
154 if (MissingArgCount) {
155 // FIXME: Use proper diagnostics!
156 llvm::errs() << "error: argument to '"
157 << InputArgs->getArgString(MissingArgIndex)
158 << "' is missing (expected " << MissingArgCount
159 << " value )\n";
160 }
161
Daniel Dunbar69fd86d2009-11-20 17:23:30 +0000162 ParseCodeGenArgs(Res.getCodeGenOpts(), *InputArgs);
Daniel Dunbarf7535122009-11-20 01:46:44 +0000163 ParseTargetArgs(Res.getTargetOpts(), *InputArgs);
Daniel Dunbar84e8a242009-11-19 20:54:59 +0000164}