16 #include "clang/AST/AST.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/RecursiveASTVisitor.h"
19 #include "clang/Index/USRGeneration.h"
20 #include "clang/Lex/Lexer.h"
21 #include "llvm/ADT/SmallVector.h"
32 class NamedDeclFindingASTVisitor
33 :
public clang::RecursiveASTVisitor<NamedDeclFindingASTVisitor> {
37 explicit NamedDeclFindingASTVisitor(
const SourceManager &
SourceMgr,
38 const SourceLocation
Point)
39 :
Result(nullptr), SourceMgr(SourceMgr),
49 bool VisitNamedDecl(
const NamedDecl *Decl) {
50 return setResult(Decl, Decl->getLocation(),
51 Decl->getNameAsString().length());
56 bool VisitDeclRefExpr(
const DeclRefExpr *Expr) {
58 if (!checkNestedNameSpecifierLoc(Expr->getQualifierLoc()))
61 const auto *Decl = Expr->getFoundDecl();
62 return setResult(Decl, Expr->getLocation(),
63 Decl->getNameAsString().length());
66 bool VisitMemberExpr(
const MemberExpr *Expr) {
67 const auto *Decl = Expr->getFoundDecl().getDecl();
68 return setResult(Decl, Expr->getMemberLoc(),
69 Decl->getNameAsString().length());
74 const NamedDecl *getNamedDecl() {
81 bool checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
83 const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
84 if (Decl && !setResult(Decl, NameLoc.getLocalBeginLoc(),
85 Decl->getNameAsString().length()))
87 NameLoc = NameLoc.getPrefix();
94 bool setResult(
const NamedDecl *Decl, SourceLocation Start,
96 if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
97 !End.isFileID() || !isPointWithin(Start, End)) {
106 bool setResult(
const NamedDecl *Decl, SourceLocation
Loc,
109 return Offset == 0 ||
110 setResult(Decl, Loc, Loc.getLocWithOffset(Offset - 1));
114 bool isPointWithin(
const SourceLocation Start,
const SourceLocation End) {
128 const SourceLocation
Point) {
129 const auto &
SourceMgr = Context.getSourceManager();
130 const auto SearchFile =
SourceMgr.getFilename(Point);
132 NamedDeclFindingASTVisitor Visitor(
SourceMgr, Point);
135 auto Decls = Context.getTranslationUnitDecl()->decls();
136 for (
auto &CurrDecl : Decls) {
137 const auto FileLoc = CurrDecl->getLocStart();
138 const auto FileName =
SourceMgr.getFilename(FileLoc);
140 if (FileName == SearchFile) {
141 Visitor.TraverseDecl(CurrDecl);
142 if (
const NamedDecl *
Result = Visitor.getNamedDecl()) {
152 llvm::SmallVector<char, 128> Buff;
155 if (Decl ==
nullptr || index::generateUSRForDecl(Decl, Buff))
158 return std::string(Buff.data(), Buff.size());
SourceLocation Loc
'#' location in the include directive
const SourceLocation Point
const NamedDecl * getNamedDeclAt(const ASTContext &Context, const SourceLocation Point)
std::string getUSRForDecl(const Decl *Decl)
Methods for determining the USR of a symbol at a location in source code.
const SourceManager & SourceMgr
ClangTidyContext & Context