[clang-tidy][NFC] Replace many instances of std::string where a StringRef would suffice.

There's many instances in clang tidy checks where owning strings are used when we already have a stable string from the options, so using a StringRef makes much more sense.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D124341
This commit is contained in:
Nathan James 2022-05-09 12:01:45 +01:00
parent fc440f27cd
commit 12cb540529
No known key found for this signature in database
GPG Key ID: CC007AFCDA90AA5F
78 changed files with 234 additions and 272 deletions

View File

@ -48,14 +48,14 @@ void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
ClangTidyCheck::OptionsView::OptionsView(
StringRef CheckName, const ClangTidyOptions::OptionMap &CheckOptions,
ClangTidyContext *Context)
: NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions),
: NamePrefix((CheckName + ".").str()), CheckOptions(CheckOptions),
Context(Context) {}
llvm::Optional<std::string>
llvm::Optional<StringRef>
ClangTidyCheck::OptionsView::get(StringRef LocalName) const {
const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
const auto &Iter = CheckOptions.find((NamePrefix + LocalName).str());
if (Iter != CheckOptions.end())
return Iter->getValue().Value;
return StringRef(Iter->getValue().Value);
return None;
}
@ -63,7 +63,7 @@ static ClangTidyOptions::OptionMap::const_iterator
findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePrefix,
StringRef LocalName) {
auto IterLocal = Options.find((NamePrefix + LocalName).str());
auto IterGlobal = Options.find(LocalName.str());
auto IterGlobal = Options.find(LocalName);
if (IterLocal == Options.end())
return IterGlobal;
if (IterGlobal == Options.end())
@ -73,11 +73,11 @@ findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePre
return IterGlobal;
}
llvm::Optional<std::string>
llvm::Optional<StringRef>
ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const {
auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName);
if (Iter != CheckOptions.end())
return Iter->getValue().Value;
return StringRef(Iter->getValue().Value);
return None;
}
@ -97,7 +97,7 @@ static Optional<bool> getAsBool(StringRef Value,
template <>
llvm::Optional<bool>
ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName) const {
if (llvm::Optional<std::string> ValueOr = get(LocalName)) {
if (llvm::Optional<StringRef> ValueOr = get(LocalName)) {
if (auto Result = getAsBool(*ValueOr, NamePrefix + LocalName))
return Result;
diagnoseBadBooleanOption(NamePrefix + LocalName, *ValueOr);
@ -120,7 +120,7 @@ ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const {
void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
StringRef LocalName,
StringRef Value) const {
Options[NamePrefix + LocalName.str()] = Value;
Options[(NamePrefix + LocalName).str()] = Value;
}
void ClangTidyCheck::OptionsView::storeInt(ClangTidyOptions::OptionMap &Options,
@ -167,10 +167,9 @@ llvm::Optional<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
}
}
if (EditDistance < 3)
diagnoseBadEnumOption(Iter->getKey().str(), Iter->getValue().Value,
Closest);
diagnoseBadEnumOption(Iter->getKey(), Iter->getValue().Value, Closest);
else
diagnoseBadEnumOption(Iter->getKey().str(), Iter->getValue().Value);
diagnoseBadEnumOption(Iter->getKey(), Iter->getValue().Value);
return None;
}
@ -203,18 +202,15 @@ void ClangTidyCheck::OptionsView::diagnoseBadEnumOption(
Diag << 3 << Suggestion;
}
std::string ClangTidyCheck::OptionsView::get(StringRef LocalName,
StringRef Default) const {
if (llvm::Optional<std::string> Val = get(LocalName))
return std::move(*Val);
return Default.str();
StringRef ClangTidyCheck::OptionsView::get(StringRef LocalName,
StringRef Default) const {
return get(LocalName).getValueOr(Default);
}
std::string
StringRef
ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName,
StringRef Default) const {
if (llvm::Optional<std::string> Val = getLocalOrGlobal(LocalName))
return std::move(*Val);
return Default.str();
return getLocalOrGlobal(LocalName).getValueOr(Default);
}
} // namespace tidy
} // namespace clang

View File

