Skip to content

Commit

Permalink
[clang-tidy] Fix LLVM include order check policy
Browse files Browse the repository at this point in the history
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 #53525.

Differential Revision: https://reviews.llvm.org/D118913

(cherry picked from commit 0447ec2)
  • Loading branch information
kadircet authored and tstellar committed Feb 7, 2022
1 parent a03ffad commit 52557b9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 17 deletions.
10 changes: 7 additions & 3 deletions clang-tools-extra/clang-tidy/llvm/IncludeOrderCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand Down
61 changes: 47 additions & 14 deletions clang-tools-extra/unittests/clang-tidy/LLVMModuleTest.cpp
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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)
Expand All @@ -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"
Expand Down Expand Up @@ -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

0 comments on commit 52557b9

Please sign in to comment.