Coverage Report

Created: 2019-07-24 05:18

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