@ -155,14 +155,14 @@ public:
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, return
/// ``None``.
llvm::Optional<std::string> get(StringRef LocalName) const;
llvm::Optional<StringRef> get(StringRef LocalName) const;
/// Read a named option from the ``Context``.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, returns
/// \p Default.
std::string get(StringRef LocalName, StringRef Default) const;
StringRef get(StringRef LocalName, StringRef Default) const;
/// Read a named option from the ``Context``.
///
@ -170,7 +170,7 @@ public:
/// global ``CheckOptions``. Gets local option first. If local is not
/// present, falls back to get global option. If global option is not
/// present either, return ``None``.
llvm::Optional<std::string> getLocalOrGlobal(StringRef LocalName) const;
llvm::Optional<StringRef> getLocalOrGlobal(StringRef LocalName) const;
/// Read a named option from the ``Context``.
///
@ -178,7 +178,7 @@ public:
/// 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 \p Default.
std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
StringRef getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
/// Read a named option from the ``Context`` and parse it as an
/// integral type ``T``.
@ -192,7 +192,7 @@ public:
template <typename T>
std::enable_if_t<std::is_integral<T>::value, llvm::Optional<T>>
get(StringRef LocalName) const {
if (llvm::Optional<std::string> Value = get(LocalName)) {
if (llvm::Optional<StringRef> Value = get(LocalName)) {
T Result{};
if (!StringRef(*Value).getAsInteger(10, Result))
return Result;
@ -229,7 +229,7 @@ public:
template <typename T>
std::enable_if_t<std::is_integral<T>::value, llvm::Optional<T>>
getLocalOrGlobal(StringRef LocalName) const {
llvm::Optional<std::string> ValueOr = get(LocalName);
llvm::Optional<StringRef> ValueOr = get(LocalName);
bool IsGlobal = false;
if (!ValueOr) {
IsGlobal = true;

View File

@ -34,8 +34,7 @@ StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
void StringFindStartswithCheck::registerMatchers(MatchFinder *Finder) {
auto ZeroLiteral = integerLiteral(equals(0));
auto StringClassMatcher = cxxRecordDecl(hasAnyName(SmallVector<StringRef, 4>(
StringLikeClasses.begin(), StringLikeClasses.end())));
auto StringClassMatcher = cxxRecordDecl(hasAnyName(StringLikeClasses));
auto StringType = hasUnqualifiedDesugaredType(
recordType(hasDeclaration(StringClassMatcher)));

View File

@ -35,9 +35,9 @@ public:
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
private:
const std::vector<std::string> StringLikeClasses;
const std::vector<StringRef> StringLikeClasses;
utils::IncludeInserter IncludeInserter;
const std::string AbseilStringsMatchHeader;
const StringRef AbseilStringsMatchHeader;
};
} // namespace abseil

View File

@ -40,10 +40,9 @@ static const char DefaultStringLikeClasses[] = "::std::basic_string;"
static const char DefaultAbseilStringsMatchHeader[] = "absl/strings/match.h";
static transformer::RewriteRuleWith<std::string>
makeRewriteRule(const std::vector<std::string> &StringLikeClassNames,
makeRewriteRule(ArrayRef<StringRef> StringLikeClassNames,
StringRef AbseilStringsMatchHeader) {
auto StringLikeClass = cxxRecordDecl(hasAnyName(SmallVector<StringRef, 4>(
StringLikeClassNames.begin(), StringLikeClassNames.end())));
auto StringLikeClass = cxxRecordDecl(hasAnyName(StringLikeClassNames));
auto StringType =
hasUnqualifiedDesugaredType(recordType(hasDeclaration(StringLikeClass)));
auto CharStarType =

View File

@ -28,8 +28,8 @@ public:
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
private:
const std::vector<std::string> StringLikeClassesOption;
const std::string AbseilStringsMatchHeaderOption;
const std::vector<StringRef> StringLikeClassesOption;
const StringRef AbseilStringsMatchHeaderOption;
};
} // namespace abseil

View File

@ -31,7 +31,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string RawRetryList;
const StringRef RawRetryList;
SmallVector<StringRef, 5> RetryMacros;
};

View File

@ -78,8 +78,8 @@ AssertSideEffectCheck::AssertSideEffectCheck(StringRef Name,
: ClangTidyCheck(Name, Context),
CheckFunctionCalls(Options.get("CheckFunctionCalls", false)),
RawAssertList(Options.get("AssertMacros", "assert,NSAssert,NSCAssert")),
IgnoredFunctions(utils::options::parseStringList(
"__builtin_expect;" + Options.get("IgnoredFunctions", ""))) {
IgnoredFunctions(utils::options::parseListPair(
"__builtin_expect;", Options.get("IgnoredFunctions", ""))) {
StringRef(RawAssertList).split(AssertMacros, ",", -1, false);
}

View File

@ -40,9 +40,9 @@ public:
private:
const bool CheckFunctionCalls;
const std::string RawAssertList;
const StringRef RawAssertList;
SmallVector<StringRef, 5> AssertMacros;
const std::vector<std::string> IgnoredFunctions;
const std::vector<StringRef> IgnoredFunctions;
};
} // namespace bugprone

View File

@ -94,9 +94,7 @@ DanglingHandleCheck::DanglingHandleCheck(StringRef Name,
HandleClasses(utils::options::parseStringList(Options.get(
"HandleClasses",
"std::basic_string_view;std::experimental::basic_string_view"))),
IsAHandle(cxxRecordDecl(hasAnyName(std::vector<StringRef>(
HandleClasses.begin(), HandleClasses.end())))
.bind("handle")) {}
IsAHandle(cxxRecordDecl(hasAnyName(HandleClasses)).bind("handle")) {}
void DanglingHandleCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "HandleClasses",

View File

@ -31,7 +31,7 @@ private:
void registerMatchersForVariables(ast_matchers::MatchFinder *Finder);
void registerMatchersForReturn(ast_matchers::MatchFinder *Finder);
const std::vector<std::string> HandleClasses;
const std::vector<StringRef> HandleClasses;
const ast_matchers::internal::Matcher<RecordDecl> IsAHandle;
};

View File

@ -36,7 +36,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string RawStringHeaderFileExtensions;
const StringRef RawStringHeaderFileExtensions;
utils::FileExtensionsSet HeaderFileExtensions;
};

View File

@ -1552,7 +1552,7 @@ static bool isIgnoredParameter(const TheCheck &Check, const ParmVarDecl *Node) {
LLVM_DEBUG(llvm::dbgs() << "\tType name is '" << NodeTypeName << "'\n");
if (!NodeTypeName.empty()) {
if (llvm::any_of(Check.IgnoredParameterTypeSuffixes,
[NodeTypeName](const std::string &E) {
[NodeTypeName](StringRef E) {
return !E.empty() && NodeTypeName.endswith(E);
})) {
LLVM_DEBUG(llvm::dbgs() << "\tType suffix ignored.\n");

View File

@ -33,11 +33,11 @@ public:
const std::size_t MinimumLength;
/// The parameter names (as written in the source text) to be ignored.
const std::vector<std::string> IgnoredParameterNames;
const std::vector<StringRef> IgnoredParameterNames;
/// The parameter typename suffixes (as written in the source code) to be
/// ignored.
const std::vector<std::string> IgnoredParameterTypeSuffixes;
const std::vector<StringRef> IgnoredParameterTypeSuffixes;
/// Whether to consider differently qualified versions of the same type
/// mixable.

View File

@ -109,7 +109,7 @@ static std::string getNonReservedFixup(std::string Name) {
static Optional<RenamerClangTidyCheck::FailureInfo>
getFailureInfoImpl(StringRef Name, bool IsInGlobalNamespace,
const LangOptions &LangOpts, bool Invert,
ArrayRef<std::string> AllowedIdentifiers) {
ArrayRef<StringRef> AllowedIdentifiers) {
assert(!Name.empty());
if (llvm::is_contained(AllowedIdentifiers, Name))
return None;

View File

@ -32,7 +32,7 @@ namespace bugprone {
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-reserved-identifier.html
class ReservedIdentifierCheck final : public RenamerClangTidyCheck {
const bool Invert;
const std::vector<std::string> AllowedIdentifiers;
const std::vector<StringRef> AllowedIdentifiers;
public:
ReservedIdentifierCheck(StringRef Name, ClangTidyContext *Context);

View File

@ -20,12 +20,6 @@ namespace bugprone {
static constexpr int UnsignedASCIIUpperBound = 127;
static Matcher<TypedefDecl> hasAnyListedName(const std::string &Names) {
const std::vector<std::string> NameList =
utils::options::parseStringList(Names);
return hasAnyName(std::vector<StringRef>(NameList.begin(), NameList.end()));
}
SignedCharMisuseCheck::SignedCharMisuseCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@ -46,8 +40,8 @@ BindableMatcher<clang::Stmt> SignedCharMisuseCheck::charCastExpression(
// We can ignore typedefs which are some kind of integer types
// (e.g. typedef char sal_Int8). In this case, we don't need to
// worry about the misinterpretation of char values.
const auto IntTypedef = qualType(
hasDeclaration(typedefDecl(hasAnyListedName(CharTypdefsToIgnoreList))));
const auto IntTypedef = qualType(hasDeclaration(typedefDecl(
hasAnyName(utils::options::parseStringList(CharTypdefsToIgnoreList)))));
auto CharTypeExpr = expr();
if (IsSigned) {

View File

@ -37,7 +37,7 @@ private:
const ast_matchers::internal::Matcher<clang::QualType> &IntegerType,
const std::string &CastBindName) const;
const std::string CharTypdefsToIgnoreList;
const StringRef CharTypdefsToIgnoreList;
const bool DiagnoseSignedUnsignedCharComparisons;
};

View File

@ -27,7 +27,7 @@ const char DefaultStringNames[] =
"::std::basic_string;::std::basic_string_view";
static std::vector<StringRef>
removeNamespaces(const std::vector<std::string> &Names) {
removeNamespaces(const std::vector<StringRef> &Names) {
std::vector<StringRef> Result;
Result.reserve(Names.size());
for (StringRef Name : Names) {

View File

@ -33,7 +33,7 @@ private:
const bool IsStringviewNullptrCheckEnabled;
const bool WarnOnLargeLength;
const unsigned int LargeLengthThreshold;
std::vector<std::string> StringNames;
std::vector<StringRef> StringNames;
};
} // namespace bugprone

View File

@ -46,8 +46,8 @@ public:
utils::FileExtensionsSet ImplementationFileExtensions;
private:
const std::string RawStringHeaderFileExtensions;
const std::string RawStringImplementationFileExtensions;
const StringRef RawStringHeaderFileExtensions;
const StringRef RawStringImplementationFileExtensions;
};
} // namespace bugprone

View File

@ -73,7 +73,7 @@ SuspiciousMissingCommaCheck::SuspiciousMissingCommaCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
SizeThreshold(Options.get("SizeThreshold", 5U)),
RatioThreshold(std::stod(Options.get("RatioThreshold", ".2"))),
RatioThreshold(std::stod(Options.get("RatioThreshold", ".2").str())),
MaxConcatenatedTokens(Options.get("MaxConcatenatedTokens", 5U)) {}
void SuspiciousMissingCommaCheck::storeOptions(

View File

@ -91,15 +91,12 @@ void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) {
// Add the list of known string compare-like functions and add user-defined
// functions.
std::vector<std::string> FunctionNames = utils::options::parseStringList(
(llvm::Twine(KnownStringCompareFunctions) + StringCompareLikeFunctions)
.str());
std::vector<StringRef> FunctionNames = utils::options::parseListPair(
KnownStringCompareFunctions, StringCompareLikeFunctions);
// Match a call to a string compare functions.
const auto FunctionCompareDecl =
functionDecl(hasAnyName(std::vector<StringRef>(FunctionNames.begin(),
FunctionNames.end())))
.bind("decl");
functionDecl(hasAnyName(FunctionNames)).bind("decl");
const auto DirectStringCompareCallExpr =
callExpr(hasDeclaration(FunctionCompareDecl)).bind("call");
const auto MacroStringCompareCallExpr = conditionalOperator(anyOf(

View File

@ -29,7 +29,7 @@ public:
private:
const bool WarnOnImplicitComparison;
const bool WarnOnLogicalNotComparison;
const std::string StringCompareLikeFunctions;
const StringRef StringCompareLikeFunctions;
};
} // namespace bugprone

View File

@ -138,8 +138,7 @@ void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) {
callExpr(callee(functionDecl(
// Don't match void overloads of checked functions.
unless(returns(voidType())),
isInstantiatedFrom(hasAnyName(
std::vector<StringRef>(FunVec.begin(), FunVec.end()))))))
isInstantiatedFrom(hasAnyName(FunVec)))))
.bind("match"))));
auto UnusedInCompoundStmt =

View File

@ -30,10 +30,6 @@ AST_MATCHER(CXXRecordDecl, isTriviallyDefaultConstructible) {
AST_MATCHER(CXXRecordDecl, isTriviallyCopyable) {
return Node.hasTrivialCopyAssignment() && Node.hasTrivialCopyConstructor();
}
AST_MATCHER_P(NamedDecl, hasAnyNameStdString, std::vector<std::string>,
String) {
return ast_matchers::internal::HasNameMatcher(String).matchesNode(Node);
}
} // namespace
static const char BuiltinMemSet[] = "::std::memset;"
@ -56,19 +52,6 @@ static constexpr llvm::StringRef ComparisonOperators[] = {
"operator==", "operator!=", "operator<",
"operator>", "operator<=", "operator>="};
static std::vector<std::string> parseStringListPair(StringRef LHS,
StringRef RHS) {
if (LHS.empty()) {
if (RHS.empty())
return {};
return utils::options::parseStringList(RHS);
}
if (RHS.empty())
return utils::options::parseStringList(LHS);
llvm::SmallString<512> Buffer;
return utils::options::parseStringList((LHS + RHS).toStringRef(Buffer));
}
NonTrivialTypesLibcMemoryCallsCheck::NonTrivialTypesLibcMemoryCallsCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@ -104,21 +87,21 @@ void NonTrivialTypesLibcMemoryCallsCheck::registerMatchers(
};
Finder->addMatcher(
callExpr(callee(namedDecl(hasAnyNameStdString(
parseStringListPair(BuiltinMemSet, MemSetNames)))),
callExpr(callee(namedDecl(hasAnyName(
utils::options::parseListPair(BuiltinMemSet, MemSetNames)))),
ArgChecker(unless(isTriviallyDefaultConstructible()),
expr(integerLiteral(equals(0)))))
.bind("lazyConstruct"),
this);
Finder->addMatcher(
callExpr(callee(namedDecl(hasAnyNameStdString(
parseStringListPair(BuiltinMemCpy, MemCpyNames)))),
callExpr(callee(namedDecl(hasAnyName(
utils::options::parseListPair(BuiltinMemCpy, MemCpyNames)))),
ArgChecker(unless(isTriviallyCopyable()), IsStructPointer()))
.bind("lazyCopy"),
this);
Finder->addMatcher(
callExpr(callee(namedDecl(hasAnyNameStdString(
parseStringListPair(BuiltinMemCmp, MemCmpNames)))),
callExpr(callee(namedDecl(hasAnyName(
utils::options::parseListPair(BuiltinMemCmp, MemCmpNames)))),
ArgChecker(hasMethod(hasAnyName(ComparisonOperators)),
IsStructPointer()))
.bind("lazyCompare"),

View File

@ -32,9 +32,9 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string MemSetNames;
const std::string MemCpyNames;
const std::string MemCmpNames;
const StringRef MemSetNames;
const StringRef MemCpyNames;
const StringRef MemCmpNames;
};
} // namespace cert

View File

@ -32,7 +32,7 @@ public:
private:
utils::IncludeInserter IncludeInserter;
const std::string MathHeader;
const StringRef MathHeader;
};
} // namespace cppcoreguidelines

View File

@ -24,13 +24,6 @@ using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace cppcoreguidelines {
namespace {
auto hasAnyListedName(const std::string &Names) {
const std::vector<std::string> NameList =
utils::options::parseStringList(Names);
return hasAnyName(std::vector<StringRef>(NameList.begin(), NameList.end()));
}
} // namespace
NarrowingConversionsCheck::NarrowingConversionsCheck(StringRef Name,
ClangTidyContext *Context)
@ -79,8 +72,8 @@ void NarrowingConversionsCheck::registerMatchers(MatchFinder *Finder) {
// We may want to exclude other types from the checks, such as `size_type`
// and `difference_type`. These are often used to count elements, represented
// in 64 bits and assigned to `int`. Rarely are people counting >2B elements.
const auto IsConversionFromIgnoredType =
hasType(namedDecl(hasAnyListedName(IgnoreConversionFromTypes)));
const auto IsConversionFromIgnoredType = hasType(namedDecl(
hasAnyName(utils::options::parseStringList(IgnoreConversionFromTypes))));
// `IsConversionFromIgnoredType` will ignore narrowing calls from those types,
// but not expressions that are promoted to an ignored type as a result of a

View File

@ -102,7 +102,7 @@ private:
const bool WarnOnFloatingPointNarrowingConversion;
const bool WarnWithinTemplateInstantiation;
const bool WarnOnEquivalentBitWidth;
const std::string IgnoreConversionFromTypes;
const StringRef IgnoreConversionFromTypes;
const bool PedanticMode;
};

View File

@ -22,14 +22,6 @@ namespace clang {
namespace tidy {
namespace cppcoreguidelines {
namespace {
Matcher<FunctionDecl> hasAnyListedName(const std::string &FunctionNames) {
const std::vector<std::string> NameList =
utils::options::parseStringList(FunctionNames);
return hasAnyName(std::vector<StringRef>(NameList.begin(), NameList.end()));
}
} // namespace
void NoMallocCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "Allocations", AllocList);
Options.store(Opts, "Reallocations", ReallocList);
@ -38,19 +30,22 @@ void NoMallocCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void NoMallocCheck::registerMatchers(MatchFinder *Finder) {
// Registering malloc, will suggest RAII.
Finder->addMatcher(callExpr(callee(functionDecl(hasAnyListedName(AllocList))))
Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName(
utils::options::parseStringList(AllocList)))))
.bind("allocation"),
this);
// Registering realloc calls, suggest std::vector or std::string.
Finder->addMatcher(
callExpr(callee(functionDecl(hasAnyListedName(ReallocList))))
callExpr(callee(functionDecl(
hasAnyName(utils::options::parseStringList((ReallocList))))))
.bind("realloc"),
this);
// Registering free calls, will suggest RAII instead.
Finder->addMatcher(
callExpr(callee(functionDecl(hasAnyListedName(DeallocList))))
callExpr(callee(functionDecl(
hasAnyName(utils::options::parseStringList((DeallocList))))))
.bind("free"),
this);
}

View File

@ -47,13 +47,13 @@ public:
private:
/// Semicolon-separated list of fully qualified names of memory allocation
/// functions the check warns about. Defaults to `::malloc;::calloc`.
const std::string AllocList;
const StringRef AllocList;
/// Semicolon-separated list of fully qualified names of memory reallocation
/// functions the check warns about. Defaults to `::realloc`.
const std::string ReallocList;
const StringRef ReallocList;
/// Semicolon-separated list of fully qualified names of memory deallocation
/// functions the check warns about. Defaults to `::free`.
const std::string DeallocList;
const StringRef DeallocList;
};
} // namespace cppcoreguidelines

View File

@ -21,16 +21,6 @@ namespace clang {
namespace tidy {
namespace cppcoreguidelines {
// FIXME: Copied from 'NoMallocCheck.cpp'. Has to be refactored into 'util' or
// something like that.
namespace {
Matcher<FunctionDecl> hasAnyListedName(const std::string &FunctionNames) {
const std::vector<std::string> NameList =
utils::options::parseStringList(FunctionNames);
return hasAnyName(std::vector<StringRef>(NameList.begin(), NameList.end()));
}
} // namespace
void OwningMemoryCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "LegacyResourceProducers", LegacyResourceProducers);
Options.store(Opts, "LegacyResourceConsumers", LegacyResourceConsumers);
@ -42,9 +32,10 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
const auto OwnerDecl = typeAliasTemplateDecl(hasName("::gsl::owner"));
const auto IsOwnerType = hasType(OwnerDecl);
const auto LegacyCreatorFunctions = hasAnyListedName(LegacyResourceProducers);
const auto LegacyCreatorFunctions =
hasAnyName(utils::options::parseStringList(LegacyResourceProducers));
const auto LegacyConsumerFunctions =
hasAnyListedName(LegacyResourceConsumers);
hasAnyName(utils::options::parseStringList(LegacyResourceConsumers));
// Legacy functions that are use for resource management but cannot be
// updated to use `gsl::owner<>`, like standard C memory management.

View File

@ -52,10 +52,10 @@ private:
/// List of old C-style functions that create resources.
/// Defaults to
/// `::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile`.
const std::string LegacyResourceProducers;
const StringRef LegacyResourceProducers;
/// List of old C-style functions that consume or release resources.
/// Defaults to `::free;::realloc;::freopen;::fclose`.
const std::string LegacyResourceConsumers;
const StringRef LegacyResourceConsumers;
};
} // namespace cppcoreguidelines

View File

@ -22,7 +22,7 @@ namespace cppcoreguidelines {
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html
class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck {
const std::string GslHeader;
const StringRef GslHeader;
utils::IncludeInserter Inserter;
public:

View File

@ -38,7 +38,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string RawStringHeaderFileExtensions;
const StringRef RawStringHeaderFileExtensions;
utils::FileExtensionsSet HeaderFileExtensions;
};

View File

@ -39,9 +39,9 @@ public:
void storeOptions(ClangTidyOptions::OptionMap &Options) override;
private:
const std::string UnsignedTypePrefix;
const std::string SignedTypePrefix;
const std::string TypeSuffix;
const StringRef UnsignedTypePrefix;
const StringRef SignedTypePrefix;
const StringRef TypeSuffix;
std::unique_ptr<IdentifierTable> IdentTable;
};

View File

@ -44,7 +44,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string RawStringHeaderFileExtensions;
const StringRef RawStringHeaderFileExtensions;
utils::FileExtensionsSet HeaderFileExtensions;
};

View File

@ -43,7 +43,7 @@ public:
private:
const bool UseHeaderFileExtension;
const std::string RawStringHeaderFileExtensions;
const StringRef RawStringHeaderFileExtensions;
utils::FileExtensionsSet HeaderFileExtensions;
};

View File

@ -177,7 +177,7 @@ private:
class DeclFinderASTVisitor
: public clang::RecursiveASTVisitor<DeclFinderASTVisitor> {
public:
DeclFinderASTVisitor(const std::string &Name,
DeclFinderASTVisitor(const StringRef &Name,
const StmtGeneratedVarNameMap *GeneratedDecls)
: Name(Name), GeneratedDecls(GeneratedDecls), Found(false) {}

View File

@ -47,8 +47,8 @@ protected:
private:
utils::IncludeInserter Inserter;
const std::string MakeSmartPtrFunctionHeader;
const std::string MakeSmartPtrFunctionName;
const StringRef MakeSmartPtrFunctionHeader;
const StringRef MakeSmartPtrFunctionName;
const bool IgnoreMacros;
const bool IgnoreDefaultInitialization;

View File

@ -49,10 +49,10 @@ public:
Preprocessor *ModuleExpanderPP) override;
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
const std::string &getMacroName() const { return MacroName; }
const StringRef &getMacroName() const { return MacroName; }
private:
const std::string MacroName;
const StringRef MacroName;
};
} // namespace modernize

