71 lines · cpp
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-exception6//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 18LLVM_INSTANTIATE_REGISTRY(clang::include_cleaner::IncludeSpellingStrategy)19 20namespace clang::include_cleaner {21namespace {22 23// Fallback strategy to default spelling via header search.24class DefaultIncludeSpeller : public IncludeSpeller {25public: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())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} // namespace49 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_cleaner71