Coverage Report

Created: 2018-09-25 23:22

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/AST/DependentDiagnostic.h
Line
Count
Source (jump to first uncovered line)
1
//==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
//  This file defines interfaces for diagnostics which may or may
11
//  fire based on how a template is instantiated.
12
//
13
//  At the moment, the only consumer of this interface is access
14
//  control.
15
//
16
//===----------------------------------------------------------------------===//
17
18
#ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
19
#define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
20
21
#include "clang/AST/DeclBase.h"
22
#include "clang/AST/DeclContextInternals.h"
23
#include "clang/AST/Type.h"
24
#include "clang/Basic/PartialDiagnostic.h"
25
#include "clang/Basic/SourceLocation.h"
26
#include "clang/Basic/Specifiers.h"
27
#include <cassert>
28
#include <iterator>
29
30
namespace clang {
31
32
class ASTContext;
33
class CXXRecordDecl;
34
class NamedDecl;
35
36
/// A dependently-generated diagnostic.
37
class DependentDiagnostic {
38
public:
39
  enum AccessNonce { Access = 0 };
40
41
  static DependentDiagnostic *Create(ASTContext &Context,
42
                                     DeclContext *Parent,
43
                                     AccessNonce _,
44
                                     SourceLocation Loc,
45
                                     bool IsMemberAccess,
46
                                     AccessSpecifier AS,
47
                                     NamedDecl *TargetDecl,
48
                                     CXXRecordDecl *NamingClass,
49
                                     QualType BaseObjectType,
50
43
                                     const PartialDiagnostic &PDiag) {
51
43
    DependentDiagnostic *DD = Create(Context, Parent, PDiag);
52
43
    DD->AccessData.Loc = Loc.getRawEncoding();
53
43
    DD->AccessData.IsMember = IsMemberAccess;
54
43
    DD->AccessData.Access = AS;
55
43
    DD->AccessData.TargetDecl = TargetDecl;
56
43
    DD->AccessData.NamingClass = NamingClass;
57
43
    DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
58
43
    return DD;
59
43
  }
60
61
62
  unsigned getKind() const {
62
62
    return Access;
63
62
  }
64
65
62
  bool isAccessToMember() const {
66
62
    assert(getKind() == Access);
67
62
    return AccessData.IsMember;
68
62
  }
69
70
62
  AccessSpecifier getAccess() const {
71
62
    assert(getKind() == Access);
72
62
    return AccessSpecifier(AccessData.Access);
73
62
  }
74
75
62
  SourceLocation getAccessLoc() const {
76
62
    assert(getKind() == Access);
77
62
    return SourceLocation::getFromRawEncoding(AccessData.Loc);
78
62
  }
79
80
62
  NamedDecl *getAccessTarget() const {
81
62
    assert(getKind() == Access);
82
62
    return AccessData.TargetDecl;
83
62
  }
84
85
62
  NamedDecl *getAccessNamingClass() const {
86
62
    assert(getKind() == Access);
87
62
    return AccessData.NamingClass;
88
62
  }
89
90
62
  QualType getAccessBaseObjectType() const {
91
62
    assert(getKind() == Access);
92
62
    return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
93
62
  }
94
95
62
  const PartialDiagnostic &getDiagnostic() const {
96
62
    return Diag;
97
62
  }
98
99
private:
100
  friend class DeclContext::ddiag_iterator;
101
  friend class DependentStoredDeclsMap;
102
103
  DependentDiagnostic(const PartialDiagnostic &PDiag,
104
                      PartialDiagnostic::Storage *Storage)
105
43
    : Diag(PDiag, Storage) {}
106
107
  static DependentDiagnostic *Create(ASTContext &Context,
108
                                     DeclContext *Parent,
109
                                     const PartialDiagnostic &PDiag);
110
111
  DependentDiagnostic *NextDiagnostic;
112
113
  PartialDiagnostic Diag;
114
115
  struct {
116
    unsigned Loc;
117
    unsigned Access : 2;
118
    unsigned IsMember : 1;
119
    NamedDecl *TargetDecl;
120
    CXXRecordDecl *NamingClass;
121
    void *BaseObjectType;
122
  } AccessData;
123
};
124
125
/// An iterator over the dependent diagnostics in a dependent context.
126
class DeclContext::ddiag_iterator {
127
public:
128
1.59M
  ddiag_iterator() = default;
129
992k
  explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
130
131
  using value_type = DependentDiagnostic *;
132
  using reference = DependentDiagnostic *;
133
  using pointer = DependentDiagnostic *;
134
  using difference_type = int;
135
  using iterator_category = std::forward_iterator_tag;
136
137
62
  reference operator*() const { return Ptr; }
138
139
62
  ddiag_iterator &operator++() {
140
62
    assert(Ptr && "attempt to increment past end of diag list");
141
62
    Ptr = Ptr->NextDiagnostic;
142
62
    return *this;
143
62
  }
144
145
0
  ddiag_iterator operator++(int) {
146
0
    ddiag_iterator tmp = *this;
147
0
    ++*this;
148
0
    return tmp;
149
0
  }
150
151
  bool operator==(ddiag_iterator Other) const {
152
    return Ptr == Other.Ptr;
153
  }
154
155
1.29M
  bool operator!=(ddiag_iterator Other) const {
156
1.29M
    return Ptr != Other.Ptr;
157
1.29M
  }
158
159
  ddiag_iterator &operator+=(difference_type N) {
160
    assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
161
    while (N--)
162
      ++*this;
163
    return *this;
164
  }
165
166
  ddiag_iterator operator+(difference_type N) const {
167
    ddiag_iterator tmp = *this;
168
    tmp += N;
169
    return tmp;
170
  }
171
172
private:
173
  DependentDiagnostic *Ptr = nullptr;
174
};
175
176
1.29M
inline DeclContext::ddiag_range DeclContext::ddiags() const {
177
1.29M
  assert(isDependentContext()
178
1.29M
         && "cannot iterate dependent diagnostics of non-dependent context");
179
1.29M
  const DependentStoredDeclsMap *Map
180
1.29M
    = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
181
1.29M
182
1.29M
  if (!Map)
183
301k
    // Return an empty range using the always-end default constructor.
184
301k
    return ddiag_range(ddiag_iterator(), ddiag_iterator());
185
992k
186
992k
  return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
187
992k
}
188
189
} // namespace clang
190
191
#endif // LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H