View File

@ -50,15 +50,14 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
// + match for emplace calls that should be replaced with insertion
auto CallPushBack = cxxMemberCallExpr(
hasDeclaration(functionDecl(hasName("push_back"))),
on(hasType(cxxRecordDecl(hasAnyName(SmallVector<StringRef, 5>(
ContainersWithPushBack.begin(), ContainersWithPushBack.end()))))));
on(hasType(cxxRecordDecl(hasAnyName(ContainersWithPushBack)))));
// We can't replace push_backs of smart pointer because
// if emplacement fails (f.e. bad_alloc in vector) we will have leak of
// passed pointer because smart pointer won't be constructed
// (and destructed) as in push_back case.
auto IsCtorOfSmartPtr = hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(
SmallVector<StringRef, 5>(SmartPointers.begin(), SmartPointers.end())))));
auto IsCtorOfSmartPtr =
hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(SmartPointers))));
// Bitfields binds only to consts and emplace_back take it by universal ref.
auto BitFieldAsArgument = hasAnyArgument(
@ -91,19 +90,16 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
auto HasConstructExpr = has(ignoringImplicit(SoughtConstructExpr));
auto MakeTuple = ignoringImplicit(
callExpr(
callee(expr(ignoringImplicit(declRefExpr(
unless(hasExplicitTemplateArgs()),
to(functionDecl(hasAnyName(SmallVector<StringRef, 2>(
TupleMakeFunctions.begin(), TupleMakeFunctions.end())))))))))
callExpr(callee(expr(ignoringImplicit(declRefExpr(
unless(hasExplicitTemplateArgs()),
to(functionDecl(hasAnyName(TupleMakeFunctions))))))))
.bind("make"));
// make_something can return type convertible to container's element type.
// Allow the conversion only on containers of pairs.
auto MakeTupleCtor = ignoringImplicit(cxxConstructExpr(
has(materializeTemporaryExpr(MakeTuple)),
hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(
SmallVector<StringRef, 2>(TupleTypes.begin(), TupleTypes.end())))))));
hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(TupleTypes))))));
auto SoughtParam = materializeTemporaryExpr(
anyOf(has(MakeTuple), has(MakeTupleCtor),

View File

@ -36,10 +36,10 @@ public:
private:
const bool IgnoreImplicitConstructors;
const std::vector<std::string> ContainersWithPushBack;
const std::vector<std::string> SmartPointers;
const std::vector<std::string> TupleTypes;
const std::vector<std::string> TupleMakeFunctions;
const std::vector<StringRef> ContainersWithPushBack;
const std::vector<StringRef> SmartPointers;
const std::vector<StringRef> TupleTypes;
const std::vector<StringRef> TupleMakeFunctions;
};
} // namespace modernize

