Coverage Report

Created: 2021-01-19 06:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
Line
Count
Source (jump to first uncovered line)
1
//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===//
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
/// \file
10
/// A wrapper class around \c RecursiveASTVisitor that visits each
11
/// occurrences of a named symbol.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
16
#define LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
17
18
#include "clang/AST/AST.h"
19
#include "clang/AST/RecursiveASTVisitor.h"
20
#include "clang/Lex/Lexer.h"
21
22
namespace clang {
23
namespace tooling {
24
25
/// Traverses the AST and visits the occurrence of each named symbol in the
26
/// given nodes.
27
template <typename T>
28
class RecursiveSymbolVisitor
29
    : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
30
  using BaseType = RecursiveASTVisitor<RecursiveSymbolVisitor<T>>;
31
32
public:
33
  RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
34
168
      : SM(SM), LangOpts(LangOpts) {}
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::RecursiveSymbolVisitor(clang::SourceManager const&, clang::LangOptions const&)
Line
Count
Source
34
84
      : SM(SM), LangOpts(LangOpts) {}
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::RecursiveSymbolVisitor(clang::SourceManager const&, clang::LangOptions const&)
Line
Count
Source
34
84
      : SM(SM), LangOpts(LangOpts) {}
35
36
  bool visitSymbolOccurrence(const NamedDecl *ND,
37
                             ArrayRef<SourceRange> NameRanges) {
38
    return true;
39
  }
40
41
  // Declaration visitors:
42
43
864
  bool VisitNamedDecl(const NamedDecl *D) {
44
861
    return isa<CXXConversionDecl>(D) ? 
true3
: visit(D, D->getLocation());
45
864
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitNamedDecl(clang::NamedDecl const*)
Line
Count
Source
43
183
  bool VisitNamedDecl(const NamedDecl *D) {
44
182
    return isa<CXXConversionDecl>(D) ? 
true1
: visit(D, D->getLocation());
45
183
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitNamedDecl(clang::NamedDecl const*)
Line
Count
Source
43
681
  bool VisitNamedDecl(const NamedDecl *D) {
44
679
    return isa<CXXConversionDecl>(D) ? 
true2
: visit(D, D->getLocation());
45
681
  }
46
47
25
  bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
48
20
    for (const auto *Initializer : CD->inits()) {
49
      // Ignore implicit initializers.
50
20
      if (!Initializer->isWritten())
51
7
        continue;
52
13
      if (const FieldDecl *FD = Initializer->getMember()) {
53
13
        if (!visit(FD, Initializer->getSourceLocation(),
54
13
                   Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
55
13
                                              0, SM, LangOpts)))
56
2
          return false;
57
13
      }
58
13
    }
59
23
    return true;
60
25
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitCXXConstructorDecl(clang::CXXConstructorDecl const*)
Line
Count
Source
47
2
  bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
48
2
    for (const auto *Initializer : CD->inits()) {
49
      // Ignore implicit initializers.
50
2
      if (!Initializer->isWritten())
51
0
        continue;
52
2
      if (const FieldDecl *FD = Initializer->getMember()) {
53
2
        if (!visit(FD, Initializer->getSourceLocation(),
54
2
                   Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
55
2
                                              0, SM, LangOpts)))
56
2
          return false;
57
2
      }
58
2
    }
59
0
    return true;
60
2
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitCXXConstructorDecl(clang::CXXConstructorDecl const*)
Line
Count
Source
47
23
  bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
48
18
    for (const auto *Initializer : CD->inits()) {
49
      // Ignore implicit initializers.
50
18
      if (!Initializer->isWritten())
51
7
        continue;
52
11
      if (const FieldDecl *FD = Initializer->getMember()) {
53
11
        if (!visit(FD, Initializer->getSourceLocation(),
54
11
                   Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
55
11
                                              0, SM, LangOpts)))
56
0
          return false;
57
11
      }
58
11
    }
59
23
    return true;
60
23
  }
61
62
  // Expression visitors:
63
64
389
  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
65
389
    return visit(Expr->getFoundDecl(), Expr->getLocation());
