1 //===--- RestrictSystemLibcHeadersCheck.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 "RestrictSystemLibcHeadersCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Lex/HeaderSearch.h"
13 #include "clang/Lex/HeaderSearchOptions.h"
14 #include "clang/Lex/Preprocessor.h"
15 
16 // FixItHint - Hint to check documentation script to mark this check as
17 // providing a FixIt.
18 
19 namespace clang {
20 namespace tidy {
21 namespace llvm_libc {
22 
23 namespace {
24 
25 class RestrictedIncludesPPCallbacks
26     : public portability::RestrictedIncludesPPCallbacks {
27 public:
RestrictedIncludesPPCallbacks(RestrictSystemLibcHeadersCheck & Check,const SourceManager & SM,const SmallString<128> CompilerIncudeDir)28   explicit RestrictedIncludesPPCallbacks(
29       RestrictSystemLibcHeadersCheck &Check, const SourceManager &SM,
30       const SmallString<128> CompilerIncudeDir)
31       : portability::RestrictedIncludesPPCallbacks(Check, SM),
32         CompilerIncudeDir(CompilerIncudeDir) {}
33 
34   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
35                           StringRef FileName, bool IsAngled,
36                           CharSourceRange FilenameRange, const FileEntry *File,
37                           StringRef SearchPath, StringRef RelativePath,
38                           const Module *Imported,
39                           SrcMgr::CharacteristicKind FileType) override;
40 
41 private:
42   const SmallString<128> CompilerIncudeDir;
43 };
44 
45 } // namespace
46 
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)47 void RestrictedIncludesPPCallbacks::InclusionDirective(
48     SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
49     bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
50     StringRef SearchPath, StringRef RelativePath, const Module *Imported,
51     SrcMgr::CharacteristicKind FileType) {
52   // Compiler provided headers are allowed (e.g stddef.h).
53   if (SrcMgr::isSystem(FileType) && SearchPath == CompilerIncudeDir)
54     return;
55   portability::RestrictedIncludesPPCallbacks::InclusionDirective(
56       HashLoc, IncludeTok, FileName, IsAngled, FilenameRange, File, SearchPath,
57       RelativePath, Imported, FileType);
58 }
59 
registerPPCallbacks(const SourceManager & SM,Preprocessor * PP,Preprocessor * ModuleExpanderPP)60 void RestrictSystemLibcHeadersCheck::registerPPCallbacks(
61     const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
62   SmallString<128> CompilerIncudeDir =
63       StringRef(PP->getHeaderSearchInfo().getHeaderSearchOpts().ResourceDir);
64   llvm::sys::path::append(CompilerIncudeDir, "include");
65   PP->addPPCallbacks(std::make_unique<RestrictedIncludesPPCallbacks>(
66       *this, SM, CompilerIncudeDir));
67 }
68 
69 } // namespace llvm_libc
70 } // namespace tidy
71 } // namespace clang
72