forked from OSchip/llvm-project
[clang-tdiy] Add header file extension configuration support.
Summary: * Add a `HeaderFileExtensions` check option in misc-definitions-in-headers, google-build-namespaces and google-global-names-in-headers. Reviewers: aaron.ballman, alexfh Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D16113 llvm-svn: 259879
This commit is contained in:
parent
5990cd5a0c
commit
c2d7577cc5
|
@ -344,13 +344,25 @@ OptionsView::OptionsView(StringRef CheckName,
|
||||||
const ClangTidyOptions::OptionMap &CheckOptions)
|
const ClangTidyOptions::OptionMap &CheckOptions)
|
||||||
: NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
|
: NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
|
||||||
|
|
||||||
std::string OptionsView::get(StringRef LocalName, std::string Default) const {
|
std::string OptionsView::get(StringRef LocalName, StringRef Default) const {
|
||||||
const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
|
const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
|
||||||
if (Iter != CheckOptions.end())
|
if (Iter != CheckOptions.end())
|
||||||
return Iter->second;
|
return Iter->second;
|
||||||
return Default;
|
return Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string OptionsView::getLocalOrGlobal(StringRef LocalName,
|
||||||
|
StringRef Default) const {
|
||||||
|
auto Iter = CheckOptions.find(NamePrefix + LocalName.str());
|
||||||
|
if (Iter != CheckOptions.end())
|
||||||
|
return Iter->second;
|
||||||
|
// Fallback to global setting, if present.
|
||||||
|
Iter = CheckOptions.find(LocalName.str());
|
||||||
|
if (Iter != CheckOptions.end())
|
||||||
|
return Iter->second;
|
||||||
|
return Default;
|
||||||
|
}
|
||||||
|
|
||||||
void OptionsView::store(ClangTidyOptions::OptionMap &Options,
|
void OptionsView::store(ClangTidyOptions::OptionMap &Options,
|
||||||
StringRef LocalName, StringRef Value) const {
|
StringRef LocalName, StringRef Value) const {
|
||||||
Options[NamePrefix + LocalName.str()] = Value;
|
Options[NamePrefix + LocalName.str()] = Value;
|
||||||
|
|
|
@ -47,7 +47,15 @@ public:
|
||||||
/// Reads the option with the check-local name \p LocalName from the
|
/// Reads the option with the check-local name \p LocalName from the
|
||||||
/// \c CheckOptions. If the corresponding key is not present, returns
|
/// \c CheckOptions. If the corresponding key is not present, returns
|
||||||
/// \p Default.
|
/// \p Default.
|
||||||
std::string get(StringRef LocalName, std::string Default) const;
|
std::string get(StringRef LocalName, StringRef Default) const;
|
||||||
|
|
||||||
|
/// \brief Read a named option from the \c Context.
|
||||||
|
///
|
||||||
|
/// Reads the option with the check-local name \p LocalName from local or
|
||||||
|
/// global \c CheckOptions. Gets local option first. If local is not
|
||||||
|
/// present, falls back to get global option. If global option is not present
|
||||||
|
/// either, returns Default.
|
||||||
|
std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
|
||||||
|
|
||||||
/// \brief Read a named option from the \c Context and parse it as an integral
|
/// \brief Read a named option from the \c Context and parse it as an integral
|
||||||
/// type \c T.
|
/// type \c T.
|
||||||
|
|
|
@ -20,6 +20,24 @@ namespace tidy {
|
||||||
namespace google {
|
namespace google {
|
||||||
namespace readability {
|
namespace readability {
|
||||||
|
|
||||||
|
GlobalNamesInHeadersCheck::GlobalNamesInHeadersCheck(StringRef Name,
|
||||||
|
ClangTidyContext *Context)
|
||||||
|
: ClangTidyCheck(Name, Context),
|
||||||
|
RawStringHeaderFileExtensions(
|
||||||
|
Options.getLocalOrGlobal("HeaderFileExtensions", "h")) {
|
||||||
|
if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
|
||||||
|
HeaderFileExtensions,
|
||||||
|
',')) {
|
||||||
|
llvm::errs() << "Invalid header file extension: "
|
||||||
|
<< RawStringHeaderFileExtensions << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalNamesInHeadersCheck::storeOptions(
|
||||||
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
|
Options.store(Opts, "HeaderFileExtensions", RawStringHeaderFileExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GlobalNamesInHeadersCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
GlobalNamesInHeadersCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
|
@ -38,10 +56,8 @@ void GlobalNamesInHeadersCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
if (Result.SourceManager->isInMainFile(
|
if (Result.SourceManager->isInMainFile(
|
||||||
Result.SourceManager->getExpansionLoc(D->getLocStart()))) {
|
Result.SourceManager->getExpansionLoc(D->getLocStart()))) {
|
||||||
// unless that file is a header.
|
// unless that file is a header.
|
||||||
StringRef Filename = Result.SourceManager->getFilename(
|
if (!utils::isSpellingLocInHeaderFile(
|
||||||
Result.SourceManager->getSpellingLoc(D->getLocStart()));
|
D->getLocStart(), *Result.SourceManager, HeaderFileExtensions))
|
||||||
|
|
||||||
if (!Filename.endswith(".h"))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,20 +11,32 @@
|
||||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBALNAMESINHEADERSCHECK_H
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBALNAMESINHEADERSCHECK_H
|
||||||
|
|
||||||
#include "../ClangTidy.h"
|
#include "../ClangTidy.h"
|
||||||
|
#include "../utils/HeaderFileExtensionsUtils.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
namespace tidy {
|
namespace tidy {
|
||||||
namespace google {
|
namespace google {
|
||||||
namespace readability {
|
namespace readability {
|
||||||
|
|
||||||
// Flag global namespace pollution in header files.
|
/// Flag global namespace pollution in header files.
|
||||||
// Right now it only triggers on using declarations and directives.
|
/// Right now it only triggers on using declarations and directives.
|
||||||
|
///
|
||||||
|
/// The check supports these options:
|
||||||
|
/// - `HeaderFileExtensions`: a comma-separated list of filename extensions
|
||||||
|
/// of header files (The filename extensions should not contain "." prefix).
|
||||||
|
/// "h" by default.
|
||||||
|
/// For extension-less header files, using an empty string or leaving an
|
||||||
|
/// empty string between "," if there are other filename extensions.
|
||||||
class GlobalNamesInHeadersCheck : public ClangTidyCheck {
|
class GlobalNamesInHeadersCheck : public ClangTidyCheck {
|
||||||
public:
|
public:
|
||||||
GlobalNamesInHeadersCheck(StringRef Name, ClangTidyContext *Context)
|
GlobalNamesInHeadersCheck(StringRef Name, ClangTidyContext *Context);
|
||||||
: ClangTidyCheck(Name, Context) {}
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
||||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string RawStringHeaderFileExtensions;
|
||||||
|
utils::HeaderFileExtensionsSet HeaderFileExtensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace readability
|
} // namespace readability
|
||||||
|
|
|
@ -19,6 +19,24 @@ namespace tidy {
|
||||||
namespace google {
|
namespace google {
|
||||||
namespace build {
|
namespace build {
|
||||||
|
|
||||||
|
UnnamedNamespaceInHeaderCheck::UnnamedNamespaceInHeaderCheck(
|
||||||
|
StringRef Name, ClangTidyContext *Context)
|
||||||
|
: ClangTidyCheck(Name, Context),
|
||||||
|
RawStringHeaderFileExtensions(
|
||||||
|
Options.getLocalOrGlobal("HeaderFileExtensions", "h,hh,hpp,hxx")) {
|
||||||
|
if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
|
||||||
|
HeaderFileExtensions,
|
||||||
|
',')) {
|
||||||
|
llvm::errs() << "Invalid header file extension: "
|
||||||
|
<< RawStringHeaderFileExtensions << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnnamedNamespaceInHeaderCheck::storeOptions(
|
||||||
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
|
Options.store(Opts, "HeaderFileExtensions", RawStringHeaderFileExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
void UnnamedNamespaceInHeaderCheck::registerMatchers(
|
void UnnamedNamespaceInHeaderCheck::registerMatchers(
|
||||||
ast_matchers::MatchFinder *Finder) {
|
ast_matchers::MatchFinder *Finder) {
|
||||||
// Only register the matchers for C++; the functionality currently does not
|
// Only register the matchers for C++; the functionality currently does not
|
||||||
|
@ -30,17 +48,13 @@ void UnnamedNamespaceInHeaderCheck::registerMatchers(
|
||||||
|
|
||||||
void
|
void
|
||||||
UnnamedNamespaceInHeaderCheck::check(const MatchFinder::MatchResult &Result) {
|
UnnamedNamespaceInHeaderCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
SourceManager *SM = Result.SourceManager;
|
|
||||||
const auto *N = Result.Nodes.getNodeAs<NamespaceDecl>("anonymousNamespace");
|
const auto *N = Result.Nodes.getNodeAs<NamespaceDecl>("anonymousNamespace");
|
||||||
SourceLocation Loc = N->getLocStart();
|
SourceLocation Loc = N->getLocStart();
|
||||||
if (!Loc.isValid())
|
if (!Loc.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Look if we're inside a header, check for common suffixes only.
|
if (utils::isPresumedLocInHeaderFile(Loc, *Result.SourceManager,
|
||||||
// TODO: Allow configuring the set of file extensions.
|
HeaderFileExtensions))
|
||||||
StringRef FileName = SM->getPresumedLoc(Loc).getFilename();
|
|
||||||
if (FileName.endswith(".h") || FileName.endswith(".hh") ||
|
|
||||||
FileName.endswith(".hpp") || FileName.endswith(".hxx"))
|
|
||||||
diag(Loc, "do not use unnamed namespaces in header files");
|
diag(Loc, "do not use unnamed namespaces in header files");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UNNAMEDNAMESPACEINHEADERCHECK_H
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UNNAMEDNAMESPACEINHEADERCHECK_H
|
||||||
|
|
||||||
#include "../ClangTidy.h"
|
#include "../ClangTidy.h"
|
||||||
|
#include "../utils/HeaderFileExtensionsUtils.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
namespace tidy {
|
namespace tidy {
|
||||||
|
@ -19,15 +20,26 @@ namespace build {
|
||||||
|
|
||||||
/// Finds anonymous namespaces in headers.
|
/// Finds anonymous namespaces in headers.
|
||||||
///
|
///
|
||||||
|
/// The check supports these options:
|
||||||
|
/// - `HeaderFileExtensions`: a comma-separated list of filename extensions of
|
||||||
|
/// header files (The filename extensions should not contain "." prefix).
|
||||||
|
/// "h,hh,hpp,hxx" by default.
|
||||||
|
/// For extension-less header files, using an empty string or leaving an
|
||||||
|
/// empty string between "," if there are other filename extensions.
|
||||||
|
///
|
||||||
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Namespaces#Namespaces
|
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Namespaces#Namespaces
|
||||||
///
|
///
|
||||||
/// Corresponding cpplint.py check name: 'build/namespaces'.
|
/// Corresponding cpplint.py check name: 'build/namespaces'.
|
||||||
class UnnamedNamespaceInHeaderCheck : public ClangTidyCheck {
|
class UnnamedNamespaceInHeaderCheck : public ClangTidyCheck {
|
||||||
public:
|
public:
|
||||||
UnnamedNamespaceInHeaderCheck(StringRef Name, ClangTidyContext *Context)
|
UnnamedNamespaceInHeaderCheck(StringRef Name, ClangTidyContext *Context);
|
||||||
: ClangTidyCheck(Name, Context) {}
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
||||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string RawStringHeaderFileExtensions;
|
||||||
|
utils::HeaderFileExtensionsSet HeaderFileExtensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace build
|
} // namespace build
|
||||||
|
|
|
@ -19,38 +19,50 @@ namespace misc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
AST_MATCHER(NamedDecl, isHeaderFileExtension) {
|
AST_MATCHER_P(NamedDecl, usesHeaderFileExtension,
|
||||||
SourceManager& SM = Finder->getASTContext().getSourceManager();
|
utils::HeaderFileExtensionsSet, HeaderFileExtensions) {
|
||||||
SourceLocation ExpansionLoc = SM.getExpansionLoc(Node.getLocStart());
|
return utils::isExpansionLocInHeaderFile(
|
||||||
StringRef Filename = SM.getFilename(ExpansionLoc);
|
Node.getLocStart(), Finder->getASTContext().getSourceManager(),
|
||||||
return Filename.endswith(".h") || Filename.endswith(".hh") ||
|
HeaderFileExtensions);
|
||||||
Filename.endswith(".hpp") || Filename.endswith(".hxx") ||
|
|
||||||
llvm::sys::path::extension(Filename).empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
DefinitionsInHeadersCheck::DefinitionsInHeadersCheck(
|
DefinitionsInHeadersCheck::DefinitionsInHeadersCheck(StringRef Name,
|
||||||
StringRef Name, ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
UseHeaderFileExtension(Options.get("UseHeaderFileExtension", true)) {}
|
UseHeaderFileExtension(Options.get("UseHeaderFileExtension", true)),
|
||||||
|
RawStringHeaderFileExtensions(
|
||||||
|
Options.getLocalOrGlobal("HeaderFileExtensions", ",h,hh,hpp,hxx")) {
|
||||||
|
if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
|
||||||
|
HeaderFileExtensions,
|
||||||
|
',')) {
|
||||||
|
// FIXME: Find a more suitable way to handle invalid configuration
|
||||||
|
// options.
|
||||||
|
llvm::errs() << "Invalid header file extension: "
|
||||||
|
<< RawStringHeaderFileExtensions << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DefinitionsInHeadersCheck::storeOptions(
|
void DefinitionsInHeadersCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "UseHeaderFileExtension", UseHeaderFileExtension);
|
Options.store(Opts, "UseHeaderFileExtension", UseHeaderFileExtension);
|
||||||
|
Options.store(Opts, "HeaderFileExtensions", RawStringHeaderFileExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) {
|
void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
if (UseHeaderFileExtension) {
|
if (UseHeaderFileExtension) {
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
namedDecl(anyOf(functionDecl(isDefinition()), varDecl(isDefinition())),
|
namedDecl(anyOf(functionDecl(isDefinition()), varDecl(isDefinition())),
|
||||||
isHeaderFileExtension()).bind("name-decl"),
|
usesHeaderFileExtension(HeaderFileExtensions))
|
||||||
|
.bind("name-decl"),
|
||||||
this);
|
this);
|
||||||
} else {
|
} else {
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
namedDecl(anyOf(functionDecl(isDefinition()), varDecl(isDefinition())),
|
namedDecl(anyOf(functionDecl(isDefinition()), varDecl(isDefinition())),
|
||||||
anyOf(isHeaderFileExtension(),
|
anyOf(usesHeaderFileExtension(HeaderFileExtensions),
|
||||||
unless(isExpansionInMainFile()))).bind("name-decl"),
|
unless(isExpansionInMainFile())))
|
||||||
|
.bind("name-decl"),
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,20 +11,26 @@
|
||||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DEFINITIONS_IN_HEADERS_H
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DEFINITIONS_IN_HEADERS_H
|
||||||
|
|
||||||
#include "../ClangTidy.h"
|
#include "../ClangTidy.h"
|
||||||
|
#include "../utils/HeaderFileExtensionsUtils.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
namespace tidy {
|
namespace tidy {
|
||||||
namespace misc {
|
namespace misc {
|
||||||
|
|
||||||
// Finds non-extern non-inline function and variable definitions in header
|
/// Finds non-extern non-inline function and variable definitions in header
|
||||||
// files, which can lead to potential ODR violations.
|
/// files, which can lead to potential ODR violations.
|
||||||
//
|
///
|
||||||
// There is one option:
|
/// The check supports these options:
|
||||||
// - `UseHeaderFileExtension`: Whether to use file extension (h, hh, hpp, hxx)
|
/// - `UseHeaderFileExtension`: Whether to use file extension to distinguish
|
||||||
// to distinguish header files. True by default.
|
/// header files. True by default.
|
||||||
//
|
/// - `HeaderFileExtensions`: a comma-separated list of filename extensions of
|
||||||
// For the user-facing documentation see:
|
/// header files (The filename extension should not contain "." prefix).
|
||||||
// http://clang.llvm.org/extra/clang-tidy/checks/misc-definitions-in-headers.html
|
/// ",h,hh,hpp,hxx" by default.
|
||||||
|
/// For extension-less header files, using an empty string or leaving an
|
||||||
|
/// empty string between "," if there are other filename extensions.
|
||||||
|
///
|
||||||
|
/// For the user-facing documentation see:
|
||||||
|
/// http://clang.llvm.org/extra/clang-tidy/checks/misc-definitions-in-headers.html
|
||||||
class DefinitionsInHeadersCheck : public ClangTidyCheck {
|
class DefinitionsInHeadersCheck : public ClangTidyCheck {
|
||||||
public:
|
public:
|
||||||
DefinitionsInHeadersCheck(StringRef Name, ClangTidyContext *Context);
|
DefinitionsInHeadersCheck(StringRef Name, ClangTidyContext *Context);
|
||||||
|
@ -34,6 +40,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const bool UseHeaderFileExtension;
|
const bool UseHeaderFileExtension;
|
||||||
|
const std::string RawStringHeaderFileExtensions;
|
||||||
|
utils::HeaderFileExtensionsSet HeaderFileExtensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace misc
|
} // namespace misc
|
||||||
|
|
|
@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
|
||||||
|
|
||||||
add_clang_library(clangTidyUtils
|
add_clang_library(clangTidyUtils
|
||||||
HeaderGuard.cpp
|
HeaderGuard.cpp
|
||||||
|
HeaderFileExtensionsUtils.cpp
|
||||||
IncludeInserter.cpp
|
IncludeInserter.cpp
|
||||||
IncludeSorter.cpp
|
IncludeSorter.cpp
|
||||||
LexerUtils.cpp
|
LexerUtils.cpp
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
//===--- HeaderFileExtensionsUtils.cpp - clang-tidy--------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "HeaderFileExtensionsUtils.h"
|
||||||
|
#include "clang/Basic/CharInfo.h"
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
bool isExpansionLocInHeaderFile(
|
||||||
|
SourceLocation Loc, const SourceManager &SM,
|
||||||
|
const HeaderFileExtensionsSet &HeaderFileExtensions) {
|
||||||
|
SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
|
||||||
|
StringRef FileExtension =
|
||||||
|
llvm::sys::path::extension(SM.getFilename(ExpansionLoc));
|
||||||
|
return HeaderFileExtensions.count(FileExtension.substr(1)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPresumedLocInHeaderFile(
|
||||||
|
SourceLocation Loc, SourceManager &SM,
|
||||||
|
const HeaderFileExtensionsSet &HeaderFileExtensions) {
|
||||||
|
PresumedLoc PresumedLocation = SM.getPresumedLoc(Loc);
|
||||||
|
StringRef FileExtension =
|
||||||
|
llvm::sys::path::extension(PresumedLocation.getFilename());
|
||||||
|
return HeaderFileExtensions.count(FileExtension.substr(1)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSpellingLocInHeaderFile(
|
||||||
|
SourceLocation Loc, SourceManager &SM,
|
||||||
|
const HeaderFileExtensionsSet &HeaderFileExtensions) {
|
||||||
|
SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
|
||||||
|
StringRef FileExtension =
|
||||||
|
llvm::sys::path::extension(SM.getFilename(SpellingLoc));
|
||||||
|
|
||||||
|
return HeaderFileExtensions.count(FileExtension.substr(1)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseHeaderFileExtensions(StringRef AllHeaderFileExtensions,
|
||||||
|
HeaderFileExtensionsSet &HeaderFileExtensions,
|
||||||
|
char delimiter) {
|
||||||
|
SmallVector<StringRef, 5> Suffixes;
|
||||||
|
AllHeaderFileExtensions.split(Suffixes, delimiter);
|
||||||
|
HeaderFileExtensions.clear();
|
||||||
|
for (StringRef Suffix : Suffixes) {
|
||||||
|
StringRef Extension = Suffix.trim();
|
||||||
|
for (StringRef::const_iterator it = Extension.begin();
|
||||||
|
it != Extension.end(); ++it) {
|
||||||
|
if (!isAlphanumeric(*it))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HeaderFileExtensions.insert(Extension);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
|
@ -0,0 +1,51 @@
|
||||||
|
//===--- HeaderFileExtensionsUtils.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_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
|
||||||
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "clang/Basic/SourceLocation.h"
|
||||||
|
#include "clang/Basic/SourceManager.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/ADT/SmallSet.h"
|
||||||
|
#include "llvm/Support/Path.h"
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
typedef llvm::SmallSet<llvm::StringRef, 5> HeaderFileExtensionsSet;
|
||||||
|
|
||||||
|
/// \brief Checks whether expansion location of Loc is in header file.
|
||||||
|
bool isExpansionLocInHeaderFile(
|
||||||
|
SourceLocation Loc, const SourceManager &SM,
|
||||||
|
const HeaderFileExtensionsSet &HeaderFileExtensions);
|
||||||
|
|
||||||
|
/// \brief Checks whether presumed location of Loc is in header file.
|
||||||
|
bool isPresumedLocInHeaderFile(
|
||||||
|
SourceLocation Loc, SourceManager &SM,
|
||||||
|
const HeaderFileExtensionsSet &HeaderFileExtensions);
|
||||||
|
|
||||||
|
/// \brief Checks whether spelling location of Loc is in header file.
|
||||||
|
bool isSpellingLocInHeaderFile(
|
||||||
|
SourceLocation Loc, SourceManager &SM,
|
||||||
|
const HeaderFileExtensionsSet &HeaderFileExtensions);
|
||||||
|
|
||||||
|
/// \brief Parses header file extensions from a semicolon-separated list.
|
||||||
|
bool parseHeaderFileExtensions(StringRef AllHeaderFileExtensions,
|
||||||
|
HeaderFileExtensionsSet &HeaderFileExtensions,
|
||||||
|
char delimiter);
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
||||||
|
|
||||||
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
|
Loading…
Reference in New Issue