10b57cec5SDimitry Andric //===- Option.cpp - Abstract Driver Options -------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
100b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
110b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
120b57cec5SDimitry Andric #include "llvm/Option/Arg.h"
130b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
140b57cec5SDimitry Andric #include "llvm/Option/Option.h"
150b57cec5SDimitry Andric #include "llvm/Option/OptTable.h"
160b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
170b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
180b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
190b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
200b57cec5SDimitry Andric #include <cassert>
210b57cec5SDimitry Andric #include <cstring>
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric using namespace llvm::opt;
250b57cec5SDimitry Andric
Option(const OptTable::Info * info,const OptTable * owner)260b57cec5SDimitry Andric Option::Option(const OptTable::Info *info, const OptTable *owner)
270b57cec5SDimitry Andric : Info(info), Owner(owner) {
280b57cec5SDimitry Andric // Multi-level aliases are not supported. This just simplifies option
290b57cec5SDimitry Andric // tracking, it is not an inherent limitation.
300b57cec5SDimitry Andric assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
310b57cec5SDimitry Andric "Multi-level aliases are not supported.");
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric if (Info && getAliasArgs()) {
340b57cec5SDimitry Andric assert(getAlias().isValid() && "Only alias options can have alias args.");
350b57cec5SDimitry Andric assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
360b57cec5SDimitry Andric assert(getAlias().getKind() != FlagClass &&
370b57cec5SDimitry Andric "Cannot provide alias args to a flag option.");
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric
print(raw_ostream & O,bool AddNewLine) const41*5f757f3fSDimitry Andric void Option::print(raw_ostream &O, bool AddNewLine) const {
420b57cec5SDimitry Andric O << "<";
430b57cec5SDimitry Andric switch (getKind()) {
440b57cec5SDimitry Andric #define P(N) case N: O << #N; break
450b57cec5SDimitry Andric P(GroupClass);
460b57cec5SDimitry Andric P(InputClass);
470b57cec5SDimitry Andric P(UnknownClass);
480b57cec5SDimitry Andric P(FlagClass);
490b57cec5SDimitry Andric P(JoinedClass);
500b57cec5SDimitry Andric P(ValuesClass);
510b57cec5SDimitry Andric P(SeparateClass);
520b57cec5SDimitry Andric P(CommaJoinedClass);
530b57cec5SDimitry Andric P(MultiArgClass);
540b57cec5SDimitry Andric P(JoinedOrSeparateClass);
550b57cec5SDimitry Andric P(JoinedAndSeparateClass);
560b57cec5SDimitry Andric P(RemainingArgsClass);
570b57cec5SDimitry Andric P(RemainingArgsJoinedClass);
580b57cec5SDimitry Andric #undef P
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric
61bdd1243dSDimitry Andric if (!Info->Prefixes.empty()) {
620b57cec5SDimitry Andric O << " Prefixes:[";
63bdd1243dSDimitry Andric for (size_t I = 0, N = Info->Prefixes.size(); I != N; ++I)
64bdd1243dSDimitry Andric O << '"' << Info->Prefixes[I] << (I == N - 1 ? "\"" : "\", ");
650b57cec5SDimitry Andric O << ']';
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric O << " Name:\"" << getName() << '"';
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric const Option Group = getGroup();
710b57cec5SDimitry Andric if (Group.isValid()) {
720b57cec5SDimitry Andric O << " Group:";
73*5f757f3fSDimitry Andric Group.print(O, /*AddNewLine=*/false);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric const Option Alias = getAlias();
770b57cec5SDimitry Andric if (Alias.isValid()) {
780b57cec5SDimitry Andric O << " Alias:";
79*5f757f3fSDimitry Andric Alias.print(O, /*AddNewLine=*/false);
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric if (getKind() == MultiArgClass)
830b57cec5SDimitry Andric O << " NumArgs:" << getNumArgs();
840b57cec5SDimitry Andric
85*5f757f3fSDimitry Andric O << ">";
86*5f757f3fSDimitry Andric if (AddNewLine)
87*5f757f3fSDimitry Andric O << "\n";
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const910b57cec5SDimitry Andric LLVM_DUMP_METHOD void Option::dump() const { print(dbgs()); }
920b57cec5SDimitry Andric #endif
930b57cec5SDimitry Andric
matches(OptSpecifier Opt) const940b57cec5SDimitry Andric bool Option::matches(OptSpecifier Opt) const {
950b57cec5SDimitry Andric // Aliases are never considered in matching, look through them.
960b57cec5SDimitry Andric const Option Alias = getAlias();
970b57cec5SDimitry Andric if (Alias.isValid())
980b57cec5SDimitry Andric return Alias.matches(Opt);
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric // Check exact match.
1010b57cec5SDimitry Andric if (getID() == Opt.getID())
1020b57cec5SDimitry Andric return true;
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric const Option Group = getGroup();
1050b57cec5SDimitry Andric if (Group.isValid())
1060b57cec5SDimitry Andric return Group.matches(Opt);
1070b57cec5SDimitry Andric return false;
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric
acceptInternal(const ArgList & Args,StringRef Spelling,unsigned & Index) const110349cc55cSDimitry Andric std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args,
111349cc55cSDimitry Andric StringRef Spelling,
112e8d8bef9SDimitry Andric unsigned &Index) const {
11306c3fb27SDimitry Andric const size_t SpellingSize = Spelling.size();
11406c3fb27SDimitry Andric const size_t ArgStringSize = StringRef(Args.getArgString(Index)).size();
1150b57cec5SDimitry Andric switch (getKind()) {
1160b57cec5SDimitry Andric case FlagClass: {
11706c3fb27SDimitry Andric if (SpellingSize != ArgStringSize)
1180b57cec5SDimitry Andric return nullptr;
119349cc55cSDimitry Andric return std::make_unique<Arg>(*this, Spelling, Index++);
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric case JoinedClass: {
12206c3fb27SDimitry Andric const char *Value = Args.getArgString(Index) + SpellingSize;
123349cc55cSDimitry Andric return std::make_unique<Arg>(*this, Spelling, Index++, Value);
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric case CommaJoinedClass: {
1260b57cec5SDimitry Andric // Always matches.
12706c3fb27SDimitry Andric const char *Str = Args.getArgString(Index) + SpellingSize;
128349cc55cSDimitry Andric auto A = std::make_unique<Arg>(*this, Spelling, Index++);
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andric // Parse out the comma separated values.
1310b57cec5SDimitry Andric const char *Prev = Str;
1320b57cec5SDimitry Andric for (;; ++Str) {
1330b57cec5SDimitry Andric char c = *Str;
1340b57cec5SDimitry Andric
1350b57cec5SDimitry Andric if (!c || c == ',') {
1360b57cec5SDimitry Andric if (Prev != Str) {
1370b57cec5SDimitry Andric char *Value = new char[Str - Prev + 1];
1380b57cec5SDimitry Andric memcpy(Value, Prev, Str - Prev);
1390b57cec5SDimitry Andric Value[Str - Prev] = '\0';
1400b57cec5SDimitry Andric A->getValues().push_back(Value);
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andric if (!c)
1440b57cec5SDimitry Andric break;
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric Prev = Str + 1;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric A->setOwnsValues(true);
1500b57cec5SDimitry Andric
1510b57cec5SDimitry Andric return A;
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric case SeparateClass:
1540b57cec5SDimitry Andric // Matches iff this is an exact match.
15506c3fb27SDimitry Andric if (SpellingSize != ArgStringSize)
1560b57cec5SDimitry Andric return nullptr;
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andric Index += 2;
1590b57cec5SDimitry Andric if (Index > Args.getNumInputArgStrings() ||
1600b57cec5SDimitry Andric Args.getArgString(Index - 1) == nullptr)
1610b57cec5SDimitry Andric return nullptr;
1620b57cec5SDimitry Andric
163349cc55cSDimitry Andric return std::make_unique<Arg>(*this, Spelling, Index - 2,
164349cc55cSDimitry Andric Args.getArgString(Index - 1));
1650b57cec5SDimitry Andric case MultiArgClass: {
1660b57cec5SDimitry Andric // Matches iff this is an exact match.
16706c3fb27SDimitry Andric if (SpellingSize != ArgStringSize)
1680b57cec5SDimitry Andric return nullptr;
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric Index += 1 + getNumArgs();
1710b57cec5SDimitry Andric if (Index > Args.getNumInputArgStrings())
1720b57cec5SDimitry Andric return nullptr;
1730b57cec5SDimitry Andric
174349cc55cSDimitry Andric auto A = std::make_unique<Arg>(*this, Spelling, Index - 1 - getNumArgs(),
1750b57cec5SDimitry Andric Args.getArgString(Index - getNumArgs()));
1760b57cec5SDimitry Andric for (unsigned i = 1; i != getNumArgs(); ++i)
1770b57cec5SDimitry Andric A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
1780b57cec5SDimitry Andric return A;
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric case JoinedOrSeparateClass: {
1810b57cec5SDimitry Andric // If this is not an exact match, it is a joined arg.
18206c3fb27SDimitry Andric if (SpellingSize != ArgStringSize) {
18306c3fb27SDimitry Andric const char *Value = Args.getArgString(Index) + SpellingSize;
184349cc55cSDimitry Andric return std::make_unique<Arg>(*this, Spelling, Index++, Value);
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric // Otherwise it must be separate.
1880b57cec5SDimitry Andric Index += 2;
1890b57cec5SDimitry Andric if (Index > Args.getNumInputArgStrings() ||
1900b57cec5SDimitry Andric Args.getArgString(Index - 1) == nullptr)
1910b57cec5SDimitry Andric return nullptr;
1920b57cec5SDimitry Andric
193349cc55cSDimitry Andric return std::make_unique<Arg>(*this, Spelling, Index - 2,
194349cc55cSDimitry Andric Args.getArgString(Index - 1));
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric case JoinedAndSeparateClass:
1970b57cec5SDimitry Andric // Always matches.
1980b57cec5SDimitry Andric Index += 2;
1990b57cec5SDimitry Andric if (Index > Args.getNumInputArgStrings() ||
2000b57cec5SDimitry Andric Args.getArgString(Index - 1) == nullptr)
2010b57cec5SDimitry Andric return nullptr;
2020b57cec5SDimitry Andric
203349cc55cSDimitry Andric return std::make_unique<Arg>(*this, Spelling, Index - 2,
20406c3fb27SDimitry Andric Args.getArgString(Index - 2) + SpellingSize,
2050b57cec5SDimitry Andric Args.getArgString(Index - 1));
2060b57cec5SDimitry Andric case RemainingArgsClass: {
2070b57cec5SDimitry Andric // Matches iff this is an exact match.
20806c3fb27SDimitry Andric if (SpellingSize != ArgStringSize)
2090b57cec5SDimitry Andric return nullptr;
210349cc55cSDimitry Andric auto A = std::make_unique<Arg>(*this, Spelling, Index++);
2110b57cec5SDimitry Andric while (Index < Args.getNumInputArgStrings() &&
2120b57cec5SDimitry Andric Args.getArgString(Index) != nullptr)
2130b57cec5SDimitry Andric A->getValues().push_back(Args.getArgString(Index++));
2140b57cec5SDimitry Andric return A;
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric case RemainingArgsJoinedClass: {
217349cc55cSDimitry Andric auto A = std::make_unique<Arg>(*this, Spelling, Index);
21806c3fb27SDimitry Andric if (SpellingSize != ArgStringSize) {
2190b57cec5SDimitry Andric // An inexact match means there is a joined arg.
22006c3fb27SDimitry Andric A->getValues().push_back(Args.getArgString(Index) + SpellingSize);
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric Index++;
2230b57cec5SDimitry Andric while (Index < Args.getNumInputArgStrings() &&
2240b57cec5SDimitry Andric Args.getArgString(Index) != nullptr)
2250b57cec5SDimitry Andric A->getValues().push_back(Args.getArgString(Index++));
2260b57cec5SDimitry Andric return A;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andric default:
2300b57cec5SDimitry Andric llvm_unreachable("Invalid option kind!");
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric
accept(const ArgList & Args,StringRef CurArg,bool GroupedShortOption,unsigned & Index) const234349cc55cSDimitry Andric std::unique_ptr<Arg> Option::accept(const ArgList &Args, StringRef CurArg,
235349cc55cSDimitry Andric bool GroupedShortOption,
236349cc55cSDimitry Andric unsigned &Index) const {
237349cc55cSDimitry Andric auto A(GroupedShortOption && getKind() == FlagClass
238349cc55cSDimitry Andric ? std::make_unique<Arg>(*this, CurArg, Index)
239e8d8bef9SDimitry Andric : acceptInternal(Args, CurArg, Index));
2400b57cec5SDimitry Andric if (!A)
2410b57cec5SDimitry Andric return nullptr;
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric const Option &UnaliasedOption = getUnaliasedOption();
2440b57cec5SDimitry Andric if (getID() == UnaliasedOption.getID())
245349cc55cSDimitry Andric return A;
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric // "A" is an alias for a different flag. For most clients it's more convenient
2480b57cec5SDimitry Andric // if this function returns unaliased Args, so create an unaliased arg for
2490b57cec5SDimitry Andric // returning.
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andric // This creates a completely new Arg object for the unaliased Arg because
2520b57cec5SDimitry Andric // the alias and the unaliased arg can have different Kinds and different
2530b57cec5SDimitry Andric // Values (due to AliasArgs<>).
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric // Get the spelling from the unaliased option.
2560b57cec5SDimitry Andric StringRef UnaliasedSpelling = Args.MakeArgString(
2570b57cec5SDimitry Andric Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName()));
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric // It's a bit weird that aliased and unaliased arg share one index, but
2600b57cec5SDimitry Andric // the index is mostly use as a memory optimization in render().
2610b57cec5SDimitry Andric // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
2620b57cec5SDimitry Andric // of the aliased arg always, while A->getSpelling() returns either the
2630b57cec5SDimitry Andric // unaliased or the aliased arg, depending on which Arg object it's called on.
264349cc55cSDimitry Andric auto UnaliasedA =
265349cc55cSDimitry Andric std::make_unique<Arg>(UnaliasedOption, UnaliasedSpelling, A->getIndex());
2660b57cec5SDimitry Andric Arg *RawA = A.get();
2670b57cec5SDimitry Andric UnaliasedA->setAlias(std::move(A));
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric if (getKind() != FlagClass) {
2700b57cec5SDimitry Andric // Values are usually owned by the ArgList. The exception are
2710b57cec5SDimitry Andric // CommaJoined flags, where the Arg owns the values. For aliased flags,
2720b57cec5SDimitry Andric // make the unaliased Arg the owner of the values.
2730b57cec5SDimitry Andric // FIXME: There aren't many uses of CommaJoined -- try removing
2740b57cec5SDimitry Andric // CommaJoined in favor of just calling StringRef::split(',') instead.
2750b57cec5SDimitry Andric UnaliasedA->getValues() = RawA->getValues();
2760b57cec5SDimitry Andric UnaliasedA->setOwnsValues(RawA->getOwnsValues());
2770b57cec5SDimitry Andric RawA->setOwnsValues(false);
2780b57cec5SDimitry Andric return UnaliasedA;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
2820b57cec5SDimitry Andric if (const char *Val = getAliasArgs()) {
2830b57cec5SDimitry Andric while (*Val != '\0') {
2840b57cec5SDimitry Andric UnaliasedA->getValues().push_back(Val);
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric // Move past the '\0' to the next argument.
2870b57cec5SDimitry Andric Val += strlen(Val) + 1;
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
2910b57cec5SDimitry Andric // A Flag alias for a Joined option must provide an argument.
2920b57cec5SDimitry Andric UnaliasedA->getValues().push_back("");
2930b57cec5SDimitry Andric return UnaliasedA;
2940b57cec5SDimitry Andric }
295