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/OptTable.cpp | |
parent | 35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff) | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff) |
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/OptTable.cpp')
-rw-r--r-- | contrib/llvm/lib/Option/OptTable.cpp | 81 |
1 files changed, 45 insertions, 36 deletions
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; |