View File

@ -131,7 +131,7 @@ void UseNodiscardCheck::check(const MatchFinder::MatchResult &Result) {
// 1. A const member function which returns a variable which is ignored
// but performs some external I/O operation and the return value could be
// ignored.
Diag << FixItHint::CreateInsertion(RetLoc, NoDiscardMacro + " ");
Diag << FixItHint::CreateInsertion(RetLoc, (NoDiscardMacro + " ").str());
}
bool UseNodiscardCheck::isLanguageVersionSupported(

View File

@ -40,7 +40,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string NoDiscardMacro;
const StringRef NoDiscardMacro;
};
} // namespace modernize

View File

@ -89,12 +89,10 @@ void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
bool IsNoThrow = FnTy->isNothrow();
StringRef ReplacementStr =
IsNoThrow
? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro.c_str()
: NoexceptMacro.empty()
? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)"
: ""
: "";
IsNoThrow ? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro
: NoexceptMacro.empty()
? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)" : ""
: "";
FixItHint FixIt;
if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())

View File

@ -40,7 +40,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string NoexceptMacro;
const StringRef NoexceptMacro;
const bool UseNoexceptFalse;
};

View File

@ -28,7 +28,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
const std::string NullMacrosStr;
const StringRef NullMacrosStr;
SmallVector<StringRef, 1> NullMacros;
};

