1 //===-------- IncludeInserter.cpp - clang-tidy ----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "IncludeInserter.h" 11 #include "clang/Lex/Token.h" 12 13 namespace clang { 14 namespace tidy { 15 namespace utils { 16 17 class IncludeInserterCallback : public PPCallbacks { 18 public: 19 explicit IncludeInserterCallback(IncludeInserter *Inserter) 20 : Inserter(Inserter) {} 21 // Implements PPCallbacks::InclusionDerective(). Records the names and source 22 // locations of the inclusions in the main source file being processed. 23 void InclusionDirective(SourceLocation HashLocation, 24 const Token &IncludeToken, StringRef FileNameRef, 25 bool IsAngled, CharSourceRange FileNameRange, 26 const FileEntry * /*IncludedFile*/, 27 StringRef /*SearchPath*/, StringRef /*RelativePath*/, 28 const Module * /*ImportedModule*/) override { 29 Inserter->AddInclude(FileNameRef, IsAngled, HashLocation, 30 IncludeToken.getEndLoc()); 31 } 32 33 private: 34 IncludeInserter *Inserter; 35 }; 36 37 IncludeInserter::IncludeInserter(const SourceManager &SourceMgr, 38 const LangOptions &LangOpts, 39 IncludeSorter::IncludeStyle Style) 40 : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {} 41 42 IncludeInserter::~IncludeInserter() {} 43 44 std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() { 45 return llvm::make_unique<IncludeInserterCallback>(this); 46 } 47 48 llvm::Optional<FixItHint> 49 IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header, 50 bool IsAngled) { 51 // We assume the same Header will never be included both angled and not 52 // angled. 53 if (!InsertedHeaders[FileID].insert(Header).second) 54 return llvm::None; 55 56 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) { 57 // This may happen if there have been no preprocessor directives in this 58 // file. 59 IncludeSorterByFile.insert(std::make_pair( 60 FileID, 61 llvm::make_unique<IncludeSorter>( 62 &SourceMgr, &LangOpts, FileID, 63 SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)), 64 Style))); 65 } 66 return IncludeSorterByFile[FileID]->CreateIncludeInsertion(Header, IsAngled); 67 } 68 69 void IncludeInserter::AddInclude(StringRef FileName, bool IsAngled, 70 SourceLocation HashLocation, 71 SourceLocation EndLocation) { 72 FileID FileID = SourceMgr.getFileID(HashLocation); 73 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) { 74 IncludeSorterByFile.insert(std::make_pair( 75 FileID, llvm::make_unique<IncludeSorter>( 76 &SourceMgr, &LangOpts, FileID, 77 SourceMgr.getFilename(HashLocation), Style))); 78 } 79 IncludeSorterByFile[FileID]->AddInclude(FileName, IsAngled, HashLocation, 80 EndLocation); 81 } 82 83 } // namespace utils 84 } // namespace tidy 85 } // namespace clang 86