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