[clang-tidy] Fix LLVM include order check policy

Clang-format LLVM style has a custom include category for gtest/ and
gmock/ headers between regular includes and angled includes. Do the same here.

Fixes https://github.com/llvm/llvm-project/issues/53525.

Differential Revision: https://reviews.llvm.org/D118913
This commit is contained in:
Kadir Cetinkaya 2022-02-03 17:26:41 +01:00
parent 2349fb0312
commit 0447ec2fb0
No known key found for this signature in database
GPG key ID: E39E36B8D2057ED6
3 changed files with 56 additions and 17 deletions

View file

@ -66,11 +66,15 @@ static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
Filename.startswith("clang/") || Filename.startswith("clang-c/"))
return 2;
// System headers are sorted to the end.
if (IsAngled || Filename.startswith("gtest/") ||
Filename.startswith("gmock/"))
// Put these between system and llvm headers to be consistent with LLVM
// clang-format style.
if (Filename.startswith("gtest/") || Filename.startswith("gmock/"))
return 3;
// System headers are sorted to the end.
if (IsAngled)
return 4;
// Other headers are inserted between the main module header and LLVM headers.
return 1;
}

View file

@ -6,6 +6,7 @@
#include "gmock/foo.h"
#include "i.h"
#include <s.h>
#include <a.h>
#include "llvm/a.h"
#include "clang/b.h"
#include "clang-c/c.h" // hi
@ -19,6 +20,7 @@
// CHECK-FIXES-NEXT: #include "llvm/a.h"
// CHECK-FIXES-NEXT: #include "gmock/foo.h"
// CHECK-FIXES-NEXT: #include "gtest/foo.h"
// CHECK-FIXES-NEXT: #include <a.h>
// CHECK-FIXES-NEXT: #include <s.h>
#include "b.h"

View file

@ -1,4 +1,7 @@
#include "ClangTidyOptions.h"
#include "ClangTidyTest.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/HeaderGuardCheck.h"
#include "llvm/IncludeOrderCheck.h"
#include "gtest/gtest.h"
@ -9,11 +12,15 @@ namespace clang {
namespace tidy {
namespace test {
static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename,
Optional<StringRef> ExpectedWarning) {
template <typename T>
static std::string runCheck(StringRef Code, const Twine &Filename,
Optional<StringRef> ExpectedWarning,
std::map<StringRef, StringRef> PathsToContent =
std::map<StringRef, StringRef>()) {
std::vector<ClangTidyError> Errors;
std::string Result = test::runCheckOnCode<LLVMHeaderGuardCheck>(
Code, &Errors, Filename, std::string("-xc++-header"));
std::string Result = test::runCheckOnCode<T>(
Code, &Errors, Filename, std::string("-xc++-header"), ClangTidyOptions{},
std::move(PathsToContent));
if (Errors.size() != (size_t)ExpectedWarning.hasValue())
return "invalid error count";
if (ExpectedWarning && *ExpectedWarning != Errors.back().Message.Message)
@ -22,27 +29,36 @@ static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename,
return Result;
}
static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename,
Optional<StringRef> ExpectedWarning) {
return runCheck<LLVMHeaderGuardCheck>(Code, Filename,
std::move(ExpectedWarning));
}
static std::string
runIncludeOrderCheck(StringRef Code, const Twine &Filename,
Optional<StringRef> ExpectedWarning,
llvm::ArrayRef<llvm::StringLiteral> Includes) {
std::map<StringRef, StringRef> PathsToContent;
for (auto Include : Includes)
PathsToContent.emplace(Include, "");
return runCheck<IncludeOrderCheck>(Code, Filename, std::move(ExpectedWarning),
PathsToContent);
}
namespace {
struct WithEndifComment : public LLVMHeaderGuardCheck {
WithEndifComment(StringRef Name, ClangTidyContext *Context)
: LLVMHeaderGuardCheck(Name, Context) {}
bool shouldSuggestEndifComment(StringRef Filename) override { return true; }
};
} // namespace
static std::string
runHeaderGuardCheckWithEndif(StringRef Code, const Twine &Filename,
Optional<StringRef> ExpectedWarning) {
std::vector<ClangTidyError> Errors;
std::string Result = test::runCheckOnCode<WithEndifComment>(
Code, &Errors, Filename, std::string("-xc++-header"));
if (Errors.size() != (size_t)ExpectedWarning.hasValue())
return "invalid error count";
if (ExpectedWarning && *ExpectedWarning != Errors.back().Message.Message)
return "expected: '" + ExpectedWarning->str() + "', saw: '" +
Errors.back().Message.Message + "'";
return Result;
return runCheck<WithEndifComment>(Code, Filename, std::move(ExpectedWarning));
}
} // namespace
TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
@ -270,6 +286,23 @@ TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
#endif
}
TEST(IncludeOrderCheck, GTestHeaders) {
EXPECT_EQ(
R"cpp(
#include "foo.h"
#include "llvm/foo.h"
#include "gtest/foo.h"
#include <algorithm>)cpp",
runIncludeOrderCheck(
R"cpp(
#include "foo.h"
#include "llvm/foo.h"
#include <algorithm>
#include "gtest/foo.h")cpp",
"foo.cc", StringRef("#includes are not sorted properly"),
{"foo.h", "algorithm", "gtest/foo.h", "llvm/foo.h"}));
}
} // namespace test
} // namespace tidy
} // namespace clang