clang-tools  15.0.0git
IncludeInserter.cpp
Go to the documentation of this file.
1 //===-------- IncludeInserter.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 "IncludeInserter.h"
10 #include "clang/Lex/PPCallbacks.h"
11 #include "clang/Lex/Preprocessor.h"
12 #include "clang/Lex/Token.h"
13 
14 namespace clang {
15 namespace tidy {
16 namespace utils {
17 
19 public:
21  : Inserter(Inserter) {}
22  // Implements PPCallbacks::InclusionDirective(). Records the names and source
23  // locations of the inclusions in the main source file being processed.
24  void InclusionDirective(SourceLocation HashLocation,
25  const Token &IncludeToken, StringRef FileNameRef,
26  bool IsAngled, CharSourceRange FileNameRange,
27  Optional<FileEntryRef> /*IncludedFile*/,
28  StringRef /*SearchPath*/, StringRef /*RelativePath*/,
29  const Module * /*ImportedModule*/,
30  SrcMgr::CharacteristicKind /*FileType*/) override {
31  Inserter->addInclude(FileNameRef, IsAngled, HashLocation,
32  IncludeToken.getEndLoc());
33  }
34 
35 private:
36  IncludeInserter *Inserter;
37 };
38 
40  bool SelfContainedDiags)
41  : Style(Style), SelfContainedDiags(SelfContainedDiags) {}
42 
44  assert(PP && "PP shouldn't be null");
45  SourceMgr = &PP->getSourceManager();
46 
47  // If this gets registered multiple times, clear the maps
48  if (!IncludeSorterByFile.empty())
49  IncludeSorterByFile.clear();
50  if (!InsertedHeaders.empty())
51  InsertedHeaders.clear();
52  PP->addPPCallbacks(std::make_unique<IncludeInserterCallback>(this));
53 }
54 
55 IncludeSorter &IncludeInserter::getOrCreate(FileID FileID) {
56  assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
57  "registerPreprocessor()?");
58  // std::unique_ptr is cheap to construct, so force a construction now to save
59  // the lookup needed if we were to insert into the map.
60  std::unique_ptr<IncludeSorter> &Entry = IncludeSorterByFile[FileID];
61  if (!Entry) {
62  // If it wasn't found, Entry will be default constructed to nullptr.
63  Entry = std::make_unique<IncludeSorter>(
64  SourceMgr, FileID,
65  SourceMgr->getFilename(SourceMgr->getLocForStartOfFile(FileID)), Style);
66  }
67  return *Entry;
68 }
69 
70 llvm::Optional<FixItHint>
71 IncludeInserter::createIncludeInsertion(FileID FileID, llvm::StringRef Header) {
72  bool IsAngled = Header.consume_front("<");
73  if (IsAngled != Header.consume_back(">"))
74  return llvm::None;
75  // We assume the same Header will never be included both angled and not
76  // angled.
77  // In self contained diags mode we don't track what headers we have already
78  // inserted.
79  if (!SelfContainedDiags && !InsertedHeaders[FileID].insert(Header).second)
80  return llvm::None;
81 
82  return getOrCreate(FileID).createIncludeInsertion(Header, IsAngled);
83 }
84 
85 llvm::Optional<FixItHint>
87  assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
88  "registerPreprocessor()?");
89  return createIncludeInsertion(SourceMgr->getMainFileID(), Header);
90 }
91 
92 void IncludeInserter::addInclude(StringRef FileName, bool IsAngled,
93  SourceLocation HashLocation,
94  SourceLocation EndLocation) {
95  assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
96  "registerPreprocessor()?");
97  FileID FileID = SourceMgr->getFileID(HashLocation);
98  getOrCreate(FileID).addInclude(FileName, IsAngled, HashLocation, EndLocation);
99 }
100 
101 } // namespace utils
102 } // namespace tidy
103 } // namespace clang
clang::tidy::utils::IncludeSorter
Class used by IncludeInserterCallback to record the names of the inclusions in a given source file be...
Definition: IncludeSorter.h:23
clang::tidy::utils::IncludeInserter
Produces fixes to insert specified includes to source files, if not yet present.
Definition: IncludeInserter.h:55
clang::tidy::utils::IncludeInserterCallback
Definition: IncludeInserter.cpp:18
clang::tidy::utils::IncludeSorter::IncludeStyle
IncludeStyle
Supported include styles.
Definition: IncludeSorter.h:26
clang::tidy::utils::IncludeInserter::IncludeInserter
IncludeInserter(IncludeSorter::IncludeStyle Style, bool SelfContainedDiags)
Initializes the IncludeInserter using the IncludeStyle Style.
Definition: IncludeInserter.cpp:39
clang::tidy::utils::IncludeInserter::registerPreprocessor
void registerPreprocessor(Preprocessor *PP)
Registers this with the Preprocessor PP, must be called before this class is used.
Definition: IncludeInserter.cpp:43
clang::tidy::utils::IncludeInserterCallback::InclusionDirective
void InclusionDirective(SourceLocation HashLocation, const Token &IncludeToken, StringRef FileNameRef, bool IsAngled, CharSourceRange FileNameRange, Optional< FileEntryRef >, StringRef, StringRef, const Module *, SrcMgr::CharacteristicKind) override
Definition: IncludeInserter.cpp:24
clang::tidy::utils::IncludeInserterCallback::IncludeInserterCallback
IncludeInserterCallback(IncludeInserter *Inserter)
Definition: IncludeInserter.cpp:20
clang::tidy::utils::IncludeInserter::createMainFileIncludeInsertion
llvm::Optional< FixItHint > createMainFileIncludeInsertion(llvm::StringRef Header)
Creates a Header inclusion directive fixit in the main file.
Definition: IncludeInserter.cpp:86
FileName
StringRef FileName
Definition: KernelNameRestrictionCheck.cpp:46
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:29
Entry
Definition: Modularize.cpp:428
IsAngled
bool IsAngled
true if this was an include with angle brackets
Definition: IncludeOrderCheck.cpp:40
PPCallbacks
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::utils::IncludeInserter::createIncludeInsertion
llvm::Optional< FixItHint > createIncludeInsertion(FileID FileID, llvm::StringRef Header)
Creates a Header inclusion directive fixit in the File FileID.
Definition: IncludeInserter.cpp:71
clang::tidy::utils::IncludeSorter::addInclude
void addInclude(StringRef FileName, bool IsAngled, SourceLocation HashLocation, SourceLocation EndLocation)
Adds the given include directive to the sorter.
Definition: IncludeSorter.cpp:131
IncludeInserter.h
clang::tidy::utils::IncludeSorter::createIncludeInsertion
Optional< FixItHint > createIncludeInsertion(StringRef FileName, bool IsAngled)
Creates a quoted inclusion directive in the right sort order.
Definition: IncludeSorter.cpp:152