1 //===--- IncludeSpeller.cpp------------------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 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" 15 #include <memory> 16 #include <string> 17 18 LLVM_INSTANTIATE_REGISTRY(clang::include_cleaner::IncludeSpellingStrategy) 19 20 namespace clang::include_cleaner { 21 namespace { 22 23 // Fallback strategy to default spelling via header search. 24 class DefaultIncludeSpeller : public IncludeSpeller { 25 public: operator ()(const Input & Input) const26 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()) 38 WorkingDir = *WD; 39 std::string FinalSpelling = Input.HS.suggestPathToFileForDiagnostics( 40 Input.H.physical().getName(), WorkingDir, 41 Input.Main->tryGetRealPathName(), &IsAngled); 42 return IsAngled ? "<" + FinalSpelling + ">" : "\"" + FinalSpelling + "\""; 43 } 44 llvm_unreachable("Unknown clang::include_cleaner::Header::Kind enum"); 45 } 46 }; 47 48 } // namespace 49 spellHeader(const IncludeSpeller::Input & Input)50std::string spellHeader(const IncludeSpeller::Input &Input) { 51 static auto *Spellers = [] { 52 auto *Result = 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>()); 58 return Result; 59 }(); 60 61 std::string Spelling; 62 for (const auto &Speller : *Spellers) { 63 Spelling = (*Speller)(Input); 64 if (!Spelling.empty()) 65 break; 66 } 67 return Spelling; 68 } 69 70 } // namespace clang::include_cleaner 71