blob: 16fb58c0e53144a87b74277523986cb741df691a [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 {
Etienne Bergeron2a4c00f2016-05-03 02:54:05 +000015namespace utils {
Manuel Klimekd00d6f12015-08-11 11:37:48 +000016
17class IncludeInserterCallback : public PPCallbacks {
18public:
Manuel Klimek795daa22015-08-11 12:02:28 +000019 explicit IncludeInserterCallback(IncludeInserter *Inserter)
20 : Inserter(Inserter) {}
Manuel Klimekd00d6f12015-08-11 11:37:48 +000021 // 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,
Haojian Wu7d08ba22016-03-02 14:12:17 +000024 const Token & IncludeToken,
Manuel Klimekd00d6f12015-08-11 11:37:48 +000025 StringRef FileNameRef, bool IsAngled,
26 CharSourceRange FileNameRange,
27 const FileEntry * /*IncludedFile*/,
28 StringRef /*SearchPath*/, StringRef /*RelativePath*/,
29 const Module * /*ImportedModule*/) override {
Manuel Klimek795daa22015-08-11 12:02:28 +000030 Inserter->AddInclude(FileNameRef, IsAngled, HashLocation,
Haojian Wu7d08ba22016-03-02 14:12:17 +000031 IncludeToken.getEndLoc());
Manuel Klimekd00d6f12015-08-11 11:37:48 +000032 }
33
34private:
Manuel Klimek795daa22015-08-11 12:02:28 +000035 IncludeInserter *Inserter;
Manuel Klimekd00d6f12015-08-11 11:37:48 +000036};
37
38IncludeInserter::IncludeInserter(const SourceManager &SourceMgr,
39 const LangOptions &LangOpts,
40 IncludeSorter::IncludeStyle Style)
41 : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {}
42
David Blaikiee04a3da2015-10-20 21:45:52 +000043IncludeInserter::~IncludeInserter() {}
Manuel Klimekd00d6f12015-08-11 11:37:48 +000044
45std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() {
46 return llvm::make_unique<IncludeInserterCallback>(this);
47}
48
49llvm::Optional<FixItHint>
50IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header,
51 bool IsAngled) {
52 // We assume the same Header will never be included both angled and not
53 // angled.
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000054 if (!InsertedHeaders[FileID].insert(Header).second)
Manuel Klimekd00d6f12015-08-11 11:37:48 +000055 return llvm::None;
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000056
Manuel Klimekd00d6f12015-08-11 11:37:48 +000057 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
Alexander Kornienko8cc024e2015-08-14 12:33:25 +000058 // This may happen if there have been no preprocessor directives in this
59 // file.
60 IncludeSorterByFile.insert(std::make_pair(
61 FileID,
62 llvm::make_unique<IncludeSorter>(
63 &SourceMgr, &LangOpts, FileID,
64 SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)),
65 Style)));
Manuel Klimekd00d6f12015-08-11 11:37:48 +000066 }
67 return IncludeSorterByFile[FileID]->CreateIncludeInsertion(Header, IsAngled);
68}
69
70void IncludeInserter::AddInclude(StringRef file_name, bool IsAngled,
71 SourceLocation HashLocation,
72 SourceLocation end_location) {
73 FileID FileID = SourceMgr.getFileID(HashLocation);
74 if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
75 IncludeSorterByFile.insert(std::make_pair(
76 FileID, llvm::make_unique<IncludeSorter>(
77 &SourceMgr, &LangOpts, FileID,
78 SourceMgr.getFilename(HashLocation), Style)));
79 }
80 IncludeSorterByFile[FileID]->AddInclude(file_name, IsAngled, HashLocation,
81 end_location);
82}
83
Etienne Bergeron2a4c00f2016-05-03 02:54:05 +000084} // namespace utils
Manuel Klimekd00d6f12015-08-11 11:37:48 +000085} // namespace tidy
86} // namespace clang