19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/RecursiveASTVisitor.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Lex/Lexer.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Support/Casting.h"
41 class USRLocFindingASTVisitor
42 :
public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
44 explicit USRLocFindingASTVisitor(
const std::vector<std::string> &USRs,
47 :
USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
52 bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
53 for (
const auto *Initializer : ConstructorDecl->inits()) {
55 if (!Initializer->isWritten())
57 if (
const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
65 bool VisitNamedDecl(
const NamedDecl *Decl) {
67 checkAndAddLocation(Decl->getLocation());
73 bool VisitDeclRefExpr(
const DeclRefExpr *Expr) {
74 const NamedDecl *Decl = Expr->getFoundDecl();
77 const SourceManager &Manager = Decl->getASTContext().getSourceManager();
78 SourceLocation
Location = Manager.getSpellingLoc(Expr->getLocation());
79 checkAndAddLocation(Location);
85 bool VisitMemberExpr(
const MemberExpr *Expr) {
86 const NamedDecl *Decl = Expr->getFoundDecl().getDecl();
88 const SourceManager &Manager = Decl->getASTContext().getSourceManager();
89 SourceLocation
Location = Manager.getSpellingLoc(Expr->getMemberLoc());
90 checkAndAddLocation(Location);
97 bool VisitTypeLoc(
const TypeLoc
Loc) {
100 checkAndAddLocation(Loc.getBeginLoc());
101 if (
const auto *TemplateTypeParm =
102 dyn_cast<TemplateTypeParmType>(Loc.getType())) {
105 checkAndAddLocation(Loc.getBeginLoc());
114 const std::vector<clang::SourceLocation> &getLocationsFound()
const {
119 void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
121 const NamespaceDecl *Decl =
122 NameLoc.getNestedNameSpecifier()->getAsNamespace();
124 checkAndAddLocation(NameLoc.getLocalBeginLoc());
125 NameLoc = NameLoc.getPrefix();
130 void checkAndAddLocation(SourceLocation Loc) {
131 const SourceLocation BeginLoc =
Loc;
132 const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
134 StringRef TokenName =
135 Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
137 size_t Offset = TokenName.find(
PrevName);
141 if (Offset != StringRef::npos)
153 std::vector<SourceLocation>
156 USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
157 Visitor.TraverseDecl(Decl);
160 for (
const auto &
Location :
Finder.getNestedNameSpecifierLocations())
161 Visitor.handleNestedNameSpecifierLoc(
Location);
163 return Visitor.getLocationsFound();
SourceLocation Loc
'#' location in the include directive
std::unique_ptr< ast_matchers::MatchFinder > Finder
std::string getUSRForDecl(const Decl *Decl)
const ASTContext & Context
const std::set< std::string > USRSet
Methods for determining the USR of a symbol at a location in source code.
const std::string PrevName
Provides functionality for finding all instances of a USR in a given AST.
std::vector< clang::SourceLocation > LocationsFound
std::vector< SourceLocation > getLocationsOfUSRs(const std::vector< std::string > &USRs, StringRef PrevName, Decl *Decl)