66
389
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitDeclRefExpr(clang::DeclRefExpr const*)
Line
Count
Source
64
86
  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
65
86
    return visit(Expr->getFoundDecl(), Expr->getLocation());
66
86
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitDeclRefExpr(clang::DeclRefExpr const*)
Line
Count
Source
64
303
  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
65
303
    return visit(Expr->getFoundDecl(), Expr->getLocation());
66
303
  }
67
68
149
  bool VisitMemberExpr(const MemberExpr *Expr) {
69
149
    return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
70
149
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitMemberExpr(clang::MemberExpr const*)
Line
Count
Source
68
27
  bool VisitMemberExpr(const MemberExpr *Expr) {
69
27
    return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
70
27
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitMemberExpr(clang::MemberExpr const*)
Line
Count
Source
68
122
  bool VisitMemberExpr(const MemberExpr *Expr) {
69
122
    return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
70
122
  }
71
72
20
  bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
73
60
    for (unsigned I = 0, E = S->getNumComponents(); I != E; 
++I40
) {
74
43
      const OffsetOfNode &Component = S->getComponent(I);
75
43
      if (Component.getKind() == OffsetOfNode::Field) {
76
26
        if (!visit(Component.getField(), Component.getEndLoc()))
77
3
          return false;
78
26
      }
79
      // FIXME: Try to resolve dependent field references.
80
43
    }
81
17
    return true;
82
20
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitOffsetOfExpr(clang::OffsetOfExpr const*)
Line
Count
Source
72
5
  bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
73
10
    for (unsigned I = 0, E = S->getNumComponents(); I != E; 
++I5
) {
74
8
      const OffsetOfNode &Component = S->getComponent(I);
75
8
      if (Component.getKind() == OffsetOfNode::Field) {
76
6
        if (!visit(Component.getField(), Component.getEndLoc()))
77
3
          return false;
78
6
      }
79
      // FIXME: Try to resolve dependent field references.
80
8
    }
81
2
    return true;
82
5
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitOffsetOfExpr(clang::OffsetOfExpr const*)
Line
Count
Source
72
15
  bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
73
50
    for (unsigned I = 0, E = S->getNumComponents(); I != E; 
++I35
) {
74
35
      const OffsetOfNode &Component = S->getComponent(I);
75
35
      if (Component.getKind() == OffsetOfNode::Field) {
76
20
        if (!visit(Component.getField(), Component.getEndLoc()))
77
0
          return false;
78
20
      }
79
      // FIXME: Try to resolve dependent field references.
80
35
    }
81
15
    return true;
82
15
  }
83
84
  // Other visitors:
85
86
1.25k
  bool VisitTypeLoc(const TypeLoc Loc) {
87
1.25k
    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88
1.25k
    const SourceLocation TypeEndLoc =
89
1.25k
        Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90
1.25k
    if (const auto *TemplateTypeParm =
91
82
            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92
82
      if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93
2
        return false;
94
1.24k
    }
95
1.24k
    if (const auto *TemplateSpecType =
96
44
            dyn_cast<TemplateSpecializationType>(Loc.getType())) {
97
44
      if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
98
44
                 TypeBeginLoc, TypeEndLoc))
99
2
        return false;
100
1.24k
    }
101
1.24k
    if (const Type *TP = Loc.getTypePtr()) {
102
1.24k
      if (TP->getTypeClass() == clang::Type::Record)
103
331
        return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104
916
    }
105
916
    return true;
106
916
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitTypeLoc(clang::TypeLoc)
Line
Count
Source
86
245
  bool VisitTypeLoc(const TypeLoc Loc) {
87
245
    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88
245
    const SourceLocation TypeEndLoc =
89
245
        Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90
245
    if (const auto *TemplateTypeParm =
91
11
            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92
11
      if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93
2
        return false;
94
243
    }
95
243
    if (const auto *TemplateSpecType =
96
12
            dyn_cast<TemplateSpecializationType>(Loc.getType())) {
97
12
      if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
98
12
                 TypeBeginLoc, TypeEndLoc))
99
2
        return false;
100
241
    }
