]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Option/Option.cpp
1 //===--- Option.cpp - Abstract Driver Options -----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Option/Option.h"
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/Option/Arg.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Support/ErrorHandling.h"
15 #include "llvm/Support/raw_ostream.h"
20 using namespace llvm::opt
;
22 Option::Option(const OptTable::Info
*info
, const OptTable
*owner
)
23 : Info(info
), Owner(owner
) {
25 // Multi-level aliases are not supported. This just simplifies option
26 // tracking, it is not an inherent limitation.
27 assert((!Info
|| !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
28 "Multi-level aliases are not supported.");
30 if (Info
&& getAliasArgs()) {
31 assert(getAlias().isValid() && "Only alias options can have alias args.");
32 assert(getKind() == FlagClass
&& "Only Flag aliases can have alias args.");
33 assert(getAlias().getKind() != FlagClass
&&
34 "Cannot provide alias args to a flag option.");
41 void Option::dump() const {
44 #define P(N) case N: llvm::errs() << #N; break
53 P(JoinedOrSeparateClass
);
54 P(JoinedAndSeparateClass
);
55 P(RemainingArgsClass
);
60 llvm::errs() << " Prefixes:[";
61 for (const char * const *Pre
= Info
->Prefixes
; *Pre
!= nullptr; ++Pre
) {
62 llvm::errs() << '"' << *Pre
<< (*(Pre
+ 1) == nullptr ? "\"" : "\", ");
67 llvm::errs() << " Name:\"" << getName() << '"';
69 const Option Group
= getGroup();
70 if (Group
.isValid()) {
71 llvm::errs() << " Group:";
75 const Option Alias
= getAlias();
76 if (Alias
.isValid()) {
77 llvm::errs() << " Alias:";
81 if (getKind() == MultiArgClass
)
82 llvm::errs() << " NumArgs:" << getNumArgs();
84 llvm::errs() << ">\n";
87 bool Option::matches(OptSpecifier Opt
) const {
88 // Aliases are never considered in matching, look through them.
89 const Option Alias
= getAlias();
91 return Alias
.matches(Opt
);
94 if (getID() == Opt
.getID())
97 const Option Group
= getGroup();
99 return Group
.matches(Opt
);
103 Arg
*Option::accept(const ArgList
&Args
,
105 unsigned ArgSize
) const {
106 const Option
&UnaliasedOption
= getUnaliasedOption();
108 // If the option was an alias, get the spelling from the unaliased one.
109 if (getID() == UnaliasedOption
.getID()) {
110 Spelling
= StringRef(Args
.getArgString(Index
), ArgSize
);
112 Spelling
= Args
.MakeArgString(Twine(UnaliasedOption
.getPrefix()) +
113 Twine(UnaliasedOption
.getName()));
118 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
121 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
++);
122 if (getAliasArgs()) {
123 const char *Val
= getAliasArgs();
124 while (*Val
!= '\0') {
125 A
->getValues().push_back(Val
);
127 // Move past the '\0' to the next argument.
128 Val
+= strlen(Val
) + 1;
134 const char *Value
= Args
.getArgString(Index
) + ArgSize
;
135 return new Arg(UnaliasedOption
, Spelling
, Index
++, Value
);
137 case CommaJoinedClass
: {
139 const char *Str
= Args
.getArgString(Index
) + ArgSize
;
140 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
++);
142 // Parse out the comma separated values.
143 const char *Prev
= Str
;
147 if (!c
|| c
== ',') {
149 char *Value
= new char[Str
- Prev
+ 1];
150 memcpy(Value
, Prev
, Str
- Prev
);
151 Value
[Str
- Prev
] = '\0';
152 A
->getValues().push_back(Value
);
161 A
->setOwnsValues(true);
166 // Matches iff this is an exact match.
167 // FIXME: Avoid strlen.
168 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
172 if (Index
> Args
.getNumInputArgStrings() ||
173 Args
.getArgString(Index
- 1) == nullptr)
176 return new Arg(UnaliasedOption
, Spelling
,
177 Index
- 2, Args
.getArgString(Index
- 1));
178 case MultiArgClass
: {
179 // Matches iff this is an exact match.
180 // FIXME: Avoid strlen.
181 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
184 Index
+= 1 + getNumArgs();
185 if (Index
> Args
.getNumInputArgStrings())
188 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
- 1 - getNumArgs(),
189 Args
.getArgString(Index
- getNumArgs()));
190 for (unsigned i
= 1; i
!= getNumArgs(); ++i
)
191 A
->getValues().push_back(Args
.getArgString(Index
- getNumArgs() + i
));
194 case JoinedOrSeparateClass
: {
195 // If this is not an exact match, it is a joined arg.
196 // FIXME: Avoid strlen.
197 if (ArgSize
!= strlen(Args
.getArgString(Index
))) {
198 const char *Value
= Args
.getArgString(Index
) + ArgSize
;
199 return new Arg(*this, Spelling
, Index
++, Value
);
202 // Otherwise it must be separate.
204 if (Index
> Args
.getNumInputArgStrings() ||
205 Args
.getArgString(Index
- 1) == nullptr)
208 return new Arg(UnaliasedOption
, Spelling
,
209 Index
- 2, Args
.getArgString(Index
- 1));
211 case JoinedAndSeparateClass
:
214 if (Index
> Args
.getNumInputArgStrings() ||
215 Args
.getArgString(Index
- 1) == nullptr)
218 return new Arg(UnaliasedOption
, Spelling
, Index
- 2,
219 Args
.getArgString(Index
- 2) + ArgSize
,
220 Args
.getArgString(Index
- 1));
221 case RemainingArgsClass
: {
222 // Matches iff this is an exact match.
223 // FIXME: Avoid strlen.
224 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
226 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
++);
227 while (Index
< Args
.getNumInputArgStrings() &&
228 Args
.getArgString(Index
) != nullptr)
229 A
->getValues().push_back(Args
.getArgString(Index
++));
233 llvm_unreachable("Invalid option kind!");