aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Option
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-21 18:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-21 18:13:02 +0000
commit54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch)
tree4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/Option
parent35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff)
parente6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff)
downloadsrc-54db30ce18663e6c2991958f3b5d18362e8e93c4.tar.gz
src-54db30ce18663e6c2991958f3b5d18362e8e93c4.zip
Merge llvm trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes: svn path=/projects/clang900-import/; revision=351344
Diffstat (limited to 'contrib/llvm/lib/Option')
-rw-r--r--contrib/llvm/lib/Option/Arg.cpp10
-rw-r--r--contrib/llvm/lib/Option/ArgList.cpp22
-rw-r--r--contrib/llvm/lib/Option/OptTable.cpp81
-rw-r--r--contrib/llvm/lib/Option/Option.cpp120
4 files changed, 129 insertions, 104 deletions
diff --git a/contrib/llvm/lib/Option/Arg.cpp b/contrib/llvm/lib/Option/Arg.cpp
index 4ce40e3ab26c..ea382b347345 100644
--- a/contrib/llvm/lib/Option/Arg.cpp
+++ b/contrib/llvm/lib/Option/Arg.cpp
@@ -1,9 +1,8 @@
//===- Arg.cpp - Argument Implementations ---------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -67,6 +66,9 @@ LLVM_DUMP_METHOD void Arg::dump() const { print(dbgs()); }
#endif
std::string Arg::getAsString(const ArgList &Args) const {
+ if (Alias)
+ return Alias->getAsString(Args);
+
SmallString<256> Res;
raw_svector_ostream OS(Res);
diff --git a/contrib/llvm/lib/Option/ArgList.cpp b/contrib/llvm/lib/Option/ArgList.cpp
index 8a7d59d24366..f37c142da69b 100644
--- a/contrib/llvm/lib/Option/ArgList.cpp
+++ b/contrib/llvm/lib/Option/ArgList.cpp
@@ -1,9 +1,8 @@
//===- ArgList.cpp - Argument List Management -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -96,21 +95,6 @@ std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
return std::vector<std::string>(Values.begin(), Values.end());
}
-void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
- if (Arg *A = getLastArg(Id)) {
- A->claim();
- A->render(*this, Output);
- }
-}
-
-void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const {
- if (Arg *A = getLastArg(Id0, Id1)) {
- A->claim();
- A->render(*this, Output);
- }
-}
-
void ArgList::AddAllArgsExcept(ArgStringList &Output,
ArrayRef<OptSpecifier> Ids,
ArrayRef<OptSpecifier> ExcludeIds) const {
diff --git a/contrib/llvm/lib/Option/OptTable.cpp b/contrib/llvm/lib/Option/OptTable.cpp
index 312ff7808759..5833d03069f8 100644
--- a/contrib/llvm/lib/Option/OptTable.cpp
+++ b/contrib/llvm/lib/Option/OptTable.cpp
@@ -1,9 +1,8 @@
//===- OptTable.cpp - Option Table Implementation -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -252,59 +251,69 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,
unsigned MinimumLength) const {
assert(!Option.empty());
- // Consider each option as a candidate, finding the closest match.
+ // Consider each [option prefix + option name] pair as a candidate, finding
+ // the closest match.
unsigned BestDistance = UINT_MAX;
for (const Info &CandidateInfo :
ArrayRef<Info>(OptionInfos).drop_front(FirstSearchableIndex)) {
StringRef CandidateName = CandidateInfo.Name;
- // Ignore option candidates with empty names, such as "--", or names
- // that do not meet the minimum length.
+ // We can eliminate some option prefix/name pairs as candidates right away:
+ // * Ignore option candidates with empty names, such as "--", or names
+ // that do not meet the minimum length.
if (CandidateName.empty() || CandidateName.size() < MinimumLength)
continue;
- // If FlagsToInclude were specified, ignore options that don't include
- // those flags.
+ // * If FlagsToInclude were specified, ignore options that don't include
+ // those flags.
if (FlagsToInclude && !(CandidateInfo.Flags & FlagsToInclude))
continue;
- // Ignore options that contain the FlagsToExclude.
+ // * Ignore options that contain the FlagsToExclude.
if (CandidateInfo.Flags & FlagsToExclude)
continue;
- // Ignore positional argument option candidates (which do not
- // have prefixes).
+ // * Ignore positional argument option candidates (which do not
+ // have prefixes).
if (!CandidateInfo.Prefixes)
continue;
- // Find the most appropriate prefix. For example, if a user asks for
- // "--helm", suggest "--help" over "-help".
- StringRef Prefix = CandidateInfo.Prefixes[0];
- for (int P = 1; CandidateInfo.Prefixes[P]; P++) {
- if (Option.startswith(CandidateInfo.Prefixes[P]))
- Prefix = CandidateInfo.Prefixes[P];
- }
- // Check if the candidate ends with a character commonly used when
+ // Now check if the candidate ends with a character commonly used when
// delimiting an option from its value, such as '=' or ':'. If it does,
// attempt to split the given option based on that delimiter.
- std::string Delimiter = "";
- char Last = CandidateName.back();
- if (Last == '=' || Last == ':')
- Delimiter = std::string(1, Last);
-
StringRef LHS, RHS;
- if (Delimiter.empty())
- LHS = Option;
- else
+ char Last = CandidateName.back();
+ bool CandidateHasDelimiter = Last == '=' || Last == ':';
+ std::string NormalizedName = Option;
+ if (CandidateHasDelimiter) {
std::tie(LHS, RHS) = Option.split(Last);
+ NormalizedName = LHS;
+ if (Option.find(Last) == LHS.size())
+ NormalizedName += Last;
+ }
- std::string NormalizedName =
- (LHS.drop_front(Prefix.size()) + Delimiter).str();
- unsigned Distance =
- CandidateName.edit_distance(NormalizedName, /*AllowReplacements=*/true,
- /*MaxEditDistance=*/BestDistance);
- if (Distance < BestDistance) {
- BestDistance = Distance;
- NearestString = (Prefix + CandidateName + RHS).str();
+ // Consider each possible prefix for each candidate to find the most
+ // appropriate one. For example, if a user asks for "--helm", suggest
+ // "--help" over "-help".
+ for (int P = 0;
+ const char *const CandidatePrefix = CandidateInfo.Prefixes[P]; P++) {
+ std::string Candidate = (CandidatePrefix + CandidateName).str();
+ StringRef CandidateRef = Candidate;
+ unsigned Distance =
+ CandidateRef.edit_distance(NormalizedName, /*AllowReplacements=*/true,
+ /*MaxEditDistance=*/BestDistance);
+ if (RHS.empty() && CandidateHasDelimiter) {
+ // The Candidate ends with a = or : delimiter, but the option passed in
+ // didn't contain the delimiter (or doesn't have anything after it).
+ // In that case, penalize the correction: `-nodefaultlibs` is more
+ // likely to be a spello for `-nodefaultlib` than `-nodefaultlib:` even
+ // though both have an unmodified editing distance of 1, since the
+ // latter would need an argument.
+ ++Distance;
+ }
+ if (Distance < BestDistance) {
+ BestDistance = Distance;
+ NearestString = (Candidate + RHS).str();
+ }
}
}
return BestDistance;
diff --git a/contrib/llvm/lib/Option/Option.cpp b/contrib/llvm/lib/Option/Option.cpp
index f9d8a5e54043..9abc9fdce4c7 100644
--- a/contrib/llvm/lib/Option/Option.cpp
+++ b/contrib/llvm/lib/Option/Option.cpp
@@ -1,9 +1,8 @@
//===- Option.cpp - Abstract Driver Options -------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -107,49 +106,23 @@ bool Option::matches(OptSpecifier Opt) const {
return false;
}
-Arg *Option::accept(const ArgList &Args,
- unsigned &Index,
- unsigned ArgSize) const {
- const Option &UnaliasedOption = getUnaliasedOption();
- StringRef Spelling;
- // If the option was an alias, get the spelling from the unaliased one.
- if (getID() == UnaliasedOption.getID()) {
- Spelling = StringRef(Args.getArgString(Index), ArgSize);
- } else {
- Spelling = Args.MakeArgString(Twine(UnaliasedOption.getPrefix()) +
- Twine(UnaliasedOption.getName()));
- }
-
+Arg *Option::acceptInternal(const ArgList &Args, unsigned &Index,
+ unsigned ArgSize) const {
+ StringRef Spelling = StringRef(Args.getArgString(Index), ArgSize);
switch (getKind()) {
case FlagClass: {
if (ArgSize != strlen(Args.getArgString(Index)))
return nullptr;
-
- Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
- if (getAliasArgs()) {
- const char *Val = getAliasArgs();
- while (*Val != '\0') {
- A->getValues().push_back(Val);
-
- // Move past the '\0' to the next argument.
- Val += strlen(Val) + 1;
- }
- }
-
- if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
- // A Flag alias for a Joined option must provide an argument.
- A->getValues().push_back("");
-
- return A;
+ return new Arg(*this, Spelling, Index++);
}
case JoinedClass: {
const char *Value = Args.getArgString(Index) + ArgSize;
- return new Arg(UnaliasedOption, Spelling, Index++, Value);
+ return new Arg(*this, Spelling, Index++, Value);
}
case CommaJoinedClass: {
// Always matches.
const char *Str = Args.getArgString(Index) + ArgSize;
- Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
+ Arg *A = new Arg(*this, Spelling, Index++);
// Parse out the comma separated values.
const char *Prev = Str;
@@ -185,8 +158,7 @@ Arg *Option::accept(const ArgList &Args,
Args.getArgString(Index - 1) == nullptr)
return nullptr;
- return new Arg(UnaliasedOption, Spelling,
- Index - 2, Args.getArgString(Index - 1));
+ return new Arg(*this, Spelling, Index - 2, Args.getArgString(Index - 1));
case MultiArgClass: {
// Matches iff this is an exact match.
// FIXME: Avoid strlen.
@@ -197,8 +169,8 @@ Arg *Option::accept(const ArgList &Args,
if (Index > Args.getNumInputArgStrings())
return nullptr;
- Arg *A = new Arg(UnaliasedOption, Spelling, Index - 1 - getNumArgs(),
- Args.getArgString(Index - getNumArgs()));
+ Arg *A = new Arg(*this, Spelling, Index - 1 - getNumArgs(),
+ Args.getArgString(Index - getNumArgs()));
for (unsigned i = 1; i != getNumArgs(); ++i)
A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
return A;
@@ -217,8 +189,7 @@ Arg *Option::accept(const ArgList &Args,
Args.getArgString(Index - 1) == nullptr)
return nullptr;
- return new Arg(UnaliasedOption, Spelling,
- Index - 2, Args.getArgString(Index - 1));
+ return new Arg(*this, Spelling, Index - 2, Args.getArgString(Index - 1));
}
case JoinedAndSeparateClass:
// Always matches.
@@ -227,7 +198,7 @@ Arg *Option::accept(const ArgList &Args,
Args.getArgString(Index - 1) == nullptr)
return nullptr;
- return new Arg(UnaliasedOption, Spelling, Index - 2,
+ return new Arg(*this, Spelling, Index - 2,
Args.getArgString(Index - 2) + ArgSize,
Args.getArgString(Index - 1));
case RemainingArgsClass: {
@@ -235,14 +206,14 @@ Arg *Option::accept(const ArgList &Args,
// FIXME: Avoid strlen.
if (ArgSize != strlen(Args.getArgString(Index)))
return nullptr;
- Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
+ Arg *A = new Arg(*this, Spelling, Index++);
while (Index < Args.getNumInputArgStrings() &&
Args.getArgString(Index) != nullptr)
A->getValues().push_back(Args.getArgString(Index++));
return A;
}
case RemainingArgsJoinedClass: {
- Arg *A = new Arg(UnaliasedOption, Spelling, Index);
+ Arg *A = new Arg(*this, Spelling, Index);
if (ArgSize != strlen(Args.getArgString(Index))) {
// An inexact match means there is a joined arg.
A->getValues().push_back(Args.getArgString(Index) + ArgSize);
@@ -258,3 +229,62 @@ Arg *Option::accept(const ArgList &Args,
llvm_unreachable("Invalid option kind!");
}
}
+
+Arg *Option::accept(const ArgList &Args,
+ unsigned &Index,
+ unsigned ArgSize) const {
+ std::unique_ptr<Arg> A(acceptInternal(Args, Index, ArgSize));
+ if (!A)
+ return nullptr;
+
+ const Option &UnaliasedOption = getUnaliasedOption();
+ if (getID() == UnaliasedOption.getID())
+ return A.release();
+
+ // "A" is an alias for a different flag. For most clients it's more convenient
+ // if this function returns unaliased Args, so create an unaliased arg for
+ // returning.
+
+ // This creates a completely new Arg object for the unaliased Arg because
+ // the alias and the unaliased arg can have different Kinds and different
+ // Values (due to AliasArgs<>).
+
+ // Get the spelling from the unaliased option.
+ StringRef UnaliasedSpelling = Args.MakeArgString(
+ Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName()));
+
+ // It's a bit weird that aliased and unaliased arg share one index, but
+ // the index is mostly use as a memory optimization in render().
+ // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
+ // of the aliased arg always, while A->getSpelling() returns either the
+ // unaliased or the aliased arg, depending on which Arg object it's called on.
+ Arg *UnaliasedA = new Arg(UnaliasedOption, UnaliasedSpelling, A->getIndex());
+ Arg *RawA = A.get();
+ UnaliasedA->setAlias(std::move(A));
+
+ if (getKind() != FlagClass) {
+ // Values are usually owned by the ArgList. The exception are
+ // CommaJoined flags, where the Arg owns the values. For aliased flags,
+ // make the unaliased Arg the owner of the values.
+ // FIXME: There aren't many uses of CommaJoined -- try removing
+ // CommaJoined in favor of just calling StringRef::split(',') instead.
+ UnaliasedA->getValues() = RawA->getValues();
+ UnaliasedA->setOwnsValues(RawA->getOwnsValues());
+ RawA->setOwnsValues(false);
+ return UnaliasedA;
+ }
+
+ // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
+ if (const char *Val = getAliasArgs()) {
+ while (*Val != '\0') {
+ UnaliasedA->getValues().push_back(Val);
+
+ // Move past the '\0' to the next argument.
+ Val += strlen(Val) + 1;
+ }
+ }
+ if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
+ // A Flag alias for a Joined option must provide an argument.
+ UnaliasedA->getValues().push_back("");
+ return UnaliasedA;
+}