[clang-tidy] Lift parsing of sequence of names functions to utils.

Summary:
Lift some common code used by multiple checkers.

This function is also used by checkers that are coming.
It is quite common for a checker to parse a list of names.

Reviewers: alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19846

llvm-svn: 269065
This commit is contained in:
Etienne Bergeron 2016-05-10 15:31:15 +00:00
parent bf9473b2d8
commit de1ec03779
6 changed files with 87 additions and 53 deletions

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "DanglingHandleCheck.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
@ -19,20 +20,6 @@ namespace misc {
namespace {
static const char HandleClassesDelimiter[] = ";";
std::vector<std::string> parseClasses(StringRef Option) {
SmallVector<StringRef, 4> Classes;
Option.split(Classes, HandleClassesDelimiter);
std::vector<std::string> Result;
for (StringRef &Class : Classes) {
Class = Class.trim();
if (!Class.empty())
Result.push_back(Class);
}
return Result;
}
ast_matchers::internal::BindableMatcher<Stmt>
handleFrom(ast_matchers::internal::Matcher<RecordDecl> IsAHandle,
ast_matchers::internal::Matcher<Expr> Arg) {
@ -97,7 +84,7 @@ makeContainerMatcher(ast_matchers::internal::Matcher<RecordDecl> IsAHandle) {
DanglingHandleCheck::DanglingHandleCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
HandleClasses(parseClasses(Options.get(
HandleClasses(utils::options::parseStringList(Options.get(
"HandleClasses",
"std::basic_string_view;std::experimental::basic_string_view"))),
IsAHandle(cxxRecordDecl(hasAnyName(std::vector<StringRef>(
@ -106,8 +93,7 @@ DanglingHandleCheck::DanglingHandleCheck(StringRef Name,
void DanglingHandleCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "HandleClasses",
llvm::join(HandleClasses.begin(), HandleClasses.end(),
HandleClassesDelimiter));
utils::options::serializeStringList(HandleClasses));
}
void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {

View File

@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "SuspiciousStringCompareCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
#include "../utils/Matchers.h"
using namespace clang::ast_matchers;
@ -19,6 +20,9 @@ namespace clang {
namespace tidy {
namespace misc {
// Semicolon separated list of known string compare-like functions. The list
// must ends with a semicolon.
static const char KnownStringCompareFunctions[] = "__builtin_memcmp;"
"__builtin_strcasecmp;"
"__builtin_strcmp;"
@ -64,19 +68,6 @@ static const char KnownStringCompareFunctions[] = "__builtin_memcmp;"
"wcsnicmp;"
"wmemcmp;";
static const char StringCompareLikeFunctionsDelimiter[] = ";";
static void ParseFunctionNames(StringRef Option,
std::vector<std::string> *Result) {
SmallVector<StringRef, 4> Functions;
Option.split(Functions, StringCompareLikeFunctionsDelimiter);
for (StringRef &Function : Functions) {
Function = Function.trim();
if (!Function.empty())
Result->push_back(Function);
}
}
SuspiciousStringCompareCheck::SuspiciousStringCompareCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@ -102,9 +93,9 @@ void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) {
// Add the list of known string compare-like functions and add user-defined
// functions.
std::vector<std::string> FunctionNames;
ParseFunctionNames(KnownStringCompareFunctions, &FunctionNames);
ParseFunctionNames(StringCompareLikeFunctions, &FunctionNames);
std::vector<std::string> FunctionNames = utils::options::parseStringList(
(llvm::Twine(KnownStringCompareFunctions) + StringCompareLikeFunctions)
.str());
// Match a call to a string compare functions.
const auto FunctionCompareDecl =

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "FasterStringFindCheck.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/Optional.h"
@ -21,20 +22,6 @@ namespace performance {
namespace {
static const char StringLikeClassesDelimiter[] = ";";
std::vector<std::string> ParseClasses(StringRef Option) {
SmallVector<StringRef, 4> Classes;
Option.split(Classes, StringLikeClassesDelimiter);
std::vector<std::string> Result;
for (StringRef &Class : Classes) {
Class = Class.trim();
if (!Class.empty())
Result.push_back(Class);
}
return Result;
}
llvm::Optional<std::string> MakeCharacterLiteral(const StringLiteral *Literal) {
std::string Result;
{
@ -64,14 +51,13 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<Expr>,
FasterStringFindCheck::FasterStringFindCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
StringLikeClasses(
ParseClasses(Options.get("StringLikeClasses", "std::basic_string"))) {
StringLikeClasses(utils::options::parseStringList(
Options.get("StringLikeClasses", "std::basic_string"))) {
}
void FasterStringFindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "StringLikeClasses",
llvm::join(StringLikeClasses.begin(), StringLikeClasses.end(),
StringLikeClassesDelimiter));
utils::options::serializeStringList(StringLikeClasses));
}
void FasterStringFindCheck::registerMatchers(MatchFinder *Finder) {

View File

@ -3,11 +3,12 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyUtils
DeclRefExprUtils.cpp
FixItHintUtils.cpp
HeaderGuard.cpp
HeaderFileExtensionsUtils.cpp
HeaderGuard.cpp
IncludeInserter.cpp
IncludeSorter.cpp
LexerUtils.cpp
OptionsUtils.cpp
TypeTraits.cpp
LINK_LIBS

View File

@ -0,0 +1,38 @@
//===--- DanglingHandleCheck.cpp - clang-tidy------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "OptionsUtils.h"
namespace clang {
namespace tidy {
namespace utils {
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.push_back(Name);
}
return Result;
}
std::string serializeStringList(ArrayRef<std::string> Strings) {
return llvm::join(Strings.begin(), Strings.end(), StringsDelimiter);
}
} // namespace options
} // namespace utils
} // namespace tidy
} // namespace clang

View File

@ -0,0 +1,32 @@
//===--- DanglingHandleCheck.h - clang-tidy----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace utils {
namespace options {
/// \brief Parse a semicolon separated list of strings.
std::vector<std::string> parseStringList(StringRef Option);
/// \brief Serialize a sequence of names that can be parsed by
/// 'parseStringList'.
std::string serializeStringList(ArrayRef<std::string> Strings);
} // namespace options
} // namespace utils
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H