View File

@ -141,7 +141,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
// Add 'override' on inline declarations that don't already have it.
if (!HasFinal && !HasOverride) {
SourceLocation InsertLoc;
std::string ReplacementText = OverrideSpelling + " ";
std::string ReplacementText = (OverrideSpelling + " ").str();
SourceLocation MethodLoc = Method->getLocation();
for (Token T : Tokens) {
@ -171,7 +171,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
// end of the declaration of the function, but prefer to put it on the
// same line as the declaration if the beginning brace for the start of
// the body falls on the next line.
ReplacementText = " " + OverrideSpelling;
ReplacementText = (" " + OverrideSpelling).str();
auto *LastTokenIter = std::prev(Tokens.end());
// When try statement is used instead of compound statement as
// method body - insert override keyword before it.
@ -192,14 +192,14 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
InsertLoc = Tokens[Tokens.size() - 2].getLocation();
// Check if we need to insert a space.
if ((Tokens[Tokens.size() - 2].getFlags() & Token::LeadingSpace) == 0)
ReplacementText = " " + OverrideSpelling + " ";
ReplacementText = (" " + OverrideSpelling + " ").str();
} else if (getText(Tokens.back(), Sources) == "ABSTRACT")
InsertLoc = Tokens.back().getLocation();
}
if (!InsertLoc.isValid()) {
InsertLoc = FileRange.getEnd();
ReplacementText = " " + OverrideSpelling;
ReplacementText = (" " + OverrideSpelling).str();
}
// If the override macro has been specified just ensure it exists,

View File

@ -30,8 +30,8 @@ public:
private:
const bool IgnoreDestructors;
const bool AllowOverrideAndFinal;
const std::string OverrideSpelling;
const std::string FinalSpelling;
const StringRef OverrideSpelling;
const StringRef FinalSpelling;
};
} // namespace modernize

View File

