HeaderGuardCheck.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. #include "HeaderGuardCheck.h"
  9. #include "clang/Tooling/Tooling.h"
  10. #include "llvm/Support/Path.h"
  11. namespace clang::tidy::llvm_check {
  12. LLVMHeaderGuardCheck::LLVMHeaderGuardCheck(StringRef Name,
  13. ClangTidyContext *Context)
  14. : HeaderGuardCheck(Name, Context) {}
  15. std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename,
  16. StringRef OldGuard) {
  17. std::string Guard = tooling::getAbsolutePath(Filename);
  18. // When running under Windows, need to convert the path separators from
  19. // `\` to `/`.
  20. Guard = llvm::sys::path::convert_to_slash(Guard);
  21. // Sanitize the path. There are some rules for compatibility with the historic
  22. // style in include/llvm and include/clang which we want to preserve.
  23. // We don't want _INCLUDE_ in our guards.
  24. size_t PosInclude = Guard.rfind("include/");
  25. if (PosInclude != StringRef::npos)
  26. Guard = Guard.substr(PosInclude + std::strlen("include/"));
  27. // For clang we drop the _TOOLS_.
  28. size_t PosToolsClang = Guard.rfind("tools/clang/");
  29. if (PosToolsClang != StringRef::npos)
  30. Guard = Guard.substr(PosToolsClang + std::strlen("tools/"));
  31. // Unlike LLVM svn, LLVM git monorepo is named llvm-project, so we replace
  32. // "/llvm-project/" with the canonical "/llvm/".
  33. const static StringRef LLVMProject = "/llvm-project/";
  34. size_t PosLLVMProject = Guard.rfind(std::string(LLVMProject));
  35. if (PosLLVMProject != StringRef::npos)
  36. Guard = Guard.replace(PosLLVMProject, LLVMProject.size(), "/llvm/");
  37. // The remainder is LLVM_FULL_PATH_TO_HEADER_H
  38. size_t PosLLVM = Guard.rfind("llvm/");
  39. if (PosLLVM != StringRef::npos)
  40. Guard = Guard.substr(PosLLVM);
  41. std::replace(Guard.begin(), Guard.end(), '/', '_');
  42. std::replace(Guard.begin(), Guard.end(), '.', '_');
  43. std::replace(Guard.begin(), Guard.end(), '-', '_');
  44. // The prevalent style in clang is LLVM_CLANG_FOO_BAR_H
  45. if (StringRef(Guard).startswith("clang"))
  46. Guard = "LLVM_" + Guard;
  47. // The prevalent style in flang is FORTRAN_FOO_BAR_H
  48. if (StringRef(Guard).startswith("flang"))
  49. Guard = "FORTRAN" + Guard.substr(sizeof("flang") - 1);
  50. return StringRef(Guard).upper();
  51. }
  52. } // namespace clang::tidy::llvm_check