brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · b743330 Raw
80 lines · cpp
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-exception6//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) {24  return D->isThisDeclarationADefinition() ? Hints::CompleteSymbol25                                           : Hints::None;26}27 28Hints declHints(const Decl *D) {29  // Definition is only needed for classes and templates for completeness.30  if (auto *TD = llvm::dyn_cast<TagDecl>(D))31    return completeIfDefinition(TD);32  else if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(D))33    return completeIfDefinition(CTD);34  else if (auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(D))35    return completeIfDefinition(FTD);36  // Any other declaration is assumed usable.37  return Hints::CompleteSymbol;38}39 40std::vector<Hinted<SymbolLocation>> locateDecl(const Decl &D) {41  std::vector<Hinted<SymbolLocation>> Result;42  // FIXME: Should we also provide physical locations?43  if (auto SS = tooling::stdlib::Recognizer()(&D))44    return {{*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  //   }52  for (auto *Redecl : D.redecls())53    Result.push_back({Redecl->getLocation(), declHints(Redecl)});54  return Result;55}56 57std::vector<Hinted<SymbolLocation>> locateMacro(const Macro &M,58                                                const tooling::stdlib::Lang L) {59  // FIXME: Should we also provide physical locations?60  if (auto SS = tooling::stdlib::Symbol::named("", M.Name->getName(), L))61    return {{*SS, Hints::CompleteSymbol}};62  return {{M.Definition, Hints::CompleteSymbol}};63}64} // namespace65 66std::vector<Hinted<SymbolLocation>> locateSymbol(const Symbol &S,67                                                 const LangOptions &LO) {68  const auto L = !LO.CPlusPlus && LO.C99 ? tooling::stdlib::Lang::C69                                         : tooling::stdlib::Lang::CXX;70  switch (S.kind()) {71  case Symbol::Declaration:72    return locateDecl(S.declaration());73  case Symbol::Macro:74    return locateMacro(S.macro(), L);75  }76  llvm_unreachable("Unknown Symbol::Kind enum");77}78 79} // namespace clang::include_cleaner80