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