| //===-------- IncludeInserter.cpp - clang-tidy ----------------------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "IncludeInserter.h" | 
 | #include "clang/Lex/Token.h" | 
 |  | 
 | namespace clang { | 
 | namespace tidy { | 
 | namespace utils { | 
 |  | 
 | class IncludeInserterCallback : public PPCallbacks { | 
 | public: | 
 |   explicit IncludeInserterCallback(IncludeInserter *Inserter) | 
 |       : Inserter(Inserter) {} | 
 |   // Implements PPCallbacks::InclusionDerective(). Records the names and source | 
 |   // locations of the inclusions in the main source file being processed. | 
 |   void InclusionDirective(SourceLocation HashLocation, | 
 |                           const Token &IncludeToken, StringRef FileNameRef, | 
 |                           bool IsAngled, CharSourceRange FileNameRange, | 
 |                           const FileEntry * /*IncludedFile*/, | 
 |                           StringRef /*SearchPath*/, StringRef /*RelativePath*/, | 
 |                           const Module * /*ImportedModule*/, | 
 |                           SrcMgr::CharacteristicKind /*FileType*/) override { | 
 |     Inserter->AddInclude(FileNameRef, IsAngled, HashLocation, | 
 |                          IncludeToken.getEndLoc()); | 
 |   } | 
 |  | 
 | private: | 
 |   IncludeInserter *Inserter; | 
 | }; | 
 |  | 
 | IncludeInserter::IncludeInserter(const SourceManager &SourceMgr, | 
 |                                  const LangOptions &LangOpts, | 
 |                                  IncludeSorter::IncludeStyle Style) | 
 |     : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {} | 
 |  | 
 | IncludeInserter::~IncludeInserter() {} | 
 |  | 
 | std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() { | 
 |   return llvm::make_unique<IncludeInserterCallback>(this); | 
 | } | 
 |  | 
 | llvm::Optional<FixItHint> | 
 | IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header, | 
 |                                         bool IsAngled) { | 
 |   // We assume the same Header will never be included both angled and not | 
 |   // angled. | 
 |   if (!InsertedHeaders[FileID].insert(Header).second) | 
 |     return llvm::None; | 
 |  | 
 |   if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) { | 
 |     // This may happen if there have been no preprocessor directives in this | 
 |     // file. | 
 |     IncludeSorterByFile.insert(std::make_pair( | 
 |         FileID, | 
 |         llvm::make_unique<IncludeSorter>( | 
 |             &SourceMgr, &LangOpts, FileID, | 
 |             SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)), | 
 |             Style))); | 
 |   } | 
 |   return IncludeSorterByFile[FileID]->CreateIncludeInsertion(Header, IsAngled); | 
 | } | 
 |  | 
 | void IncludeInserter::AddInclude(StringRef FileName, bool IsAngled, | 
 |                                  SourceLocation HashLocation, | 
 |                                  SourceLocation EndLocation) { | 
 |   FileID FileID = SourceMgr.getFileID(HashLocation); | 
 |   if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) { | 
 |     IncludeSorterByFile.insert(std::make_pair( | 
 |         FileID, llvm::make_unique<IncludeSorter>( | 
 |                     &SourceMgr, &LangOpts, FileID, | 
 |                     SourceMgr.getFilename(HashLocation), Style))); | 
 |   } | 
 |   IncludeSorterByFile[FileID]->AddInclude(FileName, IsAngled, HashLocation, | 
 |                                           EndLocation); | 
 | } | 
 |  | 
 | } // namespace utils | 
 | } // namespace tidy | 
 | } // namespace clang |