clang-tools  11.0.0git
RestrictSystemIncludesCheck.cpp
Go to the documentation of this file.
1 //===--- RestrictSystemIncludesCheck.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 
10 #include "clang/Frontend/CompilerInstance.h"
11 #include "clang/Lex/HeaderSearch.h"
12 #include "clang/Lex/PPCallbacks.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/Support/Path.h"
17 #include <cstring>
18 
19 namespace clang {
20 namespace tidy {
21 namespace portability {
22 
24  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
25  bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
26  StringRef SearchPath, StringRef RelativePath, const Module *Imported,
27  SrcMgr::CharacteristicKind FileType) {
28  if (!Check.contains(FileName) && SrcMgr::isSystem(FileType)) {
29  SmallString<256> FullPath;
30  llvm::sys::path::append(FullPath, SearchPath);
31  llvm::sys::path::append(FullPath, RelativePath);
32  // Bucket the allowed include directives by the id of the file they were
33  // declared in.
34  IncludeDirectives[SM.getFileID(HashLoc)].emplace_back(
35  HashLoc, FilenameRange, FileName, FullPath.str(),
36  SM.isInMainFile(HashLoc));
37  }
38 }
39 
41  for (const auto &Bucket : IncludeDirectives) {
42  const FileIncludes &FileDirectives = Bucket.second;
43 
44  // Emit fixits for all restricted includes.
45  for (const auto &Include : FileDirectives) {
46  // Fetch the length of the include statement from the start to just after
47  // the newline, for finding the end (including the newline).
48  unsigned ToLen = std::strcspn(SM.getCharacterData(Include.Loc), "\n") + 1;
49  CharSourceRange ToRange = CharSourceRange::getCharRange(
50  Include.Loc, Include.Loc.getLocWithOffset(ToLen));
51 
52  if (!Include.IsInMainFile) {
53  auto D = Check.diag(
54  Include.Loc,
55  "system include %0 not allowed, transitively included from %1");
56  D << Include.IncludeFile << SM.getFilename(Include.Loc);
57  D << FixItHint::CreateRemoval(ToRange);
58  continue;
59  }
60  auto D = Check.diag(Include.Loc, "system include %0 not allowed");
61  D << Include.IncludeFile;
62  D << FixItHint::CreateRemoval(ToRange);
63  }
64  }
65 }
66 
68  const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
69  PP->addPPCallbacks(
70  std::make_unique<RestrictedIncludesPPCallbacks>(*this, SM));
71 }
72 
75  Options.store(Opts, "Includes", AllowedIncludes);
76 }
77 
78 } // namespace portability
79 } // namespace tidy
80 } // namespace clang
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
bool IsAngled
true if this was an include with angle brackets
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override
PathRef FileName
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override
Override this to register PPCallbacks in the preprocessor.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::map< std::string, ClangTidyValue > OptionMap
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check&#39;s name.