1 #include "ClangTidyTest.h" 2 #include "llvm/HeaderGuardCheck.h" 3 #include "llvm/IncludeOrderCheck.h" 4 #include "gtest/gtest.h" 5 6 using namespace clang::tidy::llvm_check; 7 8 namespace clang { 9 namespace tidy { 10 namespace test { 11 12 // FIXME: It seems this might be incompatible to dos path. Investigating. 13 #if !defined(_WIN32) 14 static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename, 15 Optional<StringRef> ExpectedWarning) { 16 std::vector<ClangTidyError> Errors; 17 std::string Result = test::runCheckOnCode<LLVMHeaderGuardCheck>( 18 Code, &Errors, Filename, std::string("-xc++-header")); 19 if (Errors.size() != (size_t)ExpectedWarning.hasValue()) 20 return "invalid error count"; 21 if (ExpectedWarning && *ExpectedWarning != Errors.back().Message.Message) 22 return "expected: '" + ExpectedWarning->str() + "', saw: '" + 23 Errors.back().Message.Message + "'"; 24 return Result; 25 } 26 27 namespace { 28 struct WithEndifComment : public LLVMHeaderGuardCheck { 29 WithEndifComment(StringRef Name, ClangTidyContext *Context) 30 : LLVMHeaderGuardCheck(Name, Context) {} 31 bool shouldSuggestEndifComment(StringRef Filename) override { return true; } 32 }; 33 } // namespace 34 35 static std::string 36 runHeaderGuardCheckWithEndif(StringRef Code, const Twine &Filename, 37 Optional<StringRef> ExpectedWarning) { 38 std::vector<ClangTidyError> Errors; 39 std::string Result = test::runCheckOnCode<WithEndifComment>( 40 Code, &Errors, Filename, std::string("-xc++-header")); 41 if (Errors.size() != (size_t)ExpectedWarning.hasValue()) 42 return "invalid error count"; 43 if (ExpectedWarning && *ExpectedWarning != Errors.back().Message.Message) 44 return "expected: '" + ExpectedWarning->str() + "', saw: '" + 45 Errors.back().Message.Message + "'"; 46 return Result; 47 } 48 49 TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) { 50 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 51 "#define LLVM_ADT_FOO_H\n" 52 "#endif\n", 53 runHeaderGuardCheck( 54 "#ifndef FOO\n" 55 "#define FOO\n" 56 "#endif\n", 57 "include/llvm/ADT/foo.h", 58 StringRef("header guard does not follow preferred style"))); 59 60 // Allow trailing underscores. 61 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H_\n" 62 "#define LLVM_ADT_FOO_H_\n" 63 "#endif\n", 64 runHeaderGuardCheck("#ifndef LLVM_ADT_FOO_H_\n" 65 "#define LLVM_ADT_FOO_H_\n" 66 "#endif\n", 67 "include/llvm/ADT/foo.h", None)); 68 69 EXPECT_EQ("#ifndef LLVM_CLANG_C_BAR_H\n" 70 "#define LLVM_CLANG_C_BAR_H\n" 71 "\n" 72 "\n" 73 "#endif\n", 74 runHeaderGuardCheck("", "./include/clang-c/bar.h", 75 StringRef("header is missing header guard"))); 76 77 EXPECT_EQ("#ifndef LLVM_CLANG_LIB_CODEGEN_C_H\n" 78 "#define LLVM_CLANG_LIB_CODEGEN_C_H\n" 79 "\n" 80 "\n" 81 "#endif\n", 82 runHeaderGuardCheck("", "tools/clang/lib/CodeGen/c.h", 83 StringRef("header is missing header guard"))); 84 85 EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n" 86 "#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n" 87 "\n" 88 "\n" 89 "#endif\n", 90 runHeaderGuardCheck("", "tools/clang/tools/extra/clang-tidy/x.h", 91 StringRef("header is missing header guard"))); 92 93 EXPECT_EQ( 94 "int foo;\n" 95 "#ifndef LLVM_CLANG_BAR_H\n" 96 "#define LLVM_CLANG_BAR_H\n" 97 "#endif\n", 98 runHeaderGuardCheck("int foo;\n" 99 "#ifndef LLVM_CLANG_BAR_H\n" 100 "#define LLVM_CLANG_BAR_H\n" 101 "#endif\n", 102 "include/clang/bar.h", 103 StringRef("code/includes outside of area guarded by " 104 "header guard; consider moving it"))); 105 106 EXPECT_EQ( 107 "#ifndef LLVM_CLANG_BAR_H\n" 108 "#define LLVM_CLANG_BAR_H\n" 109 "#endif\n" 110 "int foo;\n", 111 runHeaderGuardCheck("#ifndef LLVM_CLANG_BAR_H\n" 112 "#define LLVM_CLANG_BAR_H\n" 113 "#endif\n" 114 "int foo;\n", 115 "include/clang/bar.h", 116 StringRef("code/includes outside of area guarded by " 117 "header guard; consider moving it"))); 118 119 EXPECT_EQ("#ifndef LLVM_CLANG_BAR_H\n" 120 "#define LLVM_CLANG_BAR_H\n" 121 "\n" 122 "int foo;\n" 123 "#ifndef FOOLOLO\n" 124 "#define FOOLOLO\n" 125 "#endif\n" 126 "\n" 127 "#endif\n", 128 runHeaderGuardCheck("int foo;\n" 129 "#ifndef FOOLOLO\n" 130 "#define FOOLOLO\n" 131 "#endif\n", 132 "include/clang/bar.h", 133 StringRef("header is missing header guard"))); 134 135 // Fix incorrect #endif comments even if we shouldn't add new ones. 136 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 137 "#define LLVM_ADT_FOO_H\n" 138 "#endif // LLVM_ADT_FOO_H\n", 139 runHeaderGuardCheck( 140 "#ifndef FOO\n" 141 "#define FOO\n" 142 "#endif // FOO\n", 143 "include/llvm/ADT/foo.h", 144 StringRef("header guard does not follow preferred style"))); 145 146 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 147 "#define LLVM_ADT_FOO_H\n" 148 "#endif // LLVM_ADT_FOO_H\n", 149 runHeaderGuardCheckWithEndif( 150 "#ifndef FOO\n" 151 "#define FOO\n" 152 "#endif\n", 153 "include/llvm/ADT/foo.h", 154 StringRef("header guard does not follow preferred style"))); 155 156 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 157 "#define LLVM_ADT_FOO_H\n" 158 "#endif // LLVM_ADT_FOO_H\n", 159 runHeaderGuardCheckWithEndif( 160 "#ifndef LLVM_ADT_FOO_H\n" 161 "#define LLVM_ADT_FOO_H\n" 162 "#endif // LLVM_H\n", 163 "include/llvm/ADT/foo.h", 164 StringRef("#endif for a header guard should reference the " 165 "guard macro in a comment"))); 166 167 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 168 "#define LLVM_ADT_FOO_H\n" 169 "#endif /* LLVM_ADT_FOO_H */\n", 170 runHeaderGuardCheckWithEndif("#ifndef LLVM_ADT_FOO_H\n" 171 "#define LLVM_ADT_FOO_H\n" 172 "#endif /* LLVM_ADT_FOO_H */\n", 173 "include/llvm/ADT/foo.h", None)); 174 175 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H_\n" 176 "#define LLVM_ADT_FOO_H_\n" 177 "#endif // LLVM_ADT_FOO_H_\n", 178 runHeaderGuardCheckWithEndif("#ifndef LLVM_ADT_FOO_H_\n" 179 "#define LLVM_ADT_FOO_H_\n" 180 "#endif // LLVM_ADT_FOO_H_\n", 181 "include/llvm/ADT/foo.h", None)); 182 183 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 184 "#define LLVM_ADT_FOO_H\n" 185 "#endif // LLVM_ADT_FOO_H\n", 186 runHeaderGuardCheckWithEndif( 187 "#ifndef LLVM_ADT_FOO_H_\n" 188 "#define LLVM_ADT_FOO_H_\n" 189 "#endif // LLVM\n", 190 "include/llvm/ADT/foo.h", 191 StringRef("header guard does not follow preferred style"))); 192 193 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 194 "#define LLVM_ADT_FOO_H\n" 195 "#endif \\ \n" 196 "// LLVM_ADT_FOO_H\n", 197 runHeaderGuardCheckWithEndif( 198 "#ifndef LLVM_ADT_FOO_H\n" 199 "#define LLVM_ADT_FOO_H\n" 200 "#endif \\ \n" 201 "// LLVM_ADT_FOO_H\n", 202 "include/llvm/ADT/foo.h", 203 StringRef("backslash and newline separated by space"))); 204 205 EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n" 206 "#define LLVM_ADT_FOO_H\n" 207 "#endif /* LLVM_ADT_FOO_H\\ \n" 208 " FOO */", 209 runHeaderGuardCheckWithEndif("#ifndef LLVM_ADT_FOO_H\n" 210 "#define LLVM_ADT_FOO_H\n" 211 "#endif /* LLVM_ADT_FOO_H\\ \n" 212 " FOO */", 213 "include/llvm/ADT/foo.h", None)); 214 } 215 #endif 216 217 } // namespace test 218 } // namespace tidy 219 } // namespace clang 220