10c01d18094100db92d38daa923c95661512db203John McCall//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
20c01d18094100db92d38daa923c95661512db203John McCall//
30c01d18094100db92d38daa923c95661512db203John McCall//                     The LLVM Compiler Infrastructure
40c01d18094100db92d38daa923c95661512db203John McCall//
50c01d18094100db92d38daa923c95661512db203John McCall// This file is distributed under the University of Illinois Open Source
60c01d18094100db92d38daa923c95661512db203John McCall// License. See LICENSE.TXT for details.
70c01d18094100db92d38daa923c95661512db203John McCall//
80c01d18094100db92d38daa923c95661512db203John McCall//===----------------------------------------------------------------------===//
90c01d18094100db92d38daa923c95661512db203John McCall//
100c01d18094100db92d38daa923c95661512db203John McCall//  This file defines interfaces for diagnostics which may or may
110c01d18094100db92d38daa923c95661512db203John McCall//  fire based on how a template is instantiated.
120c01d18094100db92d38daa923c95661512db203John McCall//
130c01d18094100db92d38daa923c95661512db203John McCall//  At the moment, the only consumer of this interface is access
140c01d18094100db92d38daa923c95661512db203John McCall//  control.
150c01d18094100db92d38daa923c95661512db203John McCall//
160c01d18094100db92d38daa923c95661512db203John McCall//===----------------------------------------------------------------------===//
170c01d18094100db92d38daa923c95661512db203John McCall
180c01d18094100db92d38daa923c95661512db203John McCall#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
190c01d18094100db92d38daa923c95661512db203John McCall#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
200c01d18094100db92d38daa923c95661512db203John McCall
210c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DeclBase.h"
220c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DeclContextInternals.h"
23161755a09898c95d21bfff33707da9ca41cd53c5John McCall#include "clang/AST/Type.h"
2430a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Basic/PartialDiagnostic.h"
2530a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Basic/SourceLocation.h"
260c01d18094100db92d38daa923c95661512db203John McCall
270c01d18094100db92d38daa923c95661512db203John McCallnamespace clang {
280c01d18094100db92d38daa923c95661512db203John McCall
290c01d18094100db92d38daa923c95661512db203John McCallclass ASTContext;
300c01d18094100db92d38daa923c95661512db203John McCallclass CXXRecordDecl;
310c01d18094100db92d38daa923c95661512db203John McCallclass NamedDecl;
320c01d18094100db92d38daa923c95661512db203John McCall
330c01d18094100db92d38daa923c95661512db203John McCall/// A dependently-generated diagnostic.
340c01d18094100db92d38daa923c95661512db203John McCallclass DependentDiagnostic {
350c01d18094100db92d38daa923c95661512db203John McCallpublic:
360c01d18094100db92d38daa923c95661512db203John McCall  enum AccessNonce { Access = 0 };
370c01d18094100db92d38daa923c95661512db203John McCall
380c01d18094100db92d38daa923c95661512db203John McCall  static DependentDiagnostic *Create(ASTContext &Context,
390c01d18094100db92d38daa923c95661512db203John McCall                                     DeclContext *Parent,
400c01d18094100db92d38daa923c95661512db203John McCall                                     AccessNonce _,
410c01d18094100db92d38daa923c95661512db203John McCall                                     SourceLocation Loc,
420c01d18094100db92d38daa923c95661512db203John McCall                                     bool IsMemberAccess,
430c01d18094100db92d38daa923c95661512db203John McCall                                     AccessSpecifier AS,
440c01d18094100db92d38daa923c95661512db203John McCall                                     NamedDecl *TargetDecl,
450c01d18094100db92d38daa923c95661512db203John McCall                                     CXXRecordDecl *NamingClass,
46161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                     QualType BaseObjectType,
470c01d18094100db92d38daa923c95661512db203John McCall                                     const PartialDiagnostic &PDiag) {
480c01d18094100db92d38daa923c95661512db203John McCall    DependentDiagnostic *DD = Create(Context, Parent, PDiag);
490c01d18094100db92d38daa923c95661512db203John McCall    DD->AccessData.Loc = Loc.getRawEncoding();
500c01d18094100db92d38daa923c95661512db203John McCall    DD->AccessData.IsMember = IsMemberAccess;
510c01d18094100db92d38daa923c95661512db203John McCall    DD->AccessData.Access = AS;
520c01d18094100db92d38daa923c95661512db203John McCall    DD->AccessData.TargetDecl = TargetDecl;
530c01d18094100db92d38daa923c95661512db203John McCall    DD->AccessData.NamingClass = NamingClass;
54161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
550c01d18094100db92d38daa923c95661512db203John McCall    return DD;
560c01d18094100db92d38daa923c95661512db203John McCall  }
570c01d18094100db92d38daa923c95661512db203John McCall
580c01d18094100db92d38daa923c95661512db203John McCall  unsigned getKind() const {
590c01d18094100db92d38daa923c95661512db203John McCall    return Access;
600c01d18094100db92d38daa923c95661512db203John McCall  }
610c01d18094100db92d38daa923c95661512db203John McCall
620c01d18094100db92d38daa923c95661512db203John McCall  bool isAccessToMember() const {
630c01d18094100db92d38daa923c95661512db203John McCall    assert(getKind() == Access);
640c01d18094100db92d38daa923c95661512db203John McCall    return AccessData.IsMember;
650c01d18094100db92d38daa923c95661512db203John McCall  }
660c01d18094100db92d38daa923c95661512db203John McCall
670c01d18094100db92d38daa923c95661512db203John McCall  AccessSpecifier getAccess() const {
680c01d18094100db92d38daa923c95661512db203John McCall    assert(getKind() == Access);
690c01d18094100db92d38daa923c95661512db203John McCall    return AccessSpecifier(AccessData.Access);
700c01d18094100db92d38daa923c95661512db203John McCall  }
710c01d18094100db92d38daa923c95661512db203John McCall
720c01d18094100db92d38daa923c95661512db203John McCall  SourceLocation getAccessLoc() const {
730c01d18094100db92d38daa923c95661512db203John McCall    assert(getKind() == Access);
740c01d18094100db92d38daa923c95661512db203John McCall    return SourceLocation::getFromRawEncoding(AccessData.Loc);
750c01d18094100db92d38daa923c95661512db203John McCall  }
760c01d18094100db92d38daa923c95661512db203John McCall
770c01d18094100db92d38daa923c95661512db203John McCall  NamedDecl *getAccessTarget() const {
780c01d18094100db92d38daa923c95661512db203John McCall    assert(getKind() == Access);
790c01d18094100db92d38daa923c95661512db203John McCall    return AccessData.TargetDecl;
800c01d18094100db92d38daa923c95661512db203John McCall  }
810c01d18094100db92d38daa923c95661512db203John McCall
820c01d18094100db92d38daa923c95661512db203John McCall  NamedDecl *getAccessNamingClass() const {
830c01d18094100db92d38daa923c95661512db203John McCall    assert(getKind() == Access);
840c01d18094100db92d38daa923c95661512db203John McCall    return AccessData.NamingClass;
850c01d18094100db92d38daa923c95661512db203John McCall  }
860c01d18094100db92d38daa923c95661512db203John McCall
87161755a09898c95d21bfff33707da9ca41cd53c5John McCall  QualType getAccessBaseObjectType() const {
88161755a09898c95d21bfff33707da9ca41cd53c5John McCall    assert(getKind() == Access);
89161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
90161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
91161755a09898c95d21bfff33707da9ca41cd53c5John McCall
920c01d18094100db92d38daa923c95661512db203John McCall  const PartialDiagnostic &getDiagnostic() const {
930c01d18094100db92d38daa923c95661512db203John McCall    return Diag;
940c01d18094100db92d38daa923c95661512db203John McCall  }
950c01d18094100db92d38daa923c95661512db203John McCall
960c01d18094100db92d38daa923c95661512db203John McCallprivate:
97b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor  DependentDiagnostic(const PartialDiagnostic &PDiag,
98b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor                      PartialDiagnostic::Storage *Storage)
99b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor    : Diag(PDiag, Storage) {}
100b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor
1010c01d18094100db92d38daa923c95661512db203John McCall  static DependentDiagnostic *Create(ASTContext &Context,
1020c01d18094100db92d38daa923c95661512db203John McCall                                     DeclContext *Parent,
1030c01d18094100db92d38daa923c95661512db203John McCall                                     const PartialDiagnostic &PDiag);
1040c01d18094100db92d38daa923c95661512db203John McCall
1050c01d18094100db92d38daa923c95661512db203John McCall  friend class DependentStoredDeclsMap;
1060c01d18094100db92d38daa923c95661512db203John McCall  friend class DeclContext::ddiag_iterator;
1070c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic *NextDiagnostic;
1080c01d18094100db92d38daa923c95661512db203John McCall
1090c01d18094100db92d38daa923c95661512db203John McCall  PartialDiagnostic Diag;
1100c01d18094100db92d38daa923c95661512db203John McCall
111e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct {
112e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned Loc;
113e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned Access : 2;
114e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned IsMember : 1;
115e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    NamedDecl *TargetDecl;
116e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    CXXRecordDecl *NamingClass;
117e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    void *BaseObjectType;
118e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  } AccessData;
1190c01d18094100db92d38daa923c95661512db203John McCall};
1200c01d18094100db92d38daa923c95661512db203John McCall
1210c01d18094100db92d38daa923c95661512db203John McCall///
1220c01d18094100db92d38daa923c95661512db203John McCall
1230c01d18094100db92d38daa923c95661512db203John McCall/// An iterator over the dependent diagnostics in a dependent context.
1240c01d18094100db92d38daa923c95661512db203John McCallclass DeclContext::ddiag_iterator {
1250c01d18094100db92d38daa923c95661512db203John McCallpublic:
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ddiag_iterator() : Ptr(nullptr) {}
1270c01d18094100db92d38daa923c95661512db203John McCall  explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
1280c01d18094100db92d38daa923c95661512db203John McCall
1290c01d18094100db92d38daa923c95661512db203John McCall  typedef DependentDiagnostic *value_type;
1300c01d18094100db92d38daa923c95661512db203John McCall  typedef DependentDiagnostic *reference;
1310c01d18094100db92d38daa923c95661512db203John McCall  typedef DependentDiagnostic *pointer;
1320c01d18094100db92d38daa923c95661512db203John McCall  typedef int difference_type;
1330c01d18094100db92d38daa923c95661512db203John McCall  typedef std::forward_iterator_tag iterator_category;
1340c01d18094100db92d38daa923c95661512db203John McCall
1350c01d18094100db92d38daa923c95661512db203John McCall  reference operator*() const { return Ptr; }
1360c01d18094100db92d38daa923c95661512db203John McCall
1370c01d18094100db92d38daa923c95661512db203John McCall  ddiag_iterator &operator++() {
1380c01d18094100db92d38daa923c95661512db203John McCall    assert(Ptr && "attempt to increment past end of diag list");
1390c01d18094100db92d38daa923c95661512db203John McCall    Ptr = Ptr->NextDiagnostic;
1400c01d18094100db92d38daa923c95661512db203John McCall    return *this;
1410c01d18094100db92d38daa923c95661512db203John McCall  }
1420c01d18094100db92d38daa923c95661512db203John McCall
1430c01d18094100db92d38daa923c95661512db203John McCall  ddiag_iterator operator++(int) {
1440c01d18094100db92d38daa923c95661512db203John McCall    ddiag_iterator tmp = *this;
1450c01d18094100db92d38daa923c95661512db203John McCall    ++*this;
1460c01d18094100db92d38daa923c95661512db203John McCall    return tmp;
1470c01d18094100db92d38daa923c95661512db203John McCall  }
1480c01d18094100db92d38daa923c95661512db203John McCall
1490c01d18094100db92d38daa923c95661512db203John McCall  bool operator==(ddiag_iterator Other) const {
1500c01d18094100db92d38daa923c95661512db203John McCall    return Ptr == Other.Ptr;
1510c01d18094100db92d38daa923c95661512db203John McCall  }
1520c01d18094100db92d38daa923c95661512db203John McCall
1530c01d18094100db92d38daa923c95661512db203John McCall  bool operator!=(ddiag_iterator Other) const {
1540c01d18094100db92d38daa923c95661512db203John McCall    return Ptr != Other.Ptr;
1550c01d18094100db92d38daa923c95661512db203John McCall  }
1560c01d18094100db92d38daa923c95661512db203John McCall
1570c01d18094100db92d38daa923c95661512db203John McCall  ddiag_iterator &operator+=(difference_type N) {
1580c01d18094100db92d38daa923c95661512db203John McCall    assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
1590c01d18094100db92d38daa923c95661512db203John McCall    while (N--)
1600c01d18094100db92d38daa923c95661512db203John McCall      ++*this;
1610c01d18094100db92d38daa923c95661512db203John McCall    return *this;
1620c01d18094100db92d38daa923c95661512db203John McCall  }
1630c01d18094100db92d38daa923c95661512db203John McCall
1640c01d18094100db92d38daa923c95661512db203John McCall  ddiag_iterator operator+(difference_type N) const {
1650c01d18094100db92d38daa923c95661512db203John McCall    ddiag_iterator tmp = *this;
1660c01d18094100db92d38daa923c95661512db203John McCall    tmp += N;
1670c01d18094100db92d38daa923c95661512db203John McCall    return tmp;
1680c01d18094100db92d38daa923c95661512db203John McCall  }
1690c01d18094100db92d38daa923c95661512db203John McCall
1700c01d18094100db92d38daa923c95661512db203John McCallprivate:
1710c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic *Ptr;
1720c01d18094100db92d38daa923c95661512db203John McCall};
1730c01d18094100db92d38daa923c95661512db203John McCall
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline DeclContext::ddiag_range DeclContext::ddiags() const {
1750c01d18094100db92d38daa923c95661512db203John McCall  assert(isDependentContext()
1760c01d18094100db92d38daa923c95661512db203John McCall         && "cannot iterate dependent diagnostics of non-dependent context");
1770c01d18094100db92d38daa923c95661512db203John McCall  const DependentStoredDeclsMap *Map
178c5d3e80c64af9604ad798282cc6861f9cd2afc52Richard Smith    = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
1790c01d18094100db92d38daa923c95661512db203John McCall
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!Map)
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return ddiag_range();
1820c01d18094100db92d38daa923c95661512db203John McCall
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
1840c01d18094100db92d38daa923c95661512db203John McCall}
1850c01d18094100db92d38daa923c95661512db203John McCall
1860c01d18094100db92d38daa923c95661512db203John McCall}
1870c01d18094100db92d38daa923c95661512db203John McCall
1880c01d18094100db92d38daa923c95661512db203John McCall#endif
189