Coverage Report

Created: 2020-02-25 14:32

/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
152
      : 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
76
      : 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
76
      : 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
789
  bool VisitNamedDecl(const NamedDecl *D) {
44
789
    return isa<CXXConversionDecl>(D) ? 
true3
:
visit(D, D->getLocation())786
;
45
789
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitNamedDecl(clang::NamedDecl const*)
Line
Count
Source
43
174
  bool VisitNamedDecl(const NamedDecl *D) {
44
174
    return isa<CXXConversionDecl>(D) ? 
true1
:
visit(D, D->getLocation())173
;
45
174
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitNamedDecl(clang::NamedDecl const*)
Line
Count
Source
43
615
  bool VisitNamedDecl(const NamedDecl *D) {
44
615
    return isa<CXXConversionDecl>(D) ? 
true2
:
visit(D, D->getLocation())613
;
45
615
  }
46
47
25
  bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
48
25
    for (const auto *Initializer : CD->inits()) {
49
20
      // 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
25
    
return true23
;
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
2
      // 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
2
    
return true0
;
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
23
    for (const auto *Initializer : CD->inits()) {
49
18
      // 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
372
  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
65
372
    return visit(Expr->getFoundDecl(), Expr->getLocation());
66
372
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitDeclRefExpr(clang::DeclRefExpr const*)
Line
Count
Source
64
82
  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
65
82
    return visit(Expr->getFoundDecl(), Expr->getLocation());
66
82
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitDeclRefExpr(clang::DeclRefExpr const*)
Line
Count
Source
64
290
  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
65
290
    return visit(Expr->getFoundDecl(), Expr->getLocation());
66
290
  }
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
43
      // FIXME: Try to resolve dependent field references.
80
43
    }
81
20
    
return true17
;
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
8
      // FIXME: Try to resolve dependent field references.
80
8
    }
81
5
    
return true2
;
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
35
      // FIXME: Try to resolve dependent field references.
80
35
    }
81
15
    return true;
82
15
  }
83
84
  // Other visitors:
85
86
1.17k
  bool VisitTypeLoc(const TypeLoc Loc) {
87
1.17k
    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88
1.17k
    const SourceLocation TypeEndLoc =
89
1.17k
        Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90
1.17k
    if (const auto *TemplateTypeParm =
91
74
            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92
74
      if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93
2
        return false;
94
1.17k
    }
95
1.17k
    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.17k
    }
101
1.17k
    if (const Type *TP = Loc.getTypePtr()) {
102
1.17k
      if (TP->getTypeClass() == clang::Type::Record)
103
331
        return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104
842
    }
105
842
    return true;
106
842
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::VisitTypeLoc(clang::TypeLoc)
Line
Count
Source
86
238
  bool VisitTypeLoc(const TypeLoc Loc) {
87
238
    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88
238
    const SourceLocation TypeEndLoc =
89
238
        Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90
238
    if (const auto *TemplateTypeParm =
91
11
            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92
11
      if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93
2
        return false;
94
236
    }
95
236
    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
234
    }
101
234
    if (const Type *TP = Loc.getTypePtr()) {
102
234
      if (TP->getTypeClass() == clang::Type::Record)
103
82
        return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104
152
    }
105
152
    return true;
106
152
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::VisitTypeLoc(clang::TypeLoc)
Line
Count
Source
86
939
  bool VisitTypeLoc(const TypeLoc Loc) {
87
939
    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
88
939
    const SourceLocation TypeEndLoc =
89
939
        Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
90
939
    if (const auto *TemplateTypeParm =
91
63
            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
92
63
      if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
93
0
        return false;
94
939
    }
95
939
    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
939
    }
101
939
    if (const Type *TP = Loc.getTypePtr()) {
102
939
      if (TP->getTypeClass() == clang::Type::Record)
103
249
        return visit(TP->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
104
690
    }
105
690
    return true;
106
690
  }
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.21k
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
115
1.21k
    // The base visitor will visit NNSL prefixes, so we should only look at
116
1.21k
    // the current NNS.
117
1.21k
    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.21k
    }
122
1.21k
    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
123
1.21k
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)
Line
Count
Source
114
222
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
115
222
    // The base visitor will visit NNSL prefixes, so we should only look at
116
222
    // the current NNS.
117
222
    if (NNS) {
118
5
      const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
119
5
      if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
120
0
        return false;
121
222
    }
122
222
    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
123
222
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc)
Line
Count
Source
114
989
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
115
989
    // The base visitor will visit NNSL prefixes, so we should only look at
116
989
    // the current NNS.
117
989
    if (NNS) {
118
40
      const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
119
40
      if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
120
0
        return false;
121
989
    }
122
989
    return BaseType::TraverseNestedNameSpecifierLoc(NNS);
123
989
  }
124
125
private:
126
  const SourceManager &SM;
127
  const LangOptions &LangOpts;
128
129
  bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
130
1.84k
             SourceLocation EndLoc) {
131
1.84k
    return static_cast<T *>(this)->visitSymbolOccurrence(
132
1.84k
        ND, SourceRange(BeginLoc, EndLoc));
133
1.84k
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation, clang::SourceLocation)
Line
Count
Source
130
401
             SourceLocation EndLoc) {
131
401
    return static_cast<T *>(this)->visitSymbolOccurrence(
132
401
        ND, SourceRange(BeginLoc, EndLoc));
133
401
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation, clang::SourceLocation)
Line
Count
Source
130
1.44k
             SourceLocation EndLoc) {
131
1.44k
    return static_cast<T *>(this)->visitSymbolOccurrence(
132
1.44k
        ND, SourceRange(BeginLoc, EndLoc));
133
1.44k
  }
134
1.33k
  bool visit(const NamedDecl *ND, SourceLocation Loc) {
135
1.33k
    return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
136
1.33k
  }
USRFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::NamedDeclOccurrenceFindingVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation)
Line
Count
Source
134
288
  bool visit(const NamedDecl *ND, SourceLocation Loc) {
135
288
    return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
136
288
  }
USRLocFinder.cpp:clang::tooling::RecursiveSymbolVisitor<clang::tooling::(anonymous namespace)::USRLocFindingASTVisitor>::visit(clang::NamedDecl const*, clang::SourceLocation)
Line
Count
Source
134
1.04k
  bool visit(const NamedDecl *ND, SourceLocation Loc) {
135
1.04k
    return visit(ND, Loc, Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts));
136
1.04k
  }
137
};
138
139
} // end namespace tooling
140
} // end namespace clang
141
142
#endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H