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#include "clang/Tooling/Tooling.h"
11#include "llvm/Support/Path.h"
12
13namespace clang::tidy::llvm_check {
14
15LLVMHeaderGuardCheck::LLVMHeaderGuardCheck(StringRef Name,
16 ClangTidyContext *Context)
17 : HeaderGuardCheck(Name, Context) {}
18
19std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename,
20 StringRef OldGuard) {
21 std::string Guard = tooling::getAbsolutePath(File: Filename);
22
23 // When running under Windows, need to convert the path separators from
24 // `\` to `/`.
25 Guard = llvm::sys::path::convert_to_slash(path: Guard);
26
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.
29
30 // We don't want _INCLUDE_ in our guards.
31 size_t PosInclude = Guard.rfind(s: "include/");
32 if (PosInclude != StringRef::npos)
33 Guard = Guard.substr(pos: PosInclude + std::strlen(s: "include/"));
34
35 // For clang we drop the _TOOLS_.
36 size_t PosToolsClang = Guard.rfind(s: "tools/clang/");
37 if (PosToolsClang != StringRef::npos)
38 Guard = Guard.substr(pos: PosToolsClang + std::strlen(s: "tools/"));
39
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(str: std::string(LLVMProject));
44 if (PosLLVMProject != StringRef::npos)
45 Guard = Guard.replace(pos: PosLLVMProject, n1: LLVMProject.size(), s: "/llvm/");
46
47 // The remainder is LLVM_FULL_PATH_TO_HEADER_H
48 size_t PosLLVM = Guard.rfind(s: "llvm/");
49 if (PosLLVM != StringRef::npos)
50 Guard = Guard.substr(pos: PosLLVM);
51
52 std::replace(first: Guard.begin(), last: Guard.end(), old_value: '/', new_value: '_');
53 std::replace(first: Guard.begin(), last: Guard.end(), old_value: '.', new_value: '_');
54 std::replace(first: Guard.begin(), last: Guard.end(), old_value: '-', new_value: '_');
55
56 // The prevalent style in clang is LLVM_CLANG_FOO_BAR_H
57 if (StringRef(Guard).starts_with(Prefix: "clang"))
58 Guard = "LLVM_" + Guard;
59
60 // The prevalent style in flang is FORTRAN_FOO_BAR_H
61 if (StringRef(Guard).starts_with(Prefix: "flang"))
62 Guard = "FORTRAN" + Guard.substr(pos: sizeof("flang") - 1);
63
64 return StringRef(Guard).upper();
65}
66
67} // namespace clang::tidy::llvm_check
68

source code of clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp