1 //===--- IncludeSpeller.cpp------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang-include-cleaner/IncludeSpeller.h"
10 #include "clang-include-cleaner/Types.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/ErrorHandling.h"
14 #include "llvm/Support/Registry.h"
18 LLVM_INSTANTIATE_REGISTRY(clang::include_cleaner::IncludeSpellingStrategy
)
20 namespace clang::include_cleaner
{
23 // Fallback strategy to default spelling via header search.
24 class DefaultIncludeSpeller
: public IncludeSpeller
{
26 std::string
operator()(const Input
&Input
) const override
{
27 switch (Input
.H
.kind()) {
28 case Header::Standard
:
29 return Input
.H
.standard().name().str();
30 case Header::Verbatim
:
31 return Input
.H
.verbatim().str();
32 case Header::Physical
:
33 bool IsAngled
= false;
34 std::string WorkingDir
;
35 if (auto WD
= Input
.HS
.getFileMgr()
36 .getVirtualFileSystem()
37 .getCurrentWorkingDirectory())
39 std::string FinalSpelling
= Input
.HS
.suggestPathToFileForDiagnostics(
40 Input
.H
.physical().getName(), WorkingDir
,
41 Input
.Main
->tryGetRealPathName(), &IsAngled
);
42 return IsAngled
? "<" + FinalSpelling
+ ">" : "\"" + FinalSpelling
+ "\"";
44 llvm_unreachable("Unknown clang::include_cleaner::Header::Kind enum");
50 std::string
spellHeader(const IncludeSpeller::Input
&Input
) {
51 static auto *Spellers
= [] {
53 new llvm::SmallVector
<std::unique_ptr
<include_cleaner::IncludeSpeller
>>;
54 for (const auto &Strategy
:
55 include_cleaner::IncludeSpellingStrategy::entries())
56 Result
->push_back(Strategy
.instantiate());
57 Result
->push_back(std::make_unique
<DefaultIncludeSpeller
>());
62 for (const auto &Speller
: *Spellers
) {
63 Spelling
= (*Speller
)(Input
);
64 if (!Spelling
.empty())
70 } // namespace clang::include_cleaner