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, bool AddNewLine) 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, /*AddNewLine=*/false); 74 } 75 76 const Option Alias = getAlias(); 77 if (Alias.isValid()) { 78 O << " Alias:"; 79 Alias.print(O, /*AddNewLine=*/false); 80 } 81 82 if (getKind() == MultiArgClass) 83 O << " NumArgs:" << getNumArgs(); 84 85 O << ">"; 86 if (AddNewLine) 87 O << "\n"; 88 } 89 90 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 91 LLVM_DUMP_METHOD void Option::dump() const { print(dbgs()); } 92 #endif 93 94 bool Option::matches(OptSpecifier Opt) const { 95 // Aliases are never considered in matching, look through them. 96 const Option Alias = getAlias(); 97 if (Alias.isValid()) 98 return Alias.matches(Opt); 99 100 // Check exact match. 101 if (getID() == Opt.getID()) 102 return true; 103 104 const Option Group = getGroup(); 105 if (Group.isValid()) 106 return Group.matches(Opt); 107 return false; 108 } 109 110 std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args, 111 StringRef Spelling, 112 unsigned &Index) const { 113 const size_t SpellingSize = Spelling.size(); 114 const size_t ArgStringSize = StringRef(Args.getArgString(Index)).size(); 115 switch (getKind()) { 116 case FlagClass: { 117 if (SpellingSize != ArgStringSize) 118 return nullptr; 119 return std::make_unique<Arg>(*this, Spelling, Index++); 120 } 121 case JoinedClass: { 122 const char *Value = Args.getArgString(Index) + SpellingSize; 123 return std::make_unique<Arg>(*this, Spelling, Index++, Value); 124 } 125 case CommaJoinedClass: { 126 // Always matches. 127 const char *Str = Args.getArgString(Index) + SpellingSize; 128 auto A = std::make_unique<Arg>(*this, Spelling, Index++); 129 130 // Parse out the comma separated values. 131 const char *Prev = Str; 132 for (;; ++Str) { 133 char c = *Str; 134 135 if (!c || c == ',') { 136 if (Prev != Str) { 137 char *Value = new char[Str - Prev + 1]; 138 memcpy(Value, Prev, Str - Prev); 139 Value[Str - Prev] = '\0'; 140 A->getValues().push_back(Value); 141 } 142 143 if (!c) 144 break; 145 146 Prev = Str + 1; 147 } 148 } 149 A->setOwnsValues(true); 150 151 return A; 152 } 153 case SeparateClass: 154 // Matches iff this is an exact match. 155 if (SpellingSize != ArgStringSize) 156 return nullptr; 157 158 Index += 2; 159 if (Index > Args.getNumInputArgStrings() || 160 Args.getArgString(Index - 1) == nullptr) 161 return nullptr; 162 163 return std::make_unique<Arg>(*this, Spelling, Index - 2, 164 Args.getArgString(Index - 1)); 165 case MultiArgClass: { 166 // Matches iff this is an exact match. 167 if (SpellingSize != ArgStringSize) 168 return nullptr; 169 170 Index += 1 + getNumArgs(); 171 if (Index > Args.getNumInputArgStrings()) 172 return nullptr; 173 174 auto A = std::make_unique<Arg>(*this, Spelling, Index - 1 - getNumArgs(), 175 Args.getArgString(Index - getNumArgs())); 176 for (unsigned i = 1; i != getNumArgs(); ++i) 177 A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i)); 178 return A; 179 } 180 case JoinedOrSeparateClass: { 181 // If this is not an exact match, it is a joined arg. 182 if (SpellingSize != ArgStringSize) { 183 const char *Value = Args.getArgString(Index) + SpellingSize; 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) + SpellingSize, 205 Args.getArgString(Index - 1)); 206 case RemainingArgsClass: { 207 // Matches iff this is an exact match. 208 if (SpellingSize != ArgStringSize) 209 return nullptr; 210 auto A = std::make_unique<Arg>(*this, Spelling, Index++); 211 while (Index < Args.getNumInputArgStrings() && 212 Args.getArgString(Index) != nullptr) 213 A->getValues().push_back(Args.getArgString(Index++)); 214 return A; 215 } 216 case RemainingArgsJoinedClass: { 217 auto A = std::make_unique<Arg>(*this, Spelling, Index); 218 if (SpellingSize != ArgStringSize) { 219 // An inexact match means there is a joined arg. 220 A->getValues().push_back(Args.getArgString(Index) + SpellingSize); 221 } 222 Index++; 223 while (Index < Args.getNumInputArgStrings() && 224 Args.getArgString(Index) != nullptr) 225 A->getValues().push_back(Args.getArgString(Index++)); 226 return A; 227 } 228 229 default: 230 llvm_unreachable("Invalid option kind!"); 231 } 232 } 233 234 std::unique_ptr<Arg> Option::accept(const ArgList &Args, StringRef CurArg, 235 bool GroupedShortOption, 236 unsigned &Index) const { 237 auto A(GroupedShortOption && getKind() == FlagClass 238 ? std::make_unique<Arg>(*this, CurArg, Index) 239 : acceptInternal(Args, CurArg, Index)); 240 if (!A) 241 return nullptr; 242 243 const Option &UnaliasedOption = getUnaliasedOption(); 244 if (getID() == UnaliasedOption.getID()) 245 return A; 246 247 // "A" is an alias for a different flag. For most clients it's more convenient 248 // if this function returns unaliased Args, so create an unaliased arg for 249 // returning. 250 251 // This creates a completely new Arg object for the unaliased Arg because 252 // the alias and the unaliased arg can have different Kinds and different 253 // Values (due to AliasArgs<>). 254 255 // Get the spelling from the unaliased option. 256 StringRef UnaliasedSpelling = Args.MakeArgString( 257 Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName())); 258 259 // It's a bit weird that aliased and unaliased arg share one index, but 260 // the index is mostly use as a memory optimization in render(). 261 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling 262 // of the aliased arg always, while A->getSpelling() returns either the 263 // unaliased or the aliased arg, depending on which Arg object it's called on. 264 auto UnaliasedA = 265 std::make_unique<Arg>(UnaliasedOption, UnaliasedSpelling, A->getIndex()); 266 Arg *RawA = A.get(); 267 UnaliasedA->setAlias(std::move(A)); 268 269 if (getKind() != FlagClass) { 270 // Values are usually owned by the ArgList. The exception are 271 // CommaJoined flags, where the Arg owns the values. For aliased flags, 272 // make the unaliased Arg the owner of the values. 273 // FIXME: There aren't many uses of CommaJoined -- try removing 274 // CommaJoined in favor of just calling StringRef::split(',') instead. 275 UnaliasedA->getValues() = RawA->getValues(); 276 UnaliasedA->setOwnsValues(RawA->getOwnsValues()); 277 RawA->setOwnsValues(false); 278 return UnaliasedA; 279 } 280 281 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg. 282 if (const char *Val = getAliasArgs()) { 283 while (*Val != '\0') { 284 UnaliasedA->getValues().push_back(Val); 285 286 // Move past the '\0' to the next argument. 287 Val += strlen(Val) + 1; 288 } 289 } 290 if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs()) 291 // A Flag alias for a Joined option must provide an argument. 292 UnaliasedA->getValues().push_back(""); 293 return UnaliasedA; 294 } 295