DependentDiagnostic.h revision 207619
1206084Srdivacky//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
2206084Srdivacky//
3206084Srdivacky//                     The LLVM Compiler Infrastructure
4206084Srdivacky//
5206084Srdivacky// This file is distributed under the University of Illinois Open Source
6206084Srdivacky// License. See LICENSE.TXT for details.
7206084Srdivacky//
8206084Srdivacky//===----------------------------------------------------------------------===//
9206084Srdivacky//
10206084Srdivacky//  This file defines interfaces for diagnostics which may or may
11206084Srdivacky//  fire based on how a template is instantiated.
12206084Srdivacky//
13206084Srdivacky//  At the moment, the only consumer of this interface is access
14206084Srdivacky//  control.
15206084Srdivacky//
16206084Srdivacky//===----------------------------------------------------------------------===//
17206084Srdivacky
18206084Srdivacky#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
19206084Srdivacky#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
20206084Srdivacky
21206084Srdivacky#include "clang/Basic/PartialDiagnostic.h"
22206084Srdivacky#include "clang/Basic/SourceLocation.h"
23206084Srdivacky#include "clang/AST/DeclBase.h"
24206084Srdivacky#include "clang/AST/DeclContextInternals.h"
25207619Srdivacky#include "clang/AST/Type.h"
26206084Srdivacky
27206084Srdivackynamespace clang {
28206084Srdivacky
29206084Srdivackyclass ASTContext;
30206084Srdivackyclass CXXRecordDecl;
31206084Srdivackyclass NamedDecl;
32206084Srdivacky
33206084Srdivacky/// A dependently-generated diagnostic.
34206084Srdivackyclass DependentDiagnostic {
35206084Srdivackypublic:
36206084Srdivacky  enum AccessNonce { Access = 0 };
37206084Srdivacky
38206084Srdivacky  static DependentDiagnostic *Create(ASTContext &Context,
39206084Srdivacky                                     DeclContext *Parent,
40206084Srdivacky                                     AccessNonce _,
41206084Srdivacky                                     SourceLocation Loc,
42206084Srdivacky                                     bool IsMemberAccess,
43206084Srdivacky                                     AccessSpecifier AS,
44206084Srdivacky                                     NamedDecl *TargetDecl,
45206084Srdivacky                                     CXXRecordDecl *NamingClass,
46207619Srdivacky                                     QualType BaseObjectType,
47206084Srdivacky                                     const PartialDiagnostic &PDiag) {
48206084Srdivacky    DependentDiagnostic *DD = Create(Context, Parent, PDiag);
49206084Srdivacky    DD->AccessData.Loc = Loc.getRawEncoding();
50206084Srdivacky    DD->AccessData.IsMember = IsMemberAccess;
51206084Srdivacky    DD->AccessData.Access = AS;
52206084Srdivacky    DD->AccessData.TargetDecl = TargetDecl;
53206084Srdivacky    DD->AccessData.NamingClass = NamingClass;
54207619Srdivacky    DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
55206084Srdivacky    return DD;
56206084Srdivacky  }
57206084Srdivacky
58206084Srdivacky  unsigned getKind() const {
59206084Srdivacky    return Access;
60206084Srdivacky  }
61206084Srdivacky
62206084Srdivacky  bool isAccessToMember() const {
63206084Srdivacky    assert(getKind() == Access);
64206084Srdivacky    return AccessData.IsMember;
65206084Srdivacky  }
66206084Srdivacky
67206084Srdivacky  AccessSpecifier getAccess() const {
68206084Srdivacky    assert(getKind() == Access);
69206084Srdivacky    return AccessSpecifier(AccessData.Access);
70206084Srdivacky  }
71206084Srdivacky
72206084Srdivacky  SourceLocation getAccessLoc() const {
73206084Srdivacky    assert(getKind() == Access);
74206084Srdivacky    return SourceLocation::getFromRawEncoding(AccessData.Loc);
75206084Srdivacky  }
76206084Srdivacky
77206084Srdivacky  NamedDecl *getAccessTarget() const {
78206084Srdivacky    assert(getKind() == Access);
79206084Srdivacky    return AccessData.TargetDecl;
80206084Srdivacky  }
81206084Srdivacky
82206084Srdivacky  NamedDecl *getAccessNamingClass() const {
83206084Srdivacky    assert(getKind() == Access);
84206084Srdivacky    return AccessData.NamingClass;
85206084Srdivacky  }
86206084Srdivacky
87207619Srdivacky  QualType getAccessBaseObjectType() const {
88207619Srdivacky    assert(getKind() == Access);
89207619Srdivacky    return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
90207619Srdivacky  }
91207619Srdivacky
92206084Srdivacky  const PartialDiagnostic &getDiagnostic() const {
93206084Srdivacky    return Diag;
94206084Srdivacky  }
95206084Srdivacky
96206084Srdivackyprivate:
97206084Srdivacky  DependentDiagnostic(const PartialDiagnostic &PDiag,
98206084Srdivacky                      PartialDiagnostic::Storage *Storage)
99206084Srdivacky    : Diag(PDiag, Storage) {}
100206084Srdivacky
101206084Srdivacky  static DependentDiagnostic *Create(ASTContext &Context,
102206084Srdivacky                                     DeclContext *Parent,
103206084Srdivacky                                     const PartialDiagnostic &PDiag);
104206084Srdivacky
105206084Srdivacky  friend class DependentStoredDeclsMap;
106206084Srdivacky  friend class DeclContext::ddiag_iterator;
107206084Srdivacky  DependentDiagnostic *NextDiagnostic;
108206084Srdivacky
109206084Srdivacky  PartialDiagnostic Diag;
110206084Srdivacky
111206084Srdivacky  union {
112206084Srdivacky    struct {
113206084Srdivacky      unsigned Loc;
114206084Srdivacky      unsigned Access : 2;
115206084Srdivacky      unsigned IsMember : 1;
116206084Srdivacky      NamedDecl *TargetDecl;
117206084Srdivacky      CXXRecordDecl *NamingClass;
118207619Srdivacky      void *BaseObjectType;
119206084Srdivacky    } AccessData;
120206084Srdivacky  };
121206084Srdivacky};
122206084Srdivacky
123206084Srdivacky///
124206084Srdivacky
125206084Srdivacky/// An iterator over the dependent diagnostics in a dependent context.
126206084Srdivackyclass DeclContext::ddiag_iterator {
127206084Srdivackypublic:
128206084Srdivacky  ddiag_iterator() : Ptr(0) {}
129206084Srdivacky  explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
130206084Srdivacky
131206084Srdivacky  typedef DependentDiagnostic *value_type;
132206084Srdivacky  typedef DependentDiagnostic *reference;
133206084Srdivacky  typedef DependentDiagnostic *pointer;
134206084Srdivacky  typedef int difference_type;
135206084Srdivacky  typedef std::forward_iterator_tag iterator_category;
136206084Srdivacky
137206084Srdivacky  reference operator*() const { return Ptr; }
138206084Srdivacky
139206084Srdivacky  ddiag_iterator &operator++() {
140206084Srdivacky    assert(Ptr && "attempt to increment past end of diag list");
141206084Srdivacky    Ptr = Ptr->NextDiagnostic;
142206084Srdivacky    return *this;
143206084Srdivacky  }
144206084Srdivacky
145206084Srdivacky  ddiag_iterator operator++(int) {
146206084Srdivacky    ddiag_iterator tmp = *this;
147206084Srdivacky    ++*this;
148206084Srdivacky    return tmp;
149206084Srdivacky  }
150206084Srdivacky
151206084Srdivacky  bool operator==(ddiag_iterator Other) const {
152206084Srdivacky    return Ptr == Other.Ptr;
153206084Srdivacky  }
154206084Srdivacky
155206084Srdivacky  bool operator!=(ddiag_iterator Other) const {
156206084Srdivacky    return Ptr != Other.Ptr;
157206084Srdivacky  }
158206084Srdivacky
159206084Srdivacky  ddiag_iterator &operator+=(difference_type N) {
160206084Srdivacky    assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
161206084Srdivacky    while (N--)
162206084Srdivacky      ++*this;
163206084Srdivacky    return *this;
164206084Srdivacky  }
165206084Srdivacky
166206084Srdivacky  ddiag_iterator operator+(difference_type N) const {
167206084Srdivacky    ddiag_iterator tmp = *this;
168206084Srdivacky    tmp += N;
169206084Srdivacky    return tmp;
170206084Srdivacky  }
171206084Srdivacky
172206084Srdivackyprivate:
173206084Srdivacky  DependentDiagnostic *Ptr;
174206084Srdivacky};
175206084Srdivacky
176206084Srdivackyinline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
177206084Srdivacky  assert(isDependentContext()
178206084Srdivacky         && "cannot iterate dependent diagnostics of non-dependent context");
179206084Srdivacky  const DependentStoredDeclsMap *Map
180206084Srdivacky    = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->LookupPtr);
181206084Srdivacky
182206084Srdivacky  if (!Map) return ddiag_iterator();
183206084Srdivacky  return ddiag_iterator(Map->FirstDiagnostic);
184206084Srdivacky}
185206084Srdivacky
186206084Srdivackyinline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
187206084Srdivacky  return ddiag_iterator();
188206084Srdivacky}
189206084Srdivacky
190206084Srdivacky}
191206084Srdivacky
192206084Srdivacky#endif
193