blob: 8f4bee6ad906e5bb1d2980a80aa5274ade67a4c7 [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.
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000052 if (!InsertedHeaders[FileID].insert(Header).second)
Manuel Klimekd00d6f12015-08-11 11:37:48 +000053 return llvm::None;
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000054
Manuel Klimekd00d6f12015-08-11 11:37:48 +000055 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
Alexander Kornienko8cc024e2015-08-14 12:33:25 +000056 // This may happen if there have been no preprocessor directives in this
57 // file.
58 IncludeSorterByFile.insert(std::make_pair(
59 FileID,
60 llvm::make_unique<IncludeSorter>(
61 &SourceMgr, &LangOpts, FileID,
62 SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)),
63 Style)));
Manuel Klimekd00d6f12015-08-11 11:37:48 +000064 }
65 return IncludeSorterByFile[FileID]->CreateIncludeInsertion(Header, IsAngled);
66}
67
68void IncludeInserter::AddInclude(StringRef file_name, bool IsAngled,
69 SourceLocation HashLocation,
70 SourceLocation end_location) {
71 FileID FileID = SourceMgr.getFileID(HashLocation);
72 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
73 IncludeSorterByFile.insert(std::make_pair(
74 FileID, llvm::make_unique<IncludeSorter>(
75 &SourceMgr, &LangOpts, FileID,
76 SourceMgr.getFilename(HashLocation), Style)));
77 }
78 IncludeSorterByFile[FileID]->AddInclude(file_name, IsAngled, HashLocation,
79 end_location);
80}
81
82} // namespace tidy
83} // namespace clang