19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/RecursiveASTVisitor.h"
21 #include "clang/Basic/SourceLocation.h"
22 #include "clang/Index/USRGeneration.h"
23 #include "clang/Lex/Lexer.h"
24 #include "llvm/ADT/SmallVector.h"
34 class USRLocFindingASTVisitor
35 :
public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
37 explicit USRLocFindingASTVisitor(StringRef
USR, StringRef
PrevName)
38 : USR(USR), PrevName(PrevName) {}
42 bool VisitNamedDecl(
const NamedDecl *Decl) {
49 bool VisitVarDecl(clang::VarDecl *Decl) {
50 clang::QualType Type = Decl->getType();
51 const clang::RecordDecl *RecordDecl = Type->getPointeeCXXRecordDecl();
61 bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
62 const ASTContext &
Context = ConstructorDecl->getASTContext();
63 for (
auto &Initializer : ConstructorDecl->inits()) {
64 if (Initializer->getSourceOrder() == -1) {
69 if (
const clang::FieldDecl *FieldDecl = Initializer->getAnyMember()) {
72 SourceLocation
Location = Initializer->getSourceLocation();
73 StringRef TokenName = Lexer::getSourceText(
74 CharSourceRange::getTokenRange(Location),
75 Context.getSourceManager(), Context.getLangOpts());
92 bool VisitCXXDestructorDecl(clang::CXXDestructorDecl *DestructorDecl) {
95 SourceLocation Location = DestructorDecl->getLocation();
96 const ASTContext &Context = DestructorDecl->getASTContext();
97 StringRef LLVM_ATTRIBUTE_UNUSED TokenName = Lexer::getSourceText(
98 CharSourceRange::getTokenRange(Location), Context.getSourceManager(),
99 Context.getLangOpts());
102 assert(TokenName.startswith(
"~"));
105 if (DestructorDecl->isThisDeclarationADefinition()) {
116 bool VisitDeclRefExpr(
const DeclRefExpr *Expr) {
117 const auto *Decl = Expr->getFoundDecl();
119 checkNestedNameSpecifierLoc(Expr->getQualifierLoc());
121 const SourceManager &Manager = Decl->getASTContext().getSourceManager();
122 SourceLocation Location = Manager.getSpellingLoc(Expr->getLocation());
129 bool VisitMemberExpr(
const MemberExpr *Expr) {
130 const auto *Decl = Expr->getFoundDecl().getDecl();
132 const SourceManager &Manager = Decl->getASTContext().getSourceManager();
133 SourceLocation Location = Manager.getSpellingLoc(Expr->getMemberLoc());
139 bool VisitCXXConstructExpr(
const CXXConstructExpr *Expr) {
140 CXXConstructorDecl *Decl = Expr->getConstructor();
150 bool VisitCXXStaticCastExpr(clang::CXXStaticCastExpr *Expr) {
151 return handleCXXNamedCastExpr(Expr);
154 bool VisitCXXDynamicCastExpr(clang::CXXDynamicCastExpr *Expr) {
155 return handleCXXNamedCastExpr(Expr);
158 bool VisitCXXReinterpretCastExpr(clang::CXXReinterpretCastExpr *Expr) {
159 return handleCXXNamedCastExpr(Expr);
162 bool VisitCXXConstCastExpr(clang::CXXConstCastExpr *Expr) {
163 return handleCXXNamedCastExpr(Expr);
170 const std::vector<clang::SourceLocation> &getLocationsFound()
const {
176 void checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
178 const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
181 NameLoc = NameLoc.getPrefix();
185 bool handleCXXNamedCastExpr(clang::CXXNamedCastExpr *Expr) {
186 clang::QualType Type = Expr->getType();
188 const RecordDecl *Decl = Type->getPointeeCXXRecordDecl();
191 Decl = Type->getAsCXXRecordDecl();
195 SourceLocation Location =
196 Expr->getTypeInfoAsWritten()->getTypeLoc().getBeginLoc();
213 USRLocFindingASTVisitor Visitor(USR, PrevName);
215 Visitor.TraverseDecl(Decl);
216 return Visitor.getLocationsFound();
std::string getUSRForDecl(const Decl *Decl)
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 > getLocationsOfUSR(StringRef USR, StringRef PrevName, Decl *Decl)
ClangTidyContext & Context