IncludeInserter.cpp
3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//===-------- IncludeInserter.cpp - clang-tidy ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#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 std::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,
std::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, std::make_unique<IncludeSorter>(
&SourceMgr, &LangOpts, FileID,
SourceMgr.getFilename(HashLocation), Style)));
}
IncludeSorterByFile[FileID]->AddInclude(FileName, IsAngled, HashLocation,
EndLocation);
}
} // namespace utils
} // namespace tidy
} // namespace clang