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) { 62 O << " Prefixes:["; 63 for (const char *const *Pre = Info->Prefixes; *Pre != nullptr; ++Pre) { 64 O << '"' << *Pre << (*(Pre + 1) == nullptr ? "\"" : "\", "); 65 } 66 O << ']'; 67 } 68 69 O << " Name:\"" << getName() << '"'; 70 71 const Option Group = getGroup(); 72 if (Group.isValid()) { 73 O << " Group:"; 74 Group.print(O); 75 } 76 77 const Option Alias = getAlias(); 78 if (Alias.isValid()) { 79 O << " Alias:"; 80 Alias.print(O); 81 } 82 83 if (getKind() == MultiArgClass) 84 O << " NumArgs:" << getNumArgs(); 85 86 O << ">\n"; 87 } 88 89 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 90 LLVM_DUMP_METHOD void Option::dump() const { print(dbgs()); } 91 #endif 92 93 bool Option::matches(OptSpecifier Opt) const { 94 // Aliases are never considered in matching, look through them. 95 const Option Alias = getAlias(); 96 if (Alias.isValid()) 97 return Alias.matches(Opt); 98 99 // Check exact match. 100 if (getID() == Opt.getID()) 101 return true; 102 103 const Option Group = getGroup(); 104 if (Group.isValid()) 105 return Group.matches(Opt); 106 return false; 107 } 108 109 std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args, 110 StringRef Spelling, 111 unsigned &Index) const { 112 size_t ArgSize = Spelling.size(); 113 switch (getKind()) { 114 case FlagClass: { 115 if (ArgSize != strlen(Args.getArgString(Index))) 116 return nullptr; 117 return std::make_unique<Arg>(*this, Spelling, Index++); 118 } 119 case JoinedClass: { 120 const char *Value = Args.getArgString(Index) + ArgSize; 121 return std::make_unique<Arg>(*this, Spelling, Index++, Value); 122 } 123 case CommaJoinedClass: { 124 // Always matches. 125 const char *Str = Args.getArgString(Index) + ArgSize; 126 auto A = std::make_unique<Arg>(*this, Spelling, Index++); 127 128 // Parse out the comma separated values. 129 const char *Prev = Str; 130 for (;; ++Str) { 131 char c = *Str; 132 133 if (!c || c == ',') { 134 if (Prev != Str) { 135 char *Value = new char[Str - Prev + 1]; 136 memcpy(Value, Prev, Str - Prev); 137 Value[Str - Prev] = '\0'; 138 A->getValues().push_back(Value); 139 } 140 141 if (!c) 142 break; 143 144 Prev = Str + 1; 145 } 146 } 147 A->setOwnsValues(true); 148 149 return A; 150 } 151 case SeparateClass: 152 // Matches iff this is an exact match. 153 // FIXME: Avoid strlen. 154 if (ArgSize != strlen(Args.getArgString(Index))) 155 return nullptr; 156 157 Index += 2; 158 if (Index > Args.getNumInputArgStrings() || 159 Args.getArgString(Index - 1) == nullptr) 160 return nullptr; 161 162 return std::make_unique<Arg>(*this, Spelling, Index - 2, 163 Args.getArgString(Index - 1)); 164 case MultiArgClass: { 165 // Matches iff this is an exact match. 166 // FIXME: Avoid strlen. 167 if (ArgSize != strlen(Args.getArgString(Index))) 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 // FIXME: Avoid strlen. 183 if (ArgSize != strlen(Args.getArgString(Index))) { 184 const char *Value = Args.getArgString(Index) + ArgSize; 185 return std::make_unique<Arg>(*this, Spelling, Index++, Value); 186 } 187 188 // Otherwise it must be separate. 189 Index += 2; 190 if (Index > Args.getNumInputArgStrings() || 191 Args.getArgString(Index - 1) == nullptr) 192 return nullptr; 193 194 return std::make_unique<Arg>(*this, Spelling, Index - 2, 195 Args.getArgString(Index - 1)); 196 } 197 case JoinedAndSeparateClass: 198 // Always matches. 199 Index += 2; 200 if (Index > Args.getNumInputArgStrings() || 201 Args.getArgString(Index - 1) == nullptr) 202 return nullptr; 203 204 return std::make_unique<Arg>(*this, Spelling, Index - 2, 205 Args.getArgString(Index - 2) + ArgSize, 206 Args.getArgString(Index - 1)); 207 case RemainingArgsClass: { 208 // Matches iff this is an exact match. 209 // FIXME: Avoid strlen. 210 if (ArgSize != strlen(Args.getArgString(Index))) 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 (ArgSize != strlen(Args.getArgString(Index))) { 221 // An inexact match means there is a joined arg. 222 A->getValues().push_back(Args.getArgString(Index) + ArgSize); 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