[clang-move] Add header guard for the new header.

Summary:
The header guard generated by clang-move isn't always a perfect
style, just avoid getting the header included multiple times during
compiling period.

Also, we can use llvm-Header-guard clang-tidy check to correct the guard
automatically.

Reviewers: ioeric

Subscribers: cfe-commits

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

llvm-svn: 284233
This commit is contained in:
Haojian Wu 2016-10-14 13:01:36 +00:00
parent 81c0be3f56
commit 220c755dfc
4 changed files with 34 additions and 4 deletions

View File

@ -249,8 +249,22 @@ std::vector<std::string> GetNamespaces(const clang::Decl *D) {
clang::tooling::Replacements
createInsertedReplacements(const std::vector<std::string> &Includes,
const std::vector<ClangMoveTool::MovedDecl> &Decls,
llvm::StringRef FileName) {
llvm::StringRef FileName,
bool IsHeader = false) {
clang::tooling::Replacements InsertedReplacements;
std::string GuardName(FileName);
if (IsHeader) {
std::replace(GuardName.begin(), GuardName.end(), '/', '_');
std::replace(GuardName.begin(), GuardName.end(), '.', '_');
std::replace(GuardName.begin(), GuardName.end(), '-', '_');
GuardName = StringRef(GuardName).upper();
std::string HeaderGuard = "#ifndef " + GuardName + "\n";
HeaderGuard += "#define " + GuardName + "\n";
clang::tooling::Replacement HeaderGuardInclude(FileName, 0, 0,
HeaderGuard);
addOrMergeReplacement(HeaderGuardInclude, &InsertedReplacements);
}
// Add #Includes.
std::string AllIncludesString;
@ -308,6 +322,12 @@ createInsertedReplacements(const std::vector<std::string> &Includes,
FileName, 0, 0, "} // namespace " + NS + "\n");
addOrMergeReplacement(InsertedReplacement, &InsertedReplacements);
}
if (IsHeader) {
clang::tooling::Replacement HeaderGuardEnd(FileName, 0, 0,
"#endif // " + GuardName + "\n");
addOrMergeReplacement(HeaderGuardEnd, &InsertedReplacements);
}
return InsertedReplacements;
}
@ -500,7 +520,7 @@ void ClangMoveTool::moveClassDefinitionToNewFiles() {
if (!Spec.NewHeader.empty())
FileToReplacements[Spec.NewHeader] = createInsertedReplacements(
HeaderIncludes, NewHeaderDecls, Spec.NewHeader);
HeaderIncludes, NewHeaderDecls, Spec.NewHeader, /*IsHeader=*/true);
if (!Spec.NewCC.empty())
FileToReplacements[Spec.NewCC] =
createInsertedReplacements(CCIncludes, NewCCDecls, Spec.NewCC);

View File

@ -21,6 +21,9 @@
// RUN: FileCheck -input-file=%T/clang-move/src/test.cpp -check-prefix=CHECK-OLD-TEST-CPP %s
// RUN: FileCheck -input-file=%T/clang-move/include/test.h %s -implicit-check-not='{{namespace.*}}'
//
//
// CHECK-NEW-TEST-H: #ifndef {{.*}}CLANG_MOVE_NEW_TEST_H
// CHECK-NEW-TEST-H: #define {{.*}}CLANG_MOVE_NEW_TEST_H
// CHECK-NEW-TEST-H: namespace a {
// CHECK-NEW-TEST-H: class Foo {
// CHECK-NEW-TEST-H: public:
@ -28,6 +31,7 @@
// CHECK-NEW-TEST-H: int f2(int a, int b);
// CHECK-NEW-TEST-H: };
// CHECK-NEW-TEST-H: } // namespace a
// CHECK-NEW-TEST-H: #endif // {{.*}}CLANG_MOVE_NEW_TEST_H
//
// CHECK-NEW-TEST-CPP: #include "{{.*}}new_test.h"
// CHECK-NEW-TEST-CPP: #include "test2.h"

View File

@ -24,6 +24,8 @@
// CHECK-OLD-TEST-CPP: }
// CHECK-OLD-TEST-CPP: } // namespace c
// CHECK-NEW-TEST-H: #ifndef {{.*}}NEW_MULTIPLE_CLASS_TEST_H
// CHECK-NEW-TEST-H: #define {{.*}}NEW_MULTIPLE_CLASS_TEST_H
// CHECK-NEW-TEST-H: namespace a {
// CHECK-NEW-TEST-H: class Move1 {
// CHECK-NEW-TEST-H: public:
@ -54,6 +56,7 @@
// CHECK-NEW-TEST-H: static int a;
// CHECK-NEW-TEST-H: };
// CHECK-NEW-TEST-H: } // namespace c
// CHECK-NEW-TEST-H: #endif // {{.*}}NEW_MULTIPLE_CLASS_TEST_H
// CHECK-NEW-TEST-CPP: #include "{{.*}}new_multiple_class_test.h"
// CHECK-NEW-TEST-CPP: namespace a {

View File

@ -123,7 +123,9 @@ const char ExpectedTestCC[] = "#include \"foo.h\"\n"
"} // namespace b\n"
"} // namespace a\n";
const char ExpectedNewHeader[] = "namespace a {\n"
const char ExpectedNewHeader[] = "#ifndef NEW_FOO_H\n"
"#define NEW_FOO_H\n"
"namespace a {\n"
"class C1; // test\n"
"namespace b {\n"
"// This is a Foo class\n"
@ -138,7 +140,8 @@ const char ExpectedNewHeader[] = "namespace a {\n"
" static int b;\n"
"}; // abc\n"
"} // namespace b\n"
"} // namespace a\n";
"} // namespace a\n"
"#endif // NEW_FOO_H\n";
const char ExpectedNewCC[] = "namespace a {\n"
"namespace b {\n"