mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 01:29:52 +00:00
0447ec2fb0
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
309 lines
12 KiB
C++
309 lines
12 KiB
C++
#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"
|
|
|
|
using namespace clang::tidy::llvm_check;
|
|
|
|
namespace clang {
|
|
namespace tidy {
|
|
namespace test {
|
|
|
|
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<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)
|
|
return "expected: '" + ExpectedWarning->str() + "', saw: '" +
|
|
Errors.back().Message.Message + "'";
|
|
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; }
|
|
};
|
|
|
|
static std::string
|
|
runHeaderGuardCheckWithEndif(StringRef Code, const Twine &Filename,
|
|
Optional<StringRef> ExpectedWarning) {
|
|
return runCheck<WithEndifComment>(Code, Filename, std::move(ExpectedWarning));
|
|
}
|
|
} // namespace
|
|
|
|
TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck(
|
|
"#ifndef FOO\n"
|
|
"#define FOO\n"
|
|
"#endif\n",
|
|
"include/llvm/ADT/foo.h",
|
|
StringRef("header guard does not follow preferred style")));
|
|
|
|
// Allow trailing underscores.
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H_\n"
|
|
"#define LLVM_ADT_FOO_H_\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("#ifndef LLVM_ADT_FOO_H_\n"
|
|
"#define LLVM_ADT_FOO_H_\n"
|
|
"#endif\n",
|
|
"include/llvm/ADT/foo.h", None));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_C_BAR_H\n"
|
|
"#define LLVM_CLANG_C_BAR_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("", "./include/clang-c/bar.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_LIB_CODEGEN_C_H\n"
|
|
"#define LLVM_CLANG_LIB_CODEGEN_C_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("", "tools/clang/lib/CodeGen/c.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n"
|
|
"#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("", "tools/clang/tools/extra/clang-tidy/x.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
EXPECT_EQ(
|
|
"int foo;\n"
|
|
"#ifndef LLVM_CLANG_BAR_H\n"
|
|
"#define LLVM_CLANG_BAR_H\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("int foo;\n"
|
|
"#ifndef LLVM_CLANG_BAR_H\n"
|
|
"#define LLVM_CLANG_BAR_H\n"
|
|
"#endif\n",
|
|
"include/clang/bar.h",
|
|
StringRef("code/includes outside of area guarded by "
|
|
"header guard; consider moving it")));
|
|
|
|
EXPECT_EQ(
|
|
"#ifndef LLVM_CLANG_BAR_H\n"
|
|
"#define LLVM_CLANG_BAR_H\n"
|
|
"#endif\n"
|
|
"int foo;\n",
|
|
runHeaderGuardCheck("#ifndef LLVM_CLANG_BAR_H\n"
|
|
"#define LLVM_CLANG_BAR_H\n"
|
|
"#endif\n"
|
|
"int foo;\n",
|
|
"include/clang/bar.h",
|
|
StringRef("code/includes outside of area guarded by "
|
|
"header guard; consider moving it")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_BAR_H\n"
|
|
"#define LLVM_CLANG_BAR_H\n"
|
|
"\n"
|
|
"int foo;\n"
|
|
"#ifndef FOOLOLO\n"
|
|
"#define FOOLOLO\n"
|
|
"#endif\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("int foo;\n"
|
|
"#ifndef FOOLOLO\n"
|
|
"#define FOOLOLO\n"
|
|
"#endif\n",
|
|
"include/clang/bar.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
// Fix incorrect #endif comments even if we shouldn't add new ones.
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif // LLVM_ADT_FOO_H\n",
|
|
runHeaderGuardCheck(
|
|
"#ifndef FOO\n"
|
|
"#define FOO\n"
|
|
"#endif // FOO\n",
|
|
"include/llvm/ADT/foo.h",
|
|
StringRef("header guard does not follow preferred style")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif // LLVM_ADT_FOO_H\n",
|
|
runHeaderGuardCheckWithEndif(
|
|
"#ifndef FOO\n"
|
|
"#define FOO\n"
|
|
"#endif\n",
|
|
"include/llvm/ADT/foo.h",
|
|
StringRef("header guard does not follow preferred style")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif // LLVM_ADT_FOO_H\n",
|
|
runHeaderGuardCheckWithEndif(
|
|
"#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif // LLVM_H\n",
|
|
"include/llvm/ADT/foo.h",
|
|
StringRef("#endif for a header guard should reference the "
|
|
"guard macro in a comment")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif /* LLVM_ADT_FOO_H */\n",
|
|
runHeaderGuardCheckWithEndif("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif /* LLVM_ADT_FOO_H */\n",
|
|
"include/llvm/ADT/foo.h", None));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H_\n"
|
|
"#define LLVM_ADT_FOO_H_\n"
|
|
"#endif // LLVM_ADT_FOO_H_\n",
|
|
runHeaderGuardCheckWithEndif("#ifndef LLVM_ADT_FOO_H_\n"
|
|
"#define LLVM_ADT_FOO_H_\n"
|
|
"#endif // LLVM_ADT_FOO_H_\n",
|
|
"include/llvm/ADT/foo.h", None));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif // LLVM_ADT_FOO_H\n",
|
|
runHeaderGuardCheckWithEndif(
|
|
"#ifndef LLVM_ADT_FOO_H_\n"
|
|
"#define LLVM_ADT_FOO_H_\n"
|
|
"#endif // LLVM\n",
|
|
"include/llvm/ADT/foo.h",
|
|
StringRef("header guard does not follow preferred style")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif \\ \n"
|
|
"// LLVM_ADT_FOO_H\n",
|
|
runHeaderGuardCheckWithEndif(
|
|
"#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif \\ \n"
|
|
"// LLVM_ADT_FOO_H\n",
|
|
"include/llvm/ADT/foo.h",
|
|
StringRef("backslash and newline separated by space")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif /* LLVM_ADT_FOO_H\\ \n"
|
|
" FOO */",
|
|
runHeaderGuardCheckWithEndif("#ifndef LLVM_ADT_FOO_H\n"
|
|
"#define LLVM_ADT_FOO_H\n"
|
|
"#endif /* LLVM_ADT_FOO_H\\ \n"
|
|
" FOO */",
|
|
"include/llvm/ADT/foo.h", None));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck(
|
|
"", "/llvm-project/clang-tools-extra/clangd/foo.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
// Substitution of characters should not result in a header guard starting
|
|
// with "_".
|
|
EXPECT_EQ("#ifndef BAR_H\n"
|
|
"#define BAR_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("", "include/--bar.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
#ifdef WIN32
|
|
// Check interaction with Windows-style path separators (\).
|
|
EXPECT_EQ(
|
|
"#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck("", "llvm-project\\clang-tools-extra\\clangd\\foo.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck(
|
|
"", "C:\\llvm-project\\clang-tools-extra\\clangd\\foo.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck(
|
|
"",
|
|
"\\\\SMBShare\\llvm-project\\clang-tools-extra\\clangd\\foo.h",
|
|
StringRef("header is missing header guard")));
|
|
|
|
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FOO_H\n"
|
|
"\n"
|
|
"\n"
|
|
"#endif\n",
|
|
runHeaderGuardCheck(
|
|
"", "\\\\?\\C:\\llvm-project\\clang-tools-extra\\clangd\\foo.h",
|
|
StringRef("header is missing header guard")));
|
|
#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
|