blob: d128c691110aada627ad97b1860eef1a813d1ba1 [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"
Haojian Wu7d08ba22016-03-02 14:12:17 +000011#include "clang/Lex/Token.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +000012
13namespace clang {
14namespace tidy {
15
16class IncludeInserterCallback : public PPCallbacks {
17public:
Manuel Klimek795daa22015-08-11 12:02:28 +000018 explicit IncludeInserterCallback(IncludeInserter *Inserter)
19 : Inserter(Inserter) {}
Manuel Klimekd00d6f12015-08-11 11:37:48 +000020 // Implements PPCallbacks::InclusionDerective(). Records the names and source
21 // locations of the inclusions in the main source file being processed.
22 void InclusionDirective(SourceLocation HashLocation,
Haojian Wu7d08ba22016-03-02 14:12:17 +000023 const Token & IncludeToken,
Manuel Klimekd00d6f12015-08-11 11:37:48 +000024 StringRef FileNameRef, bool IsAngled,
25 CharSourceRange FileNameRange,
26 const FileEntry * /*IncludedFile*/,
27 StringRef /*SearchPath*/, StringRef /*RelativePath*/,
28 const Module * /*ImportedModule*/) override {
Manuel Klimek795daa22015-08-11 12:02:28 +000029 Inserter->AddInclude(FileNameRef, IsAngled, HashLocation,
Haojian Wu7d08ba22016-03-02 14:12:17 +000030 IncludeToken.getEndLoc());
Manuel Klimekd00d6f12015-08-11 11:37:48 +000031 }
32
33private:
Manuel Klimek795daa22015-08-11 12:02:28 +000034 IncludeInserter *Inserter;
Manuel Klimekd00d6f12015-08-11 11:37:48 +000035};
36
37IncludeInserter::IncludeInserter(const SourceManager &SourceMgr,
38 const LangOptions &LangOpts,
39 IncludeSorter::IncludeStyle Style)
40 : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {}
41
David Blaikiee04a3da2015-10-20 21:45:52 +000042IncludeInserter::~IncludeInserter() {}
Manuel Klimekd00d6f12015-08-11 11:37:48 +000043
44std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() {
45 return llvm::make_unique<IncludeInserterCallback>(this);
46}
47
48llvm::Optional<FixItHint>
49IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header,
50 bool IsAngled) {
51 // We assume the same Header will never be included both angled and not
52 // angled.
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000053 if (!InsertedHeaders[FileID].insert(Header).second)
Manuel Klimekd00d6f12015-08-11 11:37:48 +000054 return llvm::None;
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000055
Manuel Klimekd00d6f12015-08-11 11:37:48 +000056 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