diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
commit | 54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch) | |
tree | 4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/Option | |
parent | 35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff) | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff) | |
download | src-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.cpp | 10 | ||||
-rw-r--r-- | contrib/llvm/lib/Option/ArgList.cpp | 22 | ||||
-rw-r--r-- | contrib/llvm/lib/Option/OptTable.cpp | 81 | ||||
-rw-r--r-- | contrib/llvm/lib/Option/Option.cpp | 120 |
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; +} |