1 //===--- HeaderGuardCheck.cpp - clang-tidy --------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "HeaderGuardCheck.h"
10 #include "clang/Tooling/Tooling.h"
11 #include "llvm/Support/Path.h"
13 namespace clang::tidy::llvm_check
{
15 LLVMHeaderGuardCheck::LLVMHeaderGuardCheck(StringRef Name
,
16 ClangTidyContext
*Context
)
17 : HeaderGuardCheck(Name
, Context
) {}
19 std::string
LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename
,
21 std::string Guard
= tooling::getAbsolutePath(Filename
);
23 // When running under Windows, need to convert the path separators from
25 Guard
= llvm::sys::path::convert_to_slash(Guard
);
27 // Sanitize the path. There are some rules for compatibility with the historic
28 // style in include/llvm and include/clang which we want to preserve.
30 // We don't want _INCLUDE_ in our guards.
31 size_t PosInclude
= Guard
.rfind("include/");
32 if (PosInclude
!= StringRef::npos
)
33 Guard
= Guard
.substr(PosInclude
+ std::strlen("include/"));
35 // For clang we drop the _TOOLS_.
36 size_t PosToolsClang
= Guard
.rfind("tools/clang/");
37 if (PosToolsClang
!= StringRef::npos
)
38 Guard
= Guard
.substr(PosToolsClang
+ std::strlen("tools/"));
40 // Unlike LLVM svn, LLVM git monorepo is named llvm-project, so we replace
41 // "/llvm-project/" with the canonical "/llvm/".
42 const static StringRef LLVMProject
= "/llvm-project/";
43 size_t PosLLVMProject
= Guard
.rfind(std::string(LLVMProject
));
44 if (PosLLVMProject
!= StringRef::npos
)
45 Guard
= Guard
.replace(PosLLVMProject
, LLVMProject
.size(), "/llvm/");
47 // The remainder is LLVM_FULL_PATH_TO_HEADER_H
48 size_t PosLLVM
= Guard
.rfind("llvm/");
49 if (PosLLVM
!= StringRef::npos
)
50 Guard
= Guard
.substr(PosLLVM
);
52 std::replace(Guard
.begin(), Guard
.end(), '/', '_');
53 std::replace(Guard
.begin(), Guard
.end(), '.', '_');
54 std::replace(Guard
.begin(), Guard
.end(), '-', '_');
56 // The prevalent style in clang is LLVM_CLANG_FOO_BAR_H
57 if (StringRef(Guard
).startswith("clang"))
58 Guard
= "LLVM_" + Guard
;
60 // The prevalent style in flang is FORTRAN_FOO_BAR_H
61 if (StringRef(Guard
).startswith("flang"))
62 Guard
= "FORTRAN" + Guard
.substr(sizeof("flang") - 1);
64 return StringRef(Guard
).upper();
67 } // namespace clang::tidy::llvm_check