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/AST/DeclBase.h" 22206084Srdivacky#include "clang/AST/DeclContextInternals.h" 23207619Srdivacky#include "clang/AST/Type.h" 24249423Sdim#include "clang/Basic/PartialDiagnostic.h" 25249423Sdim#include "clang/Basic/SourceLocation.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 111249423Sdim struct { 112249423Sdim unsigned Loc; 113249423Sdim unsigned Access : 2; 114249423Sdim unsigned IsMember : 1; 115249423Sdim NamedDecl *TargetDecl; 116249423Sdim CXXRecordDecl *NamingClass; 117249423Sdim void *BaseObjectType; 118249423Sdim } AccessData; 119206084Srdivacky}; 120206084Srdivacky 121206084Srdivacky/// 122206084Srdivacky 123206084Srdivacky/// An iterator over the dependent diagnostics in a dependent context. 124206084Srdivackyclass DeclContext::ddiag_iterator { 125206084Srdivackypublic: 126206084Srdivacky ddiag_iterator() : Ptr(0) {} 127206084Srdivacky explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {} 128206084Srdivacky 129206084Srdivacky typedef DependentDiagnostic *value_type; 130206084Srdivacky typedef DependentDiagnostic *reference; 131206084Srdivacky typedef DependentDiagnostic *pointer; 132206084Srdivacky typedef int difference_type; 133206084Srdivacky typedef std::forward_iterator_tag iterator_category; 134206084Srdivacky 135206084Srdivacky reference operator*() const { return Ptr; } 136206084Srdivacky 137206084Srdivacky ddiag_iterator &operator++() { 138206084Srdivacky assert(Ptr && "attempt to increment past end of diag list"); 139206084Srdivacky Ptr = Ptr->NextDiagnostic; 140206084Srdivacky return *this; 141206084Srdivacky } 142206084Srdivacky 143206084Srdivacky ddiag_iterator operator++(int) { 144206084Srdivacky ddiag_iterator tmp = *this; 145206084Srdivacky ++*this; 146206084Srdivacky return tmp; 147206084Srdivacky } 148206084Srdivacky 149206084Srdivacky bool operator==(ddiag_iterator Other) const { 150206084Srdivacky return Ptr == Other.Ptr; 151206084Srdivacky } 152206084Srdivacky 153206084Srdivacky bool operator!=(ddiag_iterator Other) const { 154206084Srdivacky return Ptr != Other.Ptr; 155206084Srdivacky } 156206084Srdivacky 157206084Srdivacky ddiag_iterator &operator+=(difference_type N) { 158206084Srdivacky assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator"); 159206084Srdivacky while (N--) 160206084Srdivacky ++*this; 161206084Srdivacky return *this; 162206084Srdivacky } 163206084Srdivacky 164206084Srdivacky ddiag_iterator operator+(difference_type N) const { 165206084Srdivacky ddiag_iterator tmp = *this; 166206084Srdivacky tmp += N; 167206084Srdivacky return tmp; 168206084Srdivacky } 169206084Srdivacky 170206084Srdivackyprivate: 171206084Srdivacky DependentDiagnostic *Ptr; 172206084Srdivacky}; 173206084Srdivacky 174206084Srdivackyinline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const { 175206084Srdivacky assert(isDependentContext() 176206084Srdivacky && "cannot iterate dependent diagnostics of non-dependent context"); 177206084Srdivacky const DependentStoredDeclsMap *Map 178234353Sdim = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr()); 179206084Srdivacky 180206084Srdivacky if (!Map) return ddiag_iterator(); 181206084Srdivacky return ddiag_iterator(Map->FirstDiagnostic); 182206084Srdivacky} 183206084Srdivacky 184206084Srdivackyinline DeclContext::ddiag_iterator DeclContext::ddiag_end() const { 185206084Srdivacky return ddiag_iterator(); 186206084Srdivacky} 187206084Srdivacky 188206084Srdivacky} 189206084Srdivacky 190206084Srdivacky#endif 191