@ -51,14 +51,9 @@ ForbiddenSubclassingCheck::ForbiddenSubclassingCheck(
void ForbiddenSubclassingCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
objcInterfaceDecl(
isDerivedFrom(
objcInterfaceDecl(
hasAnyName(
std::vector<StringRef>(
ForbiddenSuperClassNames.begin(),
ForbiddenSuperClassNames.end())))
.bind("superclass")))
.bind("subclass"),
isDerivedFrom(objcInterfaceDecl(hasAnyName(ForbiddenSuperClassNames))
.bind("superclass")))
.bind("subclass"),
this);
}

View File

@ -11,7 +11,6 @@
#include "../ClangTidyCheck.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
namespace clang {
@ -34,7 +33,7 @@ public:
void storeOptions(ClangTidyOptions::OptionMap &Options) override;
private:
const std::vector<std::string> ForbiddenSuperClassNames;
const std::vector<StringRef> ForbiddenSuperClassNames;
};
} // namespace objc

View File

@ -71,11 +71,9 @@ void FasterStringFindCheck::registerMatchers(MatchFinder *Finder) {
callee(functionDecl(StringFindFunctions).bind("func")),
anyOf(argumentCountIs(1), argumentCountIs(2)),
hasArgument(0, SingleChar),
on(expr(
hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
recordDecl(hasAnyName(SmallVector<StringRef, 4>(
StringLikeClasses.begin(), StringLikeClasses.end()))))))),
unless(hasSubstitutedType())))),
on(expr(hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
recordDecl(hasAnyName(StringLikeClasses)))))),
unless(hasSubstitutedType())))),
this);
}

View File

@ -35,7 +35,7 @@ public:
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
private:
const std::vector<std::string> StringLikeClasses;
const std::vector<StringRef> StringLikeClasses;
};
} // namespace performance

View File

@ -42,7 +42,7 @@ private:
ASTContext &Context);
const bool WarnOnAllAutoCopies;
const std::vector<std::string> AllowedTypes;
const std::vector<StringRef> AllowedTypes;
};
} // namespace performance

View File

@ -159,8 +159,7 @@ void InefficientVectorOperationCheck::addMatcher(
}
void InefficientVectorOperationCheck::registerMatchers(MatchFinder *Finder) {
const auto VectorDecl = cxxRecordDecl(hasAnyName(SmallVector<StringRef, 5>(
VectorLikeClasses.begin(), VectorLikeClasses.end())));
const auto VectorDecl = cxxRecordDecl(hasAnyName(VectorLikeClasses));
const auto AppendMethodDecl =
cxxMethodDecl(hasAnyName("push_back", "emplace_back"));
addMatcher(VectorDecl, VectorVarDeclName, VectorVarDeclStmtName,

View File

@ -38,7 +38,7 @@ private:
StringRef VarDeclName, StringRef VarDeclStmtName,
const ast_matchers::DeclarationMatcher &AppendMethodDecl,
StringRef AppendCallName, ast_matchers::MatchFinder *Finder);
const std::vector<std::string> VectorLikeClasses;
const std::vector<StringRef> VectorLikeClasses;
// If true, also check inefficient operations for proto repeated fields.
bool EnableProto;

View File

@ -29,7 +29,7 @@ public:
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
private:
const std::vector<std::string> AllowedTypes;
const std::vector<StringRef> AllowedTypes;
};
} // namespace performance

View File

@ -76,7 +76,7 @@ void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
}
AST_MATCHER_FUNCTION_P(StatementMatcher, isConstRefReturningMethodCall,
std::vector<std::string>, ExcludedContainerTypes) {
std::vector<StringRef>, ExcludedContainerTypes) {
// Match method call expressions where the `this` argument is only used as
// const, this will be checked in `check()` part. This returned const
// reference is highly likely to outlive the local const reference of the
@ -110,7 +110,7 @@ AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) {
}
AST_MATCHER_FUNCTION_P(StatementMatcher, initializerReturnsReferenceToConst,
std::vector<std::string>, ExcludedContainerTypes) {
std::vector<StringRef>, ExcludedContainerTypes) {
auto OldVarDeclRef =
declRefExpr(to(varDecl(hasLocalStorage()).bind(OldVarDeclId)));
return expr(
@ -135,7 +135,7 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, initializerReturnsReferenceToConst,
// object arg or variable that is referenced is immutable as well.
static bool isInitializingVariableImmutable(
const VarDecl &InitializingVar, const Stmt &BlockStmt, ASTContext &Context,
const std::vector<std::string> &ExcludedContainerTypes) {
const std::vector<StringRef> &ExcludedContainerTypes) {
if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context))
return false;

View File

@ -42,8 +42,8 @@ private:
void handleCopyFromLocalVar(const VarDecl &NewVar, const VarDecl &OldVar,
const Stmt &BlockStmt, const DeclStmt &Stmt,
bool IssueFix, ASTContext &Context);
const std::vector<std::string> AllowedTypes;
const std::vector<std::string> ExcludedContainerTypes;
const std::vector<StringRef> AllowedTypes;
const std::vector<StringRef> ExcludedContainerTypes;
};
} // namespace performance

View File

@ -42,7 +42,7 @@ private:
llvm::DenseMap<const FunctionDecl *, FunctionParmMutationAnalyzer>
MutationAnalyzers;
utils::IncludeInserter Inserter;
const std::vector<std::string> AllowedTypes;
const std::vector<StringRef> AllowedTypes;
};
} // namespace performance

View File

