Coverage Report

Created: 2017-10-03 07:32

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