1 //===- Option.cpp - Abstract Driver Options -------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/StringRef.h" 10 #include "llvm/ADT/Twine.h" 11 #include "llvm/Config/llvm-config.h" 12 #include "llvm/Option/Arg.h" 13 #include "llvm/Option/ArgList.h" 14 #include "llvm/Option/Option.h" 15 #include "llvm/Option/OptTable.h" 16 #include "llvm/Support/Compiler.h" 17 #include "llvm/Support/Debug.h" 18 #include "llvm/Support/ErrorHandling.h" 19 #include "llvm/Support/raw_ostream.h" 20 #include <cassert> 21 #include <cstring> 22 23 using namespace llvm; 24 using namespace llvm::opt; 25 26 Option::Option(const OptTable::Info *info, const OptTable *owner) 27 : Info(info), Owner(owner) { 28 // Multi-level aliases are not supported. This just simplifies option 29 // tracking, it is not an inherent limitation. 30 assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) && 31 "Multi-level aliases are not supported."); 32 33 if (Info && getAliasArgs()) { 34 assert(getAlias().isValid() && "Only alias options can have alias args."); 35 assert(getKind() == FlagClass && "Only Flag aliases can have alias args."); 36 assert(getAlias().getKind() != FlagClass && 37 "Cannot provide alias args to a flag option."); 38 } 39 } 40 41 void Option::print(raw_ostream &O) const { 42 O << "<"; 43 switch (getKind()) { 44 #define P(N) case N: O << #N; break 45 P(GroupClass); 46 P(InputClass); 47 P(UnknownClass); 48 P(FlagClass); 49 P(JoinedClass); 50 P(ValuesClass); 51 P(SeparateClass); 52 P(CommaJoinedClass); 53 P(MultiArgClass); 54 P(JoinedOrSeparateClass); 55 P(JoinedAndSeparateClass); 56 P(RemainingArgsClass); 57 P(RemainingArgsJoinedClass); 58 #undef P 59 } 60 61 if (!Info->Prefixes.empty()) { 62 O << " Prefixes:["; 63 for (size_t I = 0, N = Info->Prefixes.size(); I != N; ++I) 64 O << '"' << Info->Prefixes[I] << (I == N - 1 ? "\"" : "\", "); 65 O << ']'; 66 } 67 68 O << " Name:\"" << getName() << '"'; 69 70 const Option Group = getGroup(); 71 if (Group.isValid()) { 72 O << " Group:"; 73 Group.print(O); 74 } 75 76 const Option Alias = getAlias(); 77 if (Alias.isValid()) { 78 O << " Alias:"; 79 Alias.print(O); 80 } 81 82 if (getKind() == MultiArgClass) 83 O << " NumArgs:" << getNumArgs(); 84 85 O << ">\n"; 86 } 87 88 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 89 LLVM_DUMP_METHOD void Option::dump() const { print(dbgs()); } 90 #endif 91 92 bool Option::matches(OptSpecifier Opt) const { 93 // Aliases are never considered in matching, look through them. 94 const Option Alias = getAlias(); 95 if (Alias.isValid()) 96 return Alias.matches(Opt); 97 98 // Check exact match. 99 if (getID() == Opt.getID()) 100 return true; 101 102 const Option Group = getGroup(); 103 if (Group.isValid()) 104 return Group.matches(Opt); 105 return false; 106 } 107 108 std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args, 109 StringRef Spelling, 110 unsigned &Index) const { 111 size_t ArgSize = Spelling.size(); 112 switch (getKind()) { 113 case FlagClass: { 114 if (ArgSize != strlen(Args.getArgString(Index))) 115 return nullptr; 116 return std::make_unique<Arg>(*this, Spelling, Index++); 117 } 118 case JoinedClass: { 119 const char *Value = Args.getArgString(Index) + ArgSize; 120 return std::make_unique<Arg>(*this, Spelling, Index++, Value); 121 } 122 case CommaJoinedClass: { 123 // Always matches. 124 const char *Str = Args.getArgString(Index) + ArgSize; 125 auto A = std::make_unique<Arg>(*this, Spelling, Index++); 126 127 // Parse out the comma separated values. 128 const char *Prev = Str; 129 for (;; ++Str) { 130 char c = *Str; 131 132 if (!c || c == ',') { 133 if (Prev != Str) { 134 char *Value = new char[Str - Prev + 1]; 135 memcpy(Value, Prev, Str - Prev); 136 Value[Str - Prev] = '\0'; 137 A->getValues().push_back(Value); 138 } 139 140 if (!c) 141 break; 142 143 Prev = Str + 1; 144 } 145 } 146 A->setOwnsValues(true); 147 148 return A; 149 } 150 case SeparateClass: 151 // Matches iff this is an exact match. 152 // FIXME: Avoid strlen. 153 if (ArgSize != strlen(Args.getArgString(Index))) 154 return nullptr; 155 156 Index += 2; 157 if (Index > Args.getNumInputArgStrings() || 158 Args.getArgString(Index - 1) == nullptr) 159 return nullptr; 160 161 return std::make_unique<Arg>(*this, Spelling, Index - 2, 162 Args.getArgString(Index - 1)); 163 case MultiArgClass: { 164 // Matches iff this is an exact match. 165 // FIXME: Avoid strlen. 166 if (ArgSize != strlen(Args.getArgString(Index))) 167 return nullptr; 168 169 Index += 1 + getNumArgs(); 170 if (Index > Args.getNumInputArgStrings()) 171 return nullptr; 172 173 auto A = std::make_unique<Arg>(*this, Spelling, Index - 1 - getNumArgs(), 174 Args.getArgString(Index - getNumArgs())); 175 for (unsigned i = 1; i != getNumArgs(); ++i) 176 A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i)); 177 return A; 178 } 179 case JoinedOrSeparateClass: { 180 // If this is not an exact match, it is a joined arg. 181 // FIXME: Avoid strlen. 182 if (ArgSize != strlen(Args.getArgString(Index))) { 183 const char *Value = Args.getArgString(Index) + ArgSize; 184 return std::make_unique<Arg>(*this, Spelling, Index++, Value); 185 } 186 187 // Otherwise it must be separate. 188 Index += 2; 189 if (Index > Args.getNumInputArgStrings() || 190 Args.getArgString(Index - 1) == nullptr) 191 return nullptr; 192 193 return std::make_unique<Arg>(*this, Spelling, Index - 2, 194 Args.getArgString(Index - 1)); 195 } 196 case JoinedAndSeparateClass: 197 // Always matches. 198 Index += 2; 199 if (Index > Args.getNumInputArgStrings() || 200 Args.getArgString(Index - 1) == nullptr) 201 return nullptr; 202 203 return std::make_unique<Arg>(*this, Spelling, Index - 2, 204 Args.getArgString(Index - 2) + ArgSize, 205 Args.getArgString(Index - 1)); 206 case RemainingArgsClass: { 207 // Matches iff this is an exact match. 208 // FIXME: Avoid strlen. 209 if (ArgSize != strlen(Args.getArgString(Index))) 210 return nullptr; 211 auto A = std::make_unique<Arg>(*this, Spelling, Index++); 212 while (Index < Args.getNumInputArgStrings() && 213 Args.getArgString(Index) != nullptr) 214 A->getValues().push_back(Args.getArgString(Index++)); 215 return A; 216 } 217 case RemainingArgsJoinedClass: { 218 auto A = std::make_unique<Arg>(*this, Spelling, Index); 219 if (ArgSize != strlen(Args.getArgString(Index))) { 220 // An inexact match means there is a joined arg. 221 A->getValues().push_back(Args.getArgString(Index) + ArgSize); 222 } 223 Index++; 224 while (Index < Args.getNumInputArgStrings() && 225 Args.getArgString(Index) != nullptr) 226 A->getValues().push_back(Args.getArgString(Index++)); 227 return A; 228 } 229 230 default: 231 llvm_unreachable("Invalid option kind!"); 232 } 233 } 234 235 std::unique_ptr<Arg> Option::accept(const ArgList &Args, StringRef CurArg, 236 bool GroupedShortOption, 237 unsigned &Index) const { 238 auto A(GroupedShortOption && getKind() == FlagClass 239 ? std::make_unique<Arg>(*this, CurArg, Index) 240 : acceptInternal(Args, CurArg, Index)); 241 if (!A) 242 return nullptr; 243 244 const Option &UnaliasedOption = getUnaliasedOption(); 245 if (getID() == UnaliasedOption.getID()) 246 return A; 247 248 // "A" is an alias for a different flag. For most clients it's more convenient 249 // if this function returns unaliased Args, so create an unaliased arg for 250 // returning. 251 252 // This creates a completely new Arg object for the unaliased Arg because 253 // the alias and the unaliased arg can have different Kinds and different 254 // Values (due to AliasArgs<>). 255 256 // Get the spelling from the unaliased option. 257 StringRef UnaliasedSpelling = Args.MakeArgString( 258 Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName())); 259 260 // It's a bit weird that aliased and unaliased arg share one index, but 261 // the index is mostly use as a memory optimization in render(). 262 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling 263 // of the aliased arg always, while A->getSpelling() returns either the 264 // unaliased or the aliased arg, depending on which Arg object it's called on. 265 auto UnaliasedA = 266 std::make_unique<Arg>(UnaliasedOption, UnaliasedSpelling, A->getIndex()); 267 Arg *RawA = A.get(); 268 UnaliasedA->setAlias(std::move(A)); 269 270 if (getKind() != FlagClass) { 271 // Values are usually owned by the ArgList. The exception are 272 // CommaJoined flags, where the Arg owns the values. For aliased flags, 273 // make the unaliased Arg the owner of the values. 274 // FIXME: There aren't many uses of CommaJoined -- try removing 275 // CommaJoined in favor of just calling StringRef::split(',') instead. 276 UnaliasedA->getValues() = RawA->getValues(); 277 UnaliasedA->setOwnsValues(RawA->getOwnsValues()); 278 RawA->setOwnsValues(false); 279 return UnaliasedA; 280 } 281 282 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg. 283 if (const char *Val = getAliasArgs()) { 284 while (*Val != '\0') { 285 UnaliasedA->getValues().push_back(Val); 286 287 // Move past the '\0' to the next argument. 288 Val += strlen(Val) + 1; 289 } 290 } 291 if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs()) 292 // A Flag alias for a Joined option must provide an argument. 293 UnaliasedA->getValues().push_back(""); 294 return UnaliasedA; 295 } 296