blob: e0b977386d879305188ffc514e64006032ba474c [file] [log] [blame]
Manuel Klimekd00d6f12015-08-11 11:37:48 +00001//===-------- 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
12namespace clang {
13namespace tidy {
14
15class IncludeInserterCallback : public PPCallbacks {
16public:
Manuel Klimek795daa22015-08-11 12:02:28 +000017 explicit IncludeInserterCallback(IncludeInserter *Inserter)
18 : Inserter(Inserter) {}
Manuel Klimekd00d6f12015-08-11 11:37:48 +000019 // Implements PPCallbacks::InclusionDerective(). Records the names and source
20 // locations of the inclusions in the main source file being processed.
21 void InclusionDirective(SourceLocation HashLocation,
22 const Token & /*include_token*/,
23 StringRef FileNameRef, bool IsAngled,
24 CharSourceRange FileNameRange,
25 const FileEntry * /*IncludedFile*/,
26 StringRef /*SearchPath*/, StringRef /*RelativePath*/,
27 const Module * /*ImportedModule*/) override {
Manuel Klimek795daa22015-08-11 12:02:28 +000028 Inserter->AddInclude(FileNameRef, IsAngled, HashLocation,
Alexander Kornienko8cc024e2015-08-14 12:33:25 +000029 FileNameRange.getEnd());
Manuel Klimekd00d6f12015-08-11 11:37:48 +000030 }
31
32private:
Manuel Klimek795daa22015-08-11 12:02:28 +000033 IncludeInserter *Inserter;
Manuel Klimekd00d6f12015-08-11 11:37:48 +000034};
35
36IncludeInserter::IncludeInserter(const SourceManager &SourceMgr,
37 const LangOptions &LangOpts,
38 IncludeSorter::IncludeStyle Style)
39 : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {}
40
41IncludeInserter::~IncludeInserter() {}
42
43std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() {
44 return llvm::make_unique<IncludeInserterCallback>(this);
45}
46
47llvm::Optional<FixItHint>
48IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header,
49 bool IsAngled) {
50 // We assume the same Header will never be included both angled and not
51 // angled.
52 if (!InsertedHeaders.insert(std::make_pair(FileID, std::set<std::string>()))
53 .second) {
54 return llvm::None;
55 }
56 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
Alexander Kornienko8cc024e2015-08-14 12:33:25 +000057 // 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)));
Manuel Klimekd00d6f12015-08-11 11:37:48 +000065 }
66 return IncludeSorterByFile[FileID]->CreateIncludeInsertion(Header, IsAngled);
67}
68
69void IncludeInserter::AddInclude(StringRef file_name, bool IsAngled,
70 SourceLocation HashLocation,
71 SourceLocation end_location) {
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(file_name, IsAngled, HashLocation,
80 end_location);
81}
82
83} // namespace tidy
84} // namespace clang