blob: 503b54d8fe63fada024f5f8f3804ab3e639324e2 [file] [log] [blame]
Daniel Dunbar1eb4e642009-03-03 05:55:11 +00001//===--- Option.cpp - Abstract Driver Options ---------------------------*-===//
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/Option.h"
Daniel Dunbarbbf842b2009-03-04 23:22:02 +000011
12#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000014#include "llvm/Support/raw_ostream.h"
Daniel Dunbar1eb4e642009-03-03 05:55:11 +000015#include <cassert>
Daniel Dunbarbbf842b2009-03-04 23:22:02 +000016#include <algorithm>
Daniel Dunbar1eb4e642009-03-03 05:55:11 +000017using namespace clang::driver;
18
Daniel Dunbar30b055f2009-03-04 21:53:04 +000019Option::Option(OptionClass _Kind, options::ID _ID, const char *_Name,
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000020 const OptionGroup *_Group, const Option *_Alias)
Daniel Dunbar30b055f2009-03-04 21:53:04 +000021 : Kind(_Kind), ID(_ID), Name(_Name), Group(_Group), Alias(_Alias),
Daniel Dunbar0f9098e2009-03-04 21:05:23 +000022 Unsupported(false), LinkerInput(false), NoOptAsInput(false),
23 ForceSeparateRender(false), ForceJoinedRender(false)
24{
Daniel Dunbar1eb4e642009-03-03 05:55:11 +000025
26 // Multi-level aliases are not supported, and alias options cannot
27 // have groups. This just simplifies option tracking, it is not an
28 // inherent limitation.
29 assert((!Alias || (!Alias->Alias && !Group)) &&
30 "Multi-level aliases and aliases with groups are unsupported.");
31}
32
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +000033Option::~Option() {
34}
35
36void Option::dump() const {
37 llvm::errs() << "<";
38 switch (Kind) {
39 default:
40 assert(0 && "Invalid kind");
41#define P(N) case N: llvm::errs() << #N; break
42 P(GroupClass);
43 P(InputClass);
44 P(UnknownClass);
45 P(FlagClass);
46 P(JoinedClass);
47 P(SeparateClass);
48 P(CommaJoinedClass);
49 P(MultiArgClass);
50 P(JoinedOrSeparateClass);
51 P(JoinedAndSeparateClass);
52#undef P
53 }
54
55 llvm::errs() << " Name:\"" << Name << '"';
56
57 if (Group) {
58 llvm::errs() << " Group:";
59 Group->dump();
60 }
61
62 if (Alias) {
63 llvm::errs() << " Alias:";
64 Alias->dump();
65 }
66
67 if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
68 llvm::errs() << " NumArgs:" << MOA->getNumArgs();
69
70 llvm::errs() << ">\n";
71}
72
Daniel Dunbar1eb4e642009-03-03 05:55:11 +000073bool Option::matches(const Option *Opt) const {
74 // Aliases are never considered in matching.
75 if (Opt->getAlias())
76 return matches(Opt->getAlias());
77 if (Alias)
78 return Alias->matches(Opt);
79
80 if (this == Opt)
81 return true;
82
83 if (Group)
84 return Group->matches(Opt);
85 return false;
86}
87
Daniel Dunbarcf0dd152009-03-12 01:34:20 +000088bool Option::matches(options::ID Id) const {
89 // FIXME: Decide what to do here; we should either pull out the
90 // handling of alias on the option for Id from the other matches, or
91 // find some other solution (which hopefully doesn't require using
92 // the option table).
93 if (Alias)
94 return Alias->matches(Id);
95
96 if (ID == Id)
97 return true;
98
99 if (Group)
100 return Group->matches(Id);
101 return false;
102}
103
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000104OptionGroup::OptionGroup(options::ID ID, const char *Name,
105 const OptionGroup *Group)
106 : Option(Option::GroupClass, ID, Name, Group, 0) {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000107}
108
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000109Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000110 assert(0 && "FIXME");
111 return 0;
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000112}
113
114InputOption::InputOption()
Daniel Dunbarb349fcc2009-03-12 03:42:54 +0000115 : Option(Option::InputClass, options::OPT_INPUT, "<input>", 0, 0) {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000116}
117
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000118Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000119 assert(0 && "FIXME");
120 return 0;
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000121}
122
123UnknownOption::UnknownOption()
Daniel Dunbarb349fcc2009-03-12 03:42:54 +0000124 : Option(Option::UnknownClass, options::OPT_UNKNOWN, "<unknown>", 0, 0) {
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000125}
126
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000127Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000128 assert(0 && "FIXME");
129 return 0;
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000130}
131
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000132FlagOption::FlagOption(options::ID ID, const char *Name,
133 const OptionGroup *Group, const Option *Alias)
134 : Option(Option::FlagClass, ID, Name, Group, Alias) {
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000135}
136
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000137Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000138 // Matches iff this is an exact match.
139 // FIXME: Avoid strlen.
140 if (strlen(getName()) != strlen(Args.getArgString(Index)))
141 return 0;
142
Daniel Dunbar06482622009-03-05 06:38:47 +0000143 return new FlagArg(this, Index++);
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000144}
145
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000146JoinedOption::JoinedOption(options::ID ID, const char *Name,
147 const OptionGroup *Group, const Option *Alias)
148 : Option(Option::JoinedClass, ID, Name, Group, Alias) {
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000149}
150
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000151Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000152 // Always matches.
153 return new JoinedArg(this, Index++);
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000154}
155
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000156CommaJoinedOption::CommaJoinedOption(options::ID ID, const char *Name,
157 const OptionGroup *Group,
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000158 const Option *Alias)
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000159 : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000160}
161
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000162Arg *CommaJoinedOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000163 // Always matches. We count the commas now so we can answer
164 // getNumValues easily.
165
166 // Get the suffix string.
167 // FIXME: Avoid strlen, and move to helper method?
168 const char *Suffix = Args.getArgString(Index) + strlen(getName());
Daniel Dunbar06482622009-03-05 06:38:47 +0000169 return new CommaJoinedArg(this, Index++, Suffix);
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000170}
171
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000172SeparateOption::SeparateOption(options::ID ID, const char *Name,
173 const OptionGroup *Group, const Option *Alias)
174 : Option(Option::SeparateClass, ID, Name, Group, Alias) {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000175}
176
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000177Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000178 // Matches iff this is an exact match.
179 // FIXME: Avoid strlen.
180 if (strlen(getName()) != strlen(Args.getArgString(Index)))
181 return 0;
182
183 // FIXME: Missing argument error.
184 Index += 2;
185 return new SeparateArg(this, Index - 2, 1);
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000186}
187
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000188MultiArgOption::MultiArgOption(options::ID ID, const char *Name,
189 const OptionGroup *Group, const Option *Alias,
190 unsigned _NumArgs)
191 : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
Daniel Dunbar644eade2009-03-12 05:46:32 +0000192 assert(NumArgs > 1 && "Invalid MultiArgOption!");
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000193}
194
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000195Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000196 // Matches iff this is an exact match.
197 // FIXME: Avoid strlen.
198 if (strlen(getName()) != strlen(Args.getArgString(Index)))
199 return 0;
200
201 // FIXME: Missing argument error.
202 Index += 1 + NumArgs;
203 return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000204}
205
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000206JoinedOrSeparateOption::JoinedOrSeparateOption(options::ID ID, const char *Name,
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000207 const OptionGroup *Group,
208 const Option *Alias)
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000209 : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000210}
211
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000212Arg *JoinedOrSeparateOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000213 // If this is not an exact match, it is a joined arg.
214 // FIXME: Avoid strlen.
215 if (strlen(getName()) != strlen(Args.getArgString(Index)))
216 return new JoinedArg(this, Index++);
217
218 // Otherwise it must be separate.
219 // FIXME: Missing argument error.
220 Index += 2;
221 return new SeparateArg(this, Index - 2, 1);
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000222}
223
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000224JoinedAndSeparateOption::JoinedAndSeparateOption(options::ID ID,
225 const char *Name,
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000226 const OptionGroup *Group,
227 const Option *Alias)
Daniel Dunbar30b055f2009-03-04 21:53:04 +0000228 : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000229}
230
Daniel Dunbar3c9cc6b2009-03-04 20:53:00 +0000231Arg *JoinedAndSeparateOption::accept(const ArgList &Args, unsigned &Index) const {
Daniel Dunbarbbf842b2009-03-04 23:22:02 +0000232 // Always matches.
233
234 // FIXME: Missing argument error.
235 Index += 2;
236 return new JoinedAndSeparateArg(this, Index - 2);
Daniel Dunbar2c6f6f32009-03-04 08:33:23 +0000237}
Daniel Dunbar1eb4e642009-03-03 05:55:11 +0000238