1 //===--- HeaderGuardCheck.cpp - clang-tidy --------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "HeaderGuardCheck.h"
10 
11 namespace clang {
12 namespace tidy {
13 namespace llvm {
14 
15 LLVMHeaderGuardCheck::LLVMHeaderGuardCheck(StringRef Name,
16                                            ClangTidyContext *Context)
17     : HeaderGuardCheck(Name, Context) {}
18 
19 std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename,
20                                                  StringRef OldGuard) {
21   std::string Guard = tooling::getAbsolutePath(Filename);
22 
23   // Sanitize the path. There are some rules for compatibility with the historic
24   // style in include/llvm and include/clang which we want to preserve.
25 
26   // We don't want _INCLUDE_ in our guards.
27   size_t PosInclude = Guard.rfind("include/");
28   if (PosInclude != StringRef::npos)
29     Guard = Guard.substr(PosInclude + std::strlen("include/"));
30 
31   // For clang we drop the _TOOLS_.
32   size_t PosToolsClang = Guard.rfind("tools/clang/");
33   if (PosToolsClang != StringRef::npos)
34     Guard = Guard.substr(PosToolsClang + std::strlen("tools/"));
35 
36   // The remainder is LLVM_FULL_PATH_TO_HEADER_H
37   size_t PosLLVM = Guard.rfind("llvm/");
38   if (PosLLVM != StringRef::npos)
39     Guard = Guard.substr(PosLLVM);
40 
41   std::replace(Guard.begin(), Guard.end(), '/', '_');
42   std::replace(Guard.begin(), Guard.end(), '.', '_');
43   std::replace(Guard.begin(), Guard.end(), '-', '_');
44 
45   // The prevalent style in clang is LLVM_CLANG_FOO_BAR_H
46   if (StringRef(Guard).startswith("clang"))
47     Guard = "LLVM_" + Guard;
48 
49   return StringRef(Guard).upper();
50 }
51 
52 } // namespace llvm
53 } // namespace tidy
54 } // namespace clang
55