]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Driver/Option.cpp
Update clang to r89337.
[FreeBSD/FreeBSD.git] / lib / Driver / Option.cpp
1 //===--- 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"
11
12 #include "clang/Driver/Arg.h"
13 #include "clang/Driver/ArgList.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include <cassert>
16 #include <algorithm>
17 using namespace clang::driver;
18
19 Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
20                const OptionGroup *_Group, const Option *_Alias)
21   : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
22     Unsupported(false), LinkerInput(false), NoOptAsInput(false),
23     ForceSeparateRender(false), ForceJoinedRender(false),
24     DriverOption(false), NoArgumentUnused(false) {
25
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
33 Option::~Option() {
34 }
35
36 void 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
73 bool Option::matches(OptSpecifier Opt) const {
74   // Aliases are never considered in matching, look through them.
75   if (Alias)
76     return Alias->matches(Opt);
77
78   // Check exact match.
79   if (ID == Opt)
80     return true;
81
82   if (Group)
83     return Group->matches(Opt);
84   return false;
85 }
86
87 OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
88                          const OptionGroup *Group)
89   : Option(Option::GroupClass, ID, Name, Group, 0) {
90 }
91
92 Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
93   assert(0 && "accept() should never be called on an OptionGroup");
94   return 0;
95 }
96
97 InputOption::InputOption(OptSpecifier ID)
98   : Option(Option::InputClass, ID, "<input>", 0, 0) {
99 }
100
101 Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
102   assert(0 && "accept() should never be called on an InputOption");
103   return 0;
104 }
105
106 UnknownOption::UnknownOption(OptSpecifier ID)
107   : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
108 }
109
110 Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
111   assert(0 && "accept() should never be called on an UnknownOption");
112   return 0;
113 }
114
115 FlagOption::FlagOption(OptSpecifier ID, const char *Name,
116                        const OptionGroup *Group, const Option *Alias)
117   : Option(Option::FlagClass, ID, Name, Group, Alias) {
118 }
119
120 Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
121   // Matches iff this is an exact match.
122   // FIXME: Avoid strlen.
123   if (strlen(getName()) != strlen(Args.getArgString(Index)))
124     return 0;
125
126   return new FlagArg(this, Index++);
127 }
128
129 JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
130                            const OptionGroup *Group, const Option *Alias)
131   : Option(Option::JoinedClass, ID, Name, Group, Alias) {
132 }
133
134 Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
135   // Always matches.
136   return new JoinedArg(this, Index++);
137 }
138
139 CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
140                                      const OptionGroup *Group,
141                                      const Option *Alias)
142   : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
143 }
144
145 Arg *CommaJoinedOption::accept(const InputArgList &Args,
146                                unsigned &Index) const {
147   // Always matches. We count the commas now so we can answer
148   // getNumValues easily.
149
150   // Get the suffix string.
151   // FIXME: Avoid strlen, and move to helper method?
152   const char *Suffix = Args.getArgString(Index) + strlen(getName());
153   return new CommaJoinedArg(this, Index++, Suffix);
154 }
155
156 SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
157                                const OptionGroup *Group, const Option *Alias)
158   : Option(Option::SeparateClass, ID, Name, Group, Alias) {
159 }
160
161 Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
162   // Matches iff this is an exact match.
163   // FIXME: Avoid strlen.
164   if (strlen(getName()) != strlen(Args.getArgString(Index)))
165     return 0;
166
167   Index += 2;
168   if (Index > Args.getNumInputArgStrings())
169     return 0;
170
171   return new SeparateArg(this, Index - 2, 1);
172 }
173
174 MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
175                                const OptionGroup *Group, const Option *Alias,
176                                unsigned _NumArgs)
177   : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
178   assert(NumArgs > 1  && "Invalid MultiArgOption!");
179 }
180
181 Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
182   // Matches iff this is an exact match.
183   // FIXME: Avoid strlen.
184   if (strlen(getName()) != strlen(Args.getArgString(Index)))
185     return 0;
186
187   Index += 1 + NumArgs;
188   if (Index > Args.getNumInputArgStrings())
189     return 0;
190
191   return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
192 }
193
194 JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
195                                                const OptionGroup *Group,
196                                                const Option *Alias)
197   : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
198 }
199
200 Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
201                                     unsigned &Index) const {
202   // If this is not an exact match, it is a joined arg.
203   // FIXME: Avoid strlen.
204   if (strlen(getName()) != strlen(Args.getArgString(Index)))
205     return new JoinedArg(this, Index++);
206
207   // Otherwise it must be separate.
208   Index += 2;
209   if (Index > Args.getNumInputArgStrings())
210     return 0;
211
212   return new SeparateArg(this, Index - 2, 1);
213 }
214
215 JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
216                                                  const char *Name,
217                                                  const OptionGroup *Group,
218                                                  const Option *Alias)
219   : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
220 }
221
222 Arg *JoinedAndSeparateOption::accept(const InputArgList &Args,
223                                      unsigned &Index) const {
224   // Always matches.
225
226   Index += 2;
227   if (Index > Args.getNumInputArgStrings())
228     return 0;
229
230   return new JoinedAndSeparateArg(this, Index - 2);
231 }
232