101
241
    if (const Type *TP = Loc.getTypePtr()) {
102
241
      if (TP->getTypeClass() == clang::Type::Record)
103
82
        return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104
159
    }
105
159
    return true;
106
159
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitTypeLoc(clang::TypeLoc)
Line
Count
Source
86
1.00k
  bool VisitTypeLoc(const TypeLoc Loc) {
87
1.00k
    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88
1.00k
    const SourceLocation TypeEndLoc =
89
1.00k
        Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90
1.00k
    if (const auto *TemplateTypeParm =
91
71
            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92
71
      if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93
0
        return false;
94
1.00k
    }
95
1.00k
    if (const auto *TemplateSpecType =
96
32
            dyn_cast<TemplateSpecializationType>(Loc.getType())) {
97
32
      if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
98
32
                 TypeBeginLoc, TypeEndLoc))
99
0
        return false;
100
1.00k
    }
101
1.00k
    if (const Type *TP = Loc.getTypePtr()) {
102
1.00k
      if (TP->getTypeClass() == clang::Type::Record)
103
249
        return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104
757
    }
105
757
    return true;
106
757
  }
107
108
2
  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
109
2
    const SourceLocation TypeEndLoc =
110
2
        Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
111
2
    return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc);
112
2
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitTypedefTypeLoc(clang::TypedefTypeLoc)
Line
Count
Source
108
1
  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
109
1
    const SourceLocation TypeEndLoc =
110
1
        Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
111
1
    return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc);
112
1
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitTypedefTypeLoc(clang::TypedefTypeLoc)
Line
Count
Source
108
1
  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
109
1
    const SourceLocation TypeEndLoc =
110
1
        Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
111
1
    return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc);
112
1
  }
113
114
1.27k
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
115
    // The base visitor will visit NNSL prefixes, so we should only look at
116
    // the current NNS.
117
1.27k
    if (NNS) {
118
45
      const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
119
45
      if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
120
0
        return false;
121
1.27k
    }
122
1.27k
    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
123
1.27k
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)
Line
Count
Source
114
226
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
115
    // The base visitor will visit NNSL prefixes, so we should only look at
116
    // the current NNS.
117
226
    if (NNS) {
118
5
      const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
119
5
      if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
120
0
        return false;
121
226
    }
122
226
    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
123
226
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)
Line
Count
Source
114
1.04k
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
115
    // The base visitor will visit NNSL prefixes, so we should only look at
116
    // the current NNS.
117
1.04k
    if (NNS) {
118
40
      const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
119
40
      if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
120
0
        return false;
121
1.04k
    }
122
1.04k
    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
123
1.04k
  }
124
125
private:
126
  const SourceManager &SM;
127
  const LangOptions &LangOpts;
128
129
  bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
130
1.94k
             SourceLocation EndLoc) {
131
1.94k
    return static_cast<T *>(this)->visitSymbolOccurrence(
132
1.94k
        ND, SourceRange(BeginLoc, EndLoc));
133
1.94k
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation, clang::SourceLocation)
Line
Count
Source
130
414
             SourceLocation EndLoc) {
131
414
    return static_cast<T *>(this)->visitSymbolOccurrence(
132
414
        ND, SourceRange(BeginLoc, EndLoc));
133
414
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation, clang::SourceLocation)
Line
Count
Source
130
1.52k
             SourceLocation EndLoc) {
131
1.52k
    return static_cast<T *>(this)->visitSymbolOccurrence(
132
1.52k
        ND, SourceRange(BeginLoc, EndLoc));
133
1.52k
  }
134
1.42k
  bool visit(const NamedDecl *ND, SourceLocation Loc) {
135
1.42k
    return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
136
1.42k
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation)
Line
Count
Source
134
301
  bool visit(const NamedDecl *ND, SourceLocation Loc) {
135
301
    return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
136
301
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation)
Line
Count
Source
134
1.12k
  bool visit(const NamedDecl *ND, SourceLocation Loc) {
135
1.12k
    return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
136
1.12k
  }
137
};
138
139
} // end namespace tooling
140
} // end namespace clang
141
142
#endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H