Skip to content

Commit

Permalink
Merged master:b9306fd042ce into amd-gfx:242c36a54a72
Browse files Browse the repository at this point in the history
Local branch amd-gfx 242c36a Merged master:ab4627364aef into amd-gfx:8356ebb3ca23
Remote branch master b9306fd [clang-tidy] Reworked enum options handling(again)
  • Loading branch information
Sw authored and Sw committed Jun 28, 2020
2 parents 242c36a + b9306fd commit 98acc66
Show file tree
Hide file tree
Showing 20 changed files with 178 additions and 143 deletions.
18 changes: 9 additions & 9 deletions clang-tools-extra/clang-tidy/ClangTidyCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
}

llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
StringRef LocalName, ArrayRef<std::pair<StringRef, int64_t>> Mapping,
StringRef LocalName, ArrayRef<std::pair<int64_t, StringRef>> Mapping,
bool CheckGlobal, bool IgnoreCase) {
auto Iter = CheckOptions.find((NamePrefix + LocalName).str());
if (CheckGlobal && Iter == CheckOptions.end())
Expand All @@ -171,19 +171,19 @@ llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
unsigned EditDistance = -1;
for (const auto &NameAndEnum : Mapping) {
if (IgnoreCase) {
if (Value.equals_lower(NameAndEnum.first))
return NameAndEnum.second;
} else if (Value.equals(NameAndEnum.first)) {
return NameAndEnum.second;
} else if (Value.equals_lower(NameAndEnum.first)) {
Closest = NameAndEnum.first;
if (Value.equals_lower(NameAndEnum.second))
return NameAndEnum.first;
} else if (Value.equals(NameAndEnum.second)) {
return NameAndEnum.first;
} else if (Value.equals_lower(NameAndEnum.second)) {
Closest = NameAndEnum.second;
EditDistance = 0;
continue;
}
unsigned Distance = Value.edit_distance(NameAndEnum.first);
unsigned Distance = Value.edit_distance(NameAndEnum.second);
if (Distance < EditDistance) {
EditDistance = Distance;
Closest = NameAndEnum.first;
Closest = NameAndEnum.second;
}
}
if (EditDistance < 3)
Expand Down
80 changes: 48 additions & 32 deletions clang-tools-extra/clang-tidy/ClangTidyCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ class CompilerInstance;

namespace tidy {

/// This class should be specialized by any enum type that needs to be converted
/// to and from an \ref llvm::StringRef.
template <class T> struct OptionEnumMapping {
// Specializations of this struct must implement this function.
static ArrayRef<std::pair<T, StringRef>> getEnumMapping() = delete;
};

template <typename T> class OptionError : public llvm::ErrorInfo<T> {
std::error_code convertToErrorCode() const override {
return llvm::inconvertibleErrorCode();
Expand Down Expand Up @@ -313,77 +320,80 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
}

/// Read a named option from the ``Context`` and parse it as an
/// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
/// it will search the mapping ignoring the case.
/// enum type ``T``.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, returns a
/// ``MissingOptionError``. If the key can't be parsed as a ``T`` returns a
/// ``UnparseableEnumOptionError``.
///
/// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
/// supply the mapping required to convert between ``T`` and a string.
template <typename T>
std::enable_if_t<std::is_enum<T>::value, llvm::Expected<T>>
get(StringRef LocalName, ArrayRef<std::pair<StringRef, T>> Mapping,
bool IgnoreCase = false) {
if (llvm::Expected<int64_t> ValueOr = getEnumInt(
LocalName, typeEraseMapping(Mapping), false, IgnoreCase))
get(StringRef LocalName, bool IgnoreCase = false) {
if (llvm::Expected<int64_t> ValueOr =
getEnumInt(LocalName, typeEraseMapping<T>(), false, IgnoreCase))
return static_cast<T>(*ValueOr);
else
return std::move(ValueOr.takeError());
}

/// Read a named option from the ``Context`` and parse it as an
/// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
/// it will search the mapping ignoring the case.
/// enum type ``T``.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present or it can't be
/// parsed as a ``T``, returns \p Default.
///
/// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
/// supply the mapping required to convert between ``T`` and a string.
template <typename T>
std::enable_if_t<std::is_enum<T>::value, T>
get(StringRef LocalName, ArrayRef<std::pair<StringRef, T>> Mapping,
T Default, bool IgnoreCase = false) {
if (auto ValueOr = get(LocalName, Mapping, IgnoreCase))
get(StringRef LocalName, T Default, bool IgnoreCase = false) {
if (auto ValueOr = get<T>(LocalName, IgnoreCase))
return *ValueOr;
else
logErrToStdErr(ValueOr.takeError());
return Default;
}

/// Read a named option from the ``Context`` and parse it as an
/// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
/// it will search the mapping ignoring the case.
/// enum type ``T``.
///
/// Reads the option with the check-local name \p LocalName from local or
/// global ``CheckOptions``. Gets local option first. If local is not
/// present, falls back to get global option. If global option is not
/// present either, returns a ``MissingOptionError``. If the key can't be
/// parsed as a ``T`` returns a ``UnparseableEnumOptionError``.
///
/// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
/// supply the mapping required to convert between ``T`` and a string.
template <typename T>
std::enable_if_t<std::is_enum<T>::value, llvm::Expected<T>>
getLocalOrGlobal(StringRef LocalName,
ArrayRef<std::pair<StringRef, T>> Mapping,
bool IgnoreCase = false) {
if (llvm::Expected<int64_t> ValueOr = getEnumInt(
LocalName, typeEraseMapping(Mapping), true, IgnoreCase))
if (llvm::Expected<int64_t> ValueOr =
getEnumInt(LocalName, typeEraseMapping<T>(), true, IgnoreCase))
return static_cast<T>(*ValueOr);
else
return std::move(ValueOr.takeError());
}

/// Read a named option from the ``Context`` and parse it as an
/// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
/// it will search the mapping ignoring the case.
/// enum type ``T``.
///
/// Reads the option with the check-local name \p LocalName from local or
/// global ``CheckOptions``. Gets local option first. If local is not
/// present, falls back to get global option. If global option is not
/// present either or it can't be parsed as a ``T``, returns \p Default.
///
/// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
/// supply the mapping required to convert between ``T`` and a string.
template <typename T>
std::enable_if_t<std::is_enum<T>::value, T>
getLocalOrGlobal(StringRef LocalName,
ArrayRef<std::pair<StringRef, T>> Mapping, T Default,
bool IgnoreCase = false) {
if (auto ValueOr = getLocalOrGlobal(LocalName, Mapping, IgnoreCase))
getLocalOrGlobal(StringRef LocalName, T Default, bool IgnoreCase = false) {
if (auto ValueOr = getLocalOrGlobal<T>(LocalName, IgnoreCase))
return *ValueOr;
else
logErrToStdErr(ValueOr.takeError());
Expand All @@ -401,34 +411,40 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
int64_t Value) const;

/// Stores an option with the check-local name \p LocalName as the string
/// representation of the Enum \p Value using the \p Mapping to \p Options.
/// representation of the Enum \p Value to \p Options.
///
/// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
/// supply the mapping required to convert between ``T`` and a string.
template <typename T>
std::enable_if_t<std::is_enum<T>::value>
store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value,
ArrayRef<std::pair<StringRef, T>> Mapping) {
store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) {
ArrayRef<std::pair<T, StringRef>> Mapping =
OptionEnumMapping<T>::getEnumMapping();
auto Iter = llvm::find_if(
Mapping, [&](const std::pair<StringRef, T> &NameAndEnum) {
return NameAndEnum.second == Value;
Mapping, [&](const std::pair<T, StringRef> &NameAndEnum) {
return NameAndEnum.first == Value;
});
assert(Iter != Mapping.end() && "Unknown Case Value");
store(Options, LocalName, Iter->first);
store(Options, LocalName, Iter->second);
}

private:
using NameAndValue = std::pair<StringRef, int64_t>;
using NameAndValue = std::pair<int64_t, StringRef>;

llvm::Expected<int64_t> getEnumInt(StringRef LocalName,
ArrayRef<NameAndValue> Mapping,
bool CheckGlobal, bool IgnoreCase);

template <typename T>
std::enable_if_t<std::is_enum<T>::value, std::vector<NameAndValue>>
typeEraseMapping(ArrayRef<std::pair<StringRef, T>> Mapping) {
typeEraseMapping() {
ArrayRef<std::pair<T, StringRef>> Mapping =
OptionEnumMapping<T>::getEnumMapping();
std::vector<NameAndValue> Result;
Result.reserve(Mapping.size());
for (auto &MappedItem : Mapping) {
Result.emplace_back(MappedItem.first,
static_cast<int64_t>(MappedItem.second));
Result.emplace_back(static_cast<int64_t>(MappedItem.first),
MappedItem.second);
}
return Result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
StringLikeClasses(utils::options::parseStringList(
Options.get("StringLikeClasses", "::std::basic_string"))),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)),
AbseilStringsMatchHeader(
Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {}
Expand Down Expand Up @@ -122,8 +121,7 @@ void StringFindStartswithCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "StringLikeClasses",
utils::options::serializeStringList(StringLikeClasses));
Options.store(Opts, "IncludeStyle", IncludeStyle,
utils::IncludeSorter::getMapping());
Options.store(Opts, "IncludeStyle", IncludeStyle);
Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ InitVariablesCheck::InitVariablesCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)),
MathHeader(Options.get("MathHeader", "math.h")) {}

void InitVariablesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeStyle,
utils::IncludeSorter::getMapping());
Options.store(Opts, "IncludeStyle", IncludeStyle);
Options.store(Opts, "MathHeader", MathHeader);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)) {}

void ProBoundsConstantArrayIndexCheck::storeOptions(
Expand Down
54 changes: 29 additions & 25 deletions clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,31 @@ using namespace llvm;

namespace clang {
namespace tidy {

template <> struct OptionEnumMapping<modernize::Confidence::Level> {
static llvm::ArrayRef<std::pair<modernize::Confidence::Level, StringRef>>
getEnumMapping() {
static constexpr std::pair<modernize::Confidence::Level, StringRef>
Mapping[] = {{modernize::Confidence::CL_Reasonable, "reasonable"},
{modernize::Confidence::CL_Safe, "safe"},
{modernize::Confidence::CL_Risky, "risky"}};
return makeArrayRef(Mapping);
}
};

template <> struct OptionEnumMapping<modernize::VariableNamer::NamingStyle> {
static llvm::ArrayRef<
std::pair<modernize::VariableNamer::NamingStyle, StringRef>>
getEnumMapping() {
static constexpr std::pair<modernize::VariableNamer::NamingStyle, StringRef>
Mapping[] = {{modernize::VariableNamer::NS_CamelCase, "CamelCase"},
{modernize::VariableNamer::NS_CamelBack, "camelBack"},
{modernize::VariableNamer::NS_LowerCase, "lower_case"},
{modernize::VariableNamer::NS_UpperCase, "UPPER_CASE"}};
return makeArrayRef(Mapping);
}
};

namespace modernize {

static const char LoopNameArray[] = "forLoopArray";
Expand All @@ -44,25 +69,6 @@ static const char EndVarName[] = "endVar";
static const char DerefByValueResultName[] = "derefByValueResult";
static const char DerefByRefResultName[] = "derefByRefResult";

static ArrayRef<std::pair<StringRef, Confidence::Level>>
getConfidenceMapping() {
static constexpr std::pair<StringRef, Confidence::Level> Mapping[] = {
{"reasonable", Confidence::CL_Reasonable},
{"safe", Confidence::CL_Safe},
{"risky", Confidence::CL_Risky}};
return makeArrayRef(Mapping);
}

static ArrayRef<std::pair<StringRef, VariableNamer::NamingStyle>>
getStyleMapping() {
static constexpr std::pair<StringRef, VariableNamer::NamingStyle> Mapping[] =
{{"CamelCase", VariableNamer::NS_CamelCase},
{"camelBack", VariableNamer::NS_CamelBack},
{"lower_case", VariableNamer::NS_LowerCase},
{"UPPER_CASE", VariableNamer::NS_UpperCase}};
return makeArrayRef(Mapping);
}

// shared matchers
static const TypeMatcher AnyType() { return anything(); }

Expand Down Expand Up @@ -477,15 +483,13 @@ LoopConvertCheck::RangeDescriptor::RangeDescriptor()
LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo),
MaxCopySize(Options.get("MaxCopySize", 16ULL)),
MinConfidence(Options.get("MinConfidence", getConfidenceMapping(),
Confidence::CL_Reasonable)),
NamingStyle(Options.get("NamingStyle", getStyleMapping(),
VariableNamer::NS_CamelCase)) {}
MinConfidence(Options.get("MinConfidence", Confidence::CL_Reasonable)),
NamingStyle(Options.get("NamingStyle", VariableNamer::NS_CamelCase)) {}

void LoopConvertCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "MaxCopySize", std::to_string(MaxCopySize));
Options.store(Opts, "MinConfidence", MinConfidence, getConfidenceMapping());
Options.store(Opts, "NamingStyle", NamingStyle, getStyleMapping());
Options.store(Opts, "MinConfidence", MinConfidence);
Options.store(Opts, "NamingStyle", NamingStyle);
}

void LoopConvertCheck::registerMatchers(MatchFinder *Finder) {
Expand Down
4 changes: 1 addition & 3 deletions clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
StringRef MakeSmartPtrFunctionName)
: ClangTidyCheck(Name, Context),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)),
MakeSmartPtrFunctionHeader(
Options.get("MakeSmartPtrFunctionHeader", StdMemoryHeader)),
Expand All @@ -54,8 +53,7 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}

void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeStyle,
utils::IncludeSorter::getMapping());
Options.store(Opts, "IncludeStyle", IncludeStyle);
Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader);
Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName);
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
Expand Down
4 changes: 1 addition & 3 deletions clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,11 @@ collectParamDecls(const CXXConstructorDecl *Ctor,
PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)),
ValuesOnly(Options.get("ValuesOnly", false)) {}

void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeStyle,
utils::IncludeSorter::getMapping());
Options.store(Opts, "IncludeStyle", IncludeStyle);
Options.store(Opts, "ValuesOnly", ValuesOnly);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,10 @@ ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)) {}

void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeStyle,
utils::IncludeSorter::getMapping());
Options.store(Opts, "IncludeStyle", IncludeStyle);
}

void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::getMapping(),
utils::IncludeSorter::IS_LLVM)) {}

void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
Expand Down Expand Up @@ -52,8 +51,7 @@ void ReplaceRandomShuffleCheck::registerPPCallbacks(

void ReplaceRandomShuffleCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeStyle,
utils::IncludeSorter::getMapping());
Options.store(Opts, "IncludeStyle", IncludeStyle);
}

void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
Expand Down
Loading

0 comments on commit 98acc66

Please sign in to comment.