llvm-project
75 строк · 2.7 Кб
1//===--- LocateSymbol.cpp - Find locations providing a symbol -------------===//
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 "AnalysisInternal.h"10#include "clang-include-cleaner/Types.h"11#include "clang/AST/Decl.h"12#include "clang/AST/DeclBase.h"13#include "clang/AST/DeclCXX.h"14#include "clang/AST/DeclTemplate.h"15#include "clang/Tooling/Inclusions/StandardLibrary.h"16#include "llvm/Support/Casting.h"17#include <utility>18#include <vector>19
20namespace clang::include_cleaner {21namespace {22
23template <typename T> Hints completeIfDefinition(T *D) {24return D->isThisDeclarationADefinition() ? Hints::CompleteSymbol25: Hints::None;26}
27
28Hints declHints(const Decl *D) {29// Definition is only needed for classes and templates for completeness.30if (auto *TD = llvm::dyn_cast<TagDecl>(D))31return completeIfDefinition(TD);32else if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(D))33return completeIfDefinition(CTD);34else if (auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(D))35return completeIfDefinition(FTD);36// Any other declaration is assumed usable.37return Hints::CompleteSymbol;38}
39
40std::vector<Hinted<SymbolLocation>> locateDecl(const Decl &D) {41std::vector<Hinted<SymbolLocation>> Result;42// FIXME: Should we also provide physical locations?43if (auto SS = tooling::stdlib::Recognizer()(&D))44return {{*SS, Hints::CompleteSymbol}};45// FIXME: Signal foreign decls, e.g. a forward declaration not owned by a46// library. Some useful signals could be derived by checking the DeclContext.47// Most incidental forward decls look like:48// namespace clang {49// class SourceManager; // likely an incidental forward decl.50// namespace my_own_ns {}51// }52for (auto *Redecl : D.redecls())53Result.push_back({Redecl->getLocation(), declHints(Redecl)});54return Result;55}
56
57std::vector<Hinted<SymbolLocation>> locateMacro(const Macro &M) {58// FIXME: Should we also provide physical locations?59if (auto SS = tooling::stdlib::Symbol::named("", M.Name->getName()))60return {{*SS, Hints::CompleteSymbol}};61return {{M.Definition, Hints::CompleteSymbol}};62}
63} // namespace64
65std::vector<Hinted<SymbolLocation>> locateSymbol(const Symbol &S) {66switch (S.kind()) {67case Symbol::Declaration:68return locateDecl(S.declaration());69case Symbol::Macro:70return locateMacro(S.macro());71}72llvm_unreachable("Unknown Symbol::Kind enum");73}
74
75} // namespace clang::include_cleaner76