[AArch64] Check Dest Register Liveness in CondOpt pass.
[oota-llvm.git] / lib / Option / 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 "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"
16 #include <algorithm>
17 #include <cassert>
18
19 using namespace llvm;
20 using namespace llvm::opt;
21
22 Option::Option(const OptTable::Info *info, const OptTable *owner)
23   : Info(info), Owner(owner) {
24
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.");
29
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.");
35   }
36 }
37
38 Option::~Option() {
39 }
40
41 void Option::dump() const {
42   llvm::errs() << "<";
43   switch (getKind()) {
44 #define P(N) case N: llvm::errs() << #N; break
45     P(GroupClass);
46     P(InputClass);
47     P(UnknownClass);
48     P(FlagClass);
49     P(JoinedClass);
50     P(SeparateClass);
51     P(CommaJoinedClass);
52     P(MultiArgClass);
53     P(JoinedOrSeparateClass);
54     P(JoinedAndSeparateClass);
55     P(RemainingArgsClass);
56 #undef P
57   }
58
59   if (Info->Prefixes) {
60     llvm::errs() << " Prefixes:[";
61     for (const char * const *Pre = Info->Prefixes; *Pre != nullptr; ++Pre) {
62       llvm::errs() << '"' << *Pre << (*(Pre + 1) == nullptr ? "\"" : "\", ");
63     }
64     llvm::errs() << ']';
65   }
66
67   llvm::errs() << " Name:\"" << getName() << '"';
68
69   const Option Group = getGroup();
70   if (Group.isValid()) {
71     llvm::errs() << " Group:";
72     Group.dump();
73   }
74
75   const Option Alias = getAlias();
76   if (Alias.isValid()) {
77     llvm::errs() << " Alias:";
78     Alias.dump();
79   }
80
81   if (getKind() == MultiArgClass)
82     llvm::errs() << " NumArgs:" << getNumArgs();
83
84   llvm::errs() << ">\n";
85 }
86
87 bool Option::matches(OptSpecifier Opt) const {
88   // Aliases are never considered in matching, look through them.
89   const Option Alias = getAlias();
90   if (Alias.isValid())
91     return Alias.matches(Opt);
92
93   // Check exact match.
94   if (getID() == Opt.getID())
95     return true;
96
97   const Option Group = getGroup();
98   if (Group.isValid())
99     return Group.matches(Opt);
100   return false;
101 }
102
103 Arg *Option::accept(const ArgList &Args,
104                     unsigned &Index,
105                     unsigned ArgSize) const {
106   const Option &UnaliasedOption = getUnaliasedOption();
107   StringRef Spelling;
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);
111   } else {
112     Spelling = Args.MakeArgString(Twine(UnaliasedOption.getPrefix()) +
113                                   Twine(UnaliasedOption.getName()));
114   }
115
116   switch (getKind()) {
117   case FlagClass: {
118     if (ArgSize != strlen(Args.getArgString(Index)))
119       return nullptr;
120
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);
126
127         // Move past the '\0' to the next argument.
128         Val += strlen(Val) + 1;
129       }
130     }
131     return A;
132   }
133   case JoinedClass: {
134     const char *Value = Args.getArgString(Index) + ArgSize;
135     return new Arg(UnaliasedOption, Spelling, Index++, Value);
136   }
137   case CommaJoinedClass: {
138     // Always matches.
139     const char *Str = Args.getArgString(Index) + ArgSize;
140     Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
141
142     // Parse out the comma separated values.
143     const char *Prev = Str;
144     for (;; ++Str) {
145       char c = *Str;
146
147       if (!c || c == ',') {
148         if (Prev != Str) {
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);
153         }
154
155         if (!c)
156           break;
157
158         Prev = Str + 1;
159       }
160     }
161     A->setOwnsValues(true);
162
163     return A;
164   }
165   case SeparateClass:
166     // Matches iff this is an exact match.
167     // FIXME: Avoid strlen.
168     if (ArgSize != strlen(Args.getArgString(Index)))
169       return nullptr;
170
171     Index += 2;
172     if (Index > Args.getNumInputArgStrings() ||
173         Args.getArgString(Index - 1) == nullptr)
174       return nullptr;
175
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)))
182       return nullptr;
183
184     Index += 1 + getNumArgs();
185     if (Index > Args.getNumInputArgStrings())
186       return nullptr;
187
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));
192     return A;
193   }
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);
200     }
201
202     // Otherwise it must be separate.
203     Index += 2;
204     if (Index > Args.getNumInputArgStrings() ||
205         Args.getArgString(Index - 1) == nullptr)
206       return nullptr;
207
208     return new Arg(UnaliasedOption, Spelling,
209                    Index - 2, Args.getArgString(Index - 1));
210   }
211   case JoinedAndSeparateClass:
212     // Always matches.
213     Index += 2;
214     if (Index > Args.getNumInputArgStrings() ||
215         Args.getArgString(Index - 1) == nullptr)
216       return nullptr;
217
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)))
225       return nullptr;
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++));
230     return A;
231   }
232   default:
233     llvm_unreachable("Invalid option kind!");
234   }
235 }