@ -265,7 +265,7 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions(
StyleString.resize(StyleSize);
StyleString.append("IgnoredRegexp");
std::string IgnoredRegexpStr = Options.get(StyleString, "");
StringRef IgnoredRegexpStr = Options.get(StyleString, "");
StyleString.resize(StyleSize);
StyleString.append("Prefix");
std::string Prefix(Options.get(StyleString, ""));
@ -281,7 +281,7 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions(
if (CaseOptional || !Prefix.empty() || !Postfix.empty() ||
!IgnoredRegexpStr.empty() || HPTOpt)
Styles[I].emplace(std::move(CaseOptional), std::move(Prefix),
std::move(Postfix), std::move(IgnoredRegexpStr),
std::move(Postfix), IgnoredRegexpStr.str(),
HPTOpt.getValueOr(IdentifierNamingCheck::HPT_Off));
}
bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false);
@ -445,16 +445,16 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig(
SmallString<128> Buffer;
for (const auto &Opt : HNOpts) {
Buffer.assign({Section, "General.", Opt});
std::string Val = Options.get(Buffer, "");
StringRef Val = Options.get(Buffer, "");
if (!Val.empty())
HNOption.General[Opt] = std::move(Val);
HNOption.General[Opt] = Val.str();
}
for (const auto &Type : HNDerivedTypes) {
Buffer.assign({Section, "DerivedType.", Type});
std::string Val = Options.get(Buffer, "");
StringRef Val = Options.get(Buffer, "");
if (!Val.empty())
HNOption.DerivedType[Type] = std::move(Val);
HNOption.DerivedType[Type] = Val.str();
}
static constexpr std::pair<StringRef, StringRef> HNCStrings[] = {
@ -465,26 +465,26 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig(
for (const auto &CStr : HNCStrings) {
Buffer.assign({Section, "CString.", CStr.first});
std::string Val = Options.get(Buffer, "");
StringRef Val = Options.get(Buffer, "");
if (!Val.empty())
HNOption.CString[CStr.first] = std::move(Val);
HNOption.CString[CStr.first] = Val.str();
}
for (const auto &PrimType : HungarainNotationPrimitiveTypes) {
Buffer.assign({Section, "PrimitiveType.", PrimType});
std::string Val = Options.get(Buffer, "");
StringRef Val = Options.get(Buffer, "");
if (!Val.empty()) {
std::string Type = PrimType.str();
std::replace(Type.begin(), Type.end(), '-', ' ');
HNOption.PrimitiveType[Type] = std::move(Val);
HNOption.PrimitiveType[Type] = Val.str();
}
}
for (const auto &Type : HungarainNotationUserDefinedTypes) {
Buffer.assign({Section, "UserDefinedType.", Type});
std::string Val = Options.get(Buffer, "");
StringRef Val = Options.get(Buffer, "");
if (!Val.empty())
HNOption.UserDefinedType[Type] = std::move(Val);
HNOption.UserDefinedType[Type] = Val.str();
}
}

View File

@ -198,7 +198,7 @@ private:
mutable llvm::StringMap<FileStyle> NamingStylesCache;
FileStyle *MainFileStyle;
ClangTidyContext *Context;
const std::string CheckName;
const StringRef CheckName;
const bool GetConfigPerFile;
const bool IgnoreFailedSplit;
HungarianNotation HungarianNotation;

View File

@ -72,16 +72,20 @@ MagicNumbersCheck::MagicNumbersCheck(StringRef Name, ClangTidyContext *Context)
RawIgnoredFloatingPointValues(Options.get(
"IgnoredFloatingPointValues", DefaultIgnoredFloatingPointValues)) {
// Process the set of ignored integer values.
const std::vector<std::string> IgnoredIntegerValuesInput =
const std::vector<StringRef> IgnoredIntegerValuesInput =
utils::options::parseStringList(RawIgnoredIntegerValues);
IgnoredIntegerValues.resize(IgnoredIntegerValuesInput.size());
llvm::transform(IgnoredIntegerValuesInput, IgnoredIntegerValues.begin(),
[](const std::string &Value) { return std::stoll(Value); });
[](StringRef Value) {
int64_t Res;
Value.getAsInteger(10, Res);
return Res;
});
llvm::sort(IgnoredIntegerValues);
if (!IgnoreAllFloatingPointValues) {
// Process the set of ignored floating point values.
const std::vector<std::string> IgnoredFloatingPointValuesInput =
const std::vector<StringRef> IgnoredFloatingPointValuesInput =
utils::options::parseStringList(RawIgnoredFloatingPointValues);
IgnoredFloatingPointValues.reserve(IgnoredFloatingPointValuesInput.size());
IgnoredDoublePointValues.reserve(IgnoredFloatingPointValuesInput.size());

View File

@ -86,8 +86,8 @@ private:
const bool IgnoreAllFloatingPointValues;
const bool IgnoreBitFieldsWidths;
const bool IgnorePowersOf2IntegerValues;
const std::string RawIgnoredIntegerValues;
const std::string RawIgnoredFloatingPointValues;
const StringRef RawIgnoredIntegerValues;
const StringRef RawIgnoredFloatingPointValues;
constexpr static unsigned SensibleNumberOfMagicValueExceptions = 16;

View File

@ -21,20 +21,13 @@ namespace readability {
const char DefaultStringNames[] =
"::std::basic_string_view;::std::basic_string";
static ast_matchers::internal::Matcher<NamedDecl>
hasAnyNameStdString(std::vector<std::string> Names) {
return ast_matchers::internal::Matcher<NamedDecl>(
new ast_matchers::internal::HasNameMatcher(std::move(Names)));
}
static std::vector<std::string>
removeNamespaces(const std::vector<std::string> &Names) {
std::vector<std::string> Result;
static std::vector<StringRef> removeNamespaces(ArrayRef<StringRef> Names) {
std::vector<StringRef> Result;
Result.reserve(Names.size());
for (const std::string &Name : Names) {
std::string::size_type ColonPos = Name.rfind(':');
for (StringRef Name : Names) {
StringRef::size_type ColonPos = Name.rfind(':');
Result.push_back(
Name.substr(ColonPos == std::string::npos ? 0 : ColonPos + 1));
Name.drop_front(ColonPos == StringRef::npos ? 0 : ColonPos + 1));
}
return Result;
}
@ -72,9 +65,8 @@ void RedundantStringInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
const auto HasStringTypeName = hasAnyNameStdString(StringNames);
const auto HasStringCtorName =
hasAnyNameStdString(removeNamespaces(StringNames));
const auto HasStringTypeName = hasAnyName(StringNames);
const auto HasStringCtorName = hasAnyName(removeNamespaces(StringNames));
// Match string constructor.
const auto StringConstructorExpr = expr(

View File

@ -29,7 +29,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
std::vector<std::string> StringNames;
std::vector<StringRef> StringNames;
};
} // namespace readability

View File

@ -28,8 +28,7 @@ SimplifySubscriptExprCheck::SimplifySubscriptExprCheck(
void SimplifySubscriptExprCheck::registerMatchers(MatchFinder *Finder) {
const auto TypesMatcher = hasUnqualifiedDesugaredType(
recordType(hasDeclaration(cxxRecordDecl(hasAnyName(
llvm::SmallVector<StringRef, 8>(Types.begin(), Types.end()))))));
recordType(hasDeclaration(cxxRecordDecl(hasAnyName(Types)))));
Finder->addMatcher(
arraySubscriptExpr(hasBase(

View File

@ -33,7 +33,7 @@ public:
}
private:
const std::vector<std::string> Types;
const std::vector<StringRef> Types;
};
} // namespace readability

View File

@ -526,12 +526,13 @@ SuspiciousCallArgumentCheck::SuspiciousCallArgumentCheck(
GetBoundOpt(H, BoundKind::SimilarAbove)));
}
for (const std::string &Abbreviation : optutils::parseStringList(
for (StringRef Abbreviation : optutils::parseStringList(
Options.get("Abbreviations", DefaultAbbreviations))) {
auto KeyAndValue = StringRef{Abbreviation}.split("=");
auto KeyAndValue = Abbreviation.split("=");
llvm::errs() << "'" << Abbreviation << "'\n";
assert(!KeyAndValue.first.empty() && !KeyAndValue.second.empty());
AbbreviationDictionary.insert(
std::make_pair(KeyAndValue.first.str(), KeyAndValue.second.str()));
std::make_pair(KeyAndValue.first, KeyAndValue.second.str()));
}
}
@ -573,7 +574,8 @@ void SuspiciousCallArgumentCheck::storeOptions(
Abbreviations.emplace_back(EqualSignJoined.str());
}
Options.store(Opts, "Abbreviations",
optutils::serializeStringList(Abbreviations));
optutils::serializeStringList(std::vector<StringRef>(
Abbreviations.begin(), Abbreviations.end())));
}
bool SuspiciousCallArgumentCheck::isHeuristicEnabled(Heuristic H) const {

View File

@ -87,18 +87,18 @@ llvm::Optional<SourceRange> getMacroAwareSourceRange(SourceRange Loc,
llvm::Optional<std::string>
getNewSuffix(llvm::StringRef OldSuffix,
const std::vector<std::string> &NewSuffixes) {
const std::vector<StringRef> &NewSuffixes) {
// If there is no config, just uppercase the entirety of the suffix.
if (NewSuffixes.empty())
return OldSuffix.upper();
// Else, find matching suffix, case-*insensitive*ly.
auto NewSuffix = llvm::find_if(
NewSuffixes, [OldSuffix](const std::string &PotentialNewSuffix) {
auto NewSuffix =
llvm::find_if(NewSuffixes, [OldSuffix](StringRef PotentialNewSuffix) {
return OldSuffix.equals_insensitive(PotentialNewSuffix);
});
// Have a match, return it.
if (NewSuffix != NewSuffixes.end())
return *NewSuffix;
return NewSuffix->str();
// Nope, I guess we have to keep it as-is.
return llvm::None;
}
@ -106,7 +106,7 @@ getNewSuffix(llvm::StringRef OldSuffix,
template <typename LiteralType>
llvm::Optional<NewSuffix>
shouldReplaceLiteralSuffix(const Expr &Literal,
const std::vector<std::string> &NewSuffixes,
const std::vector<StringRef> &NewSuffixes,
const SourceManager &SM, const LangOptions &LO) {
NewSuffix ReplacementDsc;

View File

@ -36,7 +36,7 @@ private:
template <typename LiteralType>
bool checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result);
const std::vector<std::string> NewSuffixes;
const std::vector<StringRef> NewSuffixes;
const bool IgnoreMacros;
};

View File

@ -55,7 +55,7 @@ AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isPointerToConst) {
class MatchesAnyListedNameMatcher
: public ast_matchers::internal::MatcherInterface<NamedDecl> {
public:
explicit MatchesAnyListedNameMatcher(llvm::ArrayRef<std::string> NameList) {
explicit MatchesAnyListedNameMatcher(llvm::ArrayRef<StringRef> NameList) {
std::transform(
NameList.begin(), NameList.end(), std::back_inserter(NameMatchers),
[](const llvm::StringRef Name) { return NameMatcher(Name); });
@ -116,7 +116,7 @@ private:
// expressions. If a regular expression contains starts ':' the NamedDecl's
// qualified name will be used for matching, otherwise its name will be used.
inline ::clang::ast_matchers::internal::Matcher<NamedDecl>
matchesAnyListedName(llvm::ArrayRef<std::string> NameList) {
matchesAnyListedName(llvm::ArrayRef<StringRef> NameList) {
return ::clang::ast_matchers::internal::makeMatcher(
new MatchesAnyListedNameMatcher(NameList));
}

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "OptionsUtils.h"
#include "llvm/ADT/StringExtras.h"
namespace clang {
namespace tidy {
@ -15,19 +16,50 @@ namespace options {
static const char StringsDelimiter[] = ";";
std::vector<std::string> parseStringList(StringRef Option) {
SmallVector<StringRef, 4> Names;
Option.split(Names, StringsDelimiter);
std::vector<std::string> Result;
for (StringRef &Name : Names) {
Name = Name.trim();
if (!Name.empty())
Result.emplace_back(Name);
std::vector<StringRef> parseStringList(StringRef Option) {
Option = Option.trim().trim(StringsDelimiter);
if (Option.empty())
return {};
std::vector<StringRef> Result;
Result.reserve(Option.count(StringsDelimiter) + 1);
StringRef Cur;
while (std::tie(Cur, Option) = Option.split(StringsDelimiter),
!Option.empty()) {
Cur = Cur.trim();
if (!Cur.empty())
Result.push_back(Cur);
}
Cur = Cur.trim();
if (!Cur.empty())
Result.push_back(Cur);
return Result;
}
std::vector<StringRef> parseListPair(StringRef L, StringRef R) {
L = L.trim().trim(StringsDelimiter);
if (L.empty())
return parseStringList(R);
R = R.trim().trim(StringsDelimiter);
if (R.empty())
return parseStringList(L);
std::vector<StringRef> Result;
Result.reserve(2 + L.count(StringsDelimiter) + R.count(StringsDelimiter));
for (StringRef Option : {L, R}) {
StringRef Cur;
while (std::tie(Cur, Option) = Option.split(StringsDelimiter),
!Option.empty()) {
Cur = Cur.trim();
if (!Cur.empty())
Result.push_back(Cur);
}
Cur = Cur.trim();
if (!Cur.empty())
Result.push_back(Cur);
}
return Result;
}
std::string serializeStringList(ArrayRef<std::string> Strings) {
std::string serializeStringList(ArrayRef<StringRef> Strings) {
return llvm::join(Strings, StringsDelimiter);
}

View File

@ -9,7 +9,9 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
#include "../ClangTidy.h"
#include "clang/Basic/LLVM.h"
#include <string>
#include <vector>
namespace clang {
namespace tidy {
@ -17,11 +19,13 @@ namespace utils {
namespace options {
/// Parse a semicolon separated list of strings.
std::vector<std::string> parseStringList(StringRef Option);
std::vector<StringRef> parseStringList(StringRef Option);
std::vector<StringRef> parseListPair(StringRef L, StringRef R);
/// Serialize a sequence of names that can be parsed by
/// ``parseStringList``.
std::string serializeStringList(ArrayRef<std::string> Strings);
std::string serializeStringList(ArrayRef<StringRef> Strings);
} // namespace options
} // namespace utils

View File

@ -20,7 +20,7 @@ namespace clang {
namespace tidy {
namespace zircon {
AST_MATCHER_P(CXXRecordDecl, matchesAnyName, ArrayRef<std::string>, Names) {
AST_MATCHER_P(CXXRecordDecl, matchesAnyName, ArrayRef<StringRef>, Names) {
std::string QualifiedName = Node.getQualifiedNameAsString();
return llvm::any_of(Names,
[&](StringRef Name) { return QualifiedName == Name; });

View File

@ -31,7 +31,7 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
std::vector<std::string> Names;
std::vector<StringRef> Names;
};
} // namespace zircon