DependentDiagnostic.h revision b836518bfc0a2ad5e22a670c82fa070ed83ea909
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/Basic/PartialDiagnostic.h" 220c01d18094100db92d38daa923c95661512db203John McCall#include "clang/Basic/SourceLocation.h" 230c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DeclBase.h" 240c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DeclContextInternals.h" 250c01d18094100db92d38daa923c95661512db203John McCall 260c01d18094100db92d38daa923c95661512db203John McCallnamespace clang { 270c01d18094100db92d38daa923c95661512db203John McCall 280c01d18094100db92d38daa923c95661512db203John McCallclass ASTContext; 290c01d18094100db92d38daa923c95661512db203John McCallclass CXXRecordDecl; 300c01d18094100db92d38daa923c95661512db203John McCallclass NamedDecl; 310c01d18094100db92d38daa923c95661512db203John McCall 320c01d18094100db92d38daa923c95661512db203John McCall/// A dependently-generated diagnostic. 330c01d18094100db92d38daa923c95661512db203John McCallclass DependentDiagnostic { 340c01d18094100db92d38daa923c95661512db203John McCallpublic: 350c01d18094100db92d38daa923c95661512db203John McCall enum AccessNonce { Access = 0 }; 360c01d18094100db92d38daa923c95661512db203John McCall 370c01d18094100db92d38daa923c95661512db203John McCall static DependentDiagnostic *Create(ASTContext &Context, 380c01d18094100db92d38daa923c95661512db203John McCall DeclContext *Parent, 390c01d18094100db92d38daa923c95661512db203John McCall AccessNonce _, 400c01d18094100db92d38daa923c95661512db203John McCall SourceLocation Loc, 410c01d18094100db92d38daa923c95661512db203John McCall bool IsMemberAccess, 420c01d18094100db92d38daa923c95661512db203John McCall AccessSpecifier AS, 430c01d18094100db92d38daa923c95661512db203John McCall NamedDecl *TargetDecl, 440c01d18094100db92d38daa923c95661512db203John McCall CXXRecordDecl *NamingClass, 450c01d18094100db92d38daa923c95661512db203John McCall const PartialDiagnostic &PDiag) { 460c01d18094100db92d38daa923c95661512db203John McCall DependentDiagnostic *DD = Create(Context, Parent, PDiag); 470c01d18094100db92d38daa923c95661512db203John McCall DD->AccessData.Loc = Loc.getRawEncoding(); 480c01d18094100db92d38daa923c95661512db203John McCall DD->AccessData.IsMember = IsMemberAccess; 490c01d18094100db92d38daa923c95661512db203John McCall DD->AccessData.Access = AS; 500c01d18094100db92d38daa923c95661512db203John McCall DD->AccessData.TargetDecl = TargetDecl; 510c01d18094100db92d38daa923c95661512db203John McCall DD->AccessData.NamingClass = NamingClass; 520c01d18094100db92d38daa923c95661512db203John McCall return DD; 530c01d18094100db92d38daa923c95661512db203John McCall } 540c01d18094100db92d38daa923c95661512db203John McCall 550c01d18094100db92d38daa923c95661512db203John McCall unsigned getKind() const { 560c01d18094100db92d38daa923c95661512db203John McCall return Access; 570c01d18094100db92d38daa923c95661512db203John McCall } 580c01d18094100db92d38daa923c95661512db203John McCall 590c01d18094100db92d38daa923c95661512db203John McCall bool isAccessToMember() const { 600c01d18094100db92d38daa923c95661512db203John McCall assert(getKind() == Access); 610c01d18094100db92d38daa923c95661512db203John McCall return AccessData.IsMember; 620c01d18094100db92d38daa923c95661512db203John McCall } 630c01d18094100db92d38daa923c95661512db203John McCall 640c01d18094100db92d38daa923c95661512db203John McCall AccessSpecifier getAccess() const { 650c01d18094100db92d38daa923c95661512db203John McCall assert(getKind() == Access); 660c01d18094100db92d38daa923c95661512db203John McCall return AccessSpecifier(AccessData.Access); 670c01d18094100db92d38daa923c95661512db203John McCall } 680c01d18094100db92d38daa923c95661512db203John McCall 690c01d18094100db92d38daa923c95661512db203John McCall SourceLocation getAccessLoc() const { 700c01d18094100db92d38daa923c95661512db203John McCall assert(getKind() == Access); 710c01d18094100db92d38daa923c95661512db203John McCall return SourceLocation::getFromRawEncoding(AccessData.Loc); 720c01d18094100db92d38daa923c95661512db203John McCall } 730c01d18094100db92d38daa923c95661512db203John McCall 740c01d18094100db92d38daa923c95661512db203John McCall NamedDecl *getAccessTarget() const { 750c01d18094100db92d38daa923c95661512db203John McCall assert(getKind() == Access); 760c01d18094100db92d38daa923c95661512db203John McCall return AccessData.TargetDecl; 770c01d18094100db92d38daa923c95661512db203John McCall } 780c01d18094100db92d38daa923c95661512db203John McCall 790c01d18094100db92d38daa923c95661512db203John McCall NamedDecl *getAccessNamingClass() const { 800c01d18094100db92d38daa923c95661512db203John McCall assert(getKind() == Access); 810c01d18094100db92d38daa923c95661512db203John McCall return AccessData.NamingClass; 820c01d18094100db92d38daa923c95661512db203John McCall } 830c01d18094100db92d38daa923c95661512db203John McCall 840c01d18094100db92d38daa923c95661512db203John McCall const PartialDiagnostic &getDiagnostic() const { 850c01d18094100db92d38daa923c95661512db203John McCall return Diag; 860c01d18094100db92d38daa923c95661512db203John McCall } 870c01d18094100db92d38daa923c95661512db203John McCall 880c01d18094100db92d38daa923c95661512db203John McCallprivate: 89b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor DependentDiagnostic(const PartialDiagnostic &PDiag, 90b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor PartialDiagnostic::Storage *Storage) 91b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor : Diag(PDiag, Storage) {} 92b836518bfc0a2ad5e22a670c82fa070ed83ea909Douglas Gregor 930c01d18094100db92d38daa923c95661512db203John McCall static DependentDiagnostic *Create(ASTContext &Context, 940c01d18094100db92d38daa923c95661512db203John McCall DeclContext *Parent, 950c01d18094100db92d38daa923c95661512db203John McCall const PartialDiagnostic &PDiag); 960c01d18094100db92d38daa923c95661512db203John McCall 970c01d18094100db92d38daa923c95661512db203John McCall friend class DependentStoredDeclsMap; 980c01d18094100db92d38daa923c95661512db203John McCall friend class DeclContext::ddiag_iterator; 990c01d18094100db92d38daa923c95661512db203John McCall DependentDiagnostic *NextDiagnostic; 1000c01d18094100db92d38daa923c95661512db203John McCall 1010c01d18094100db92d38daa923c95661512db203John McCall PartialDiagnostic Diag; 1020c01d18094100db92d38daa923c95661512db203John McCall 1030c01d18094100db92d38daa923c95661512db203John McCall union { 1040c01d18094100db92d38daa923c95661512db203John McCall struct { 1050c01d18094100db92d38daa923c95661512db203John McCall unsigned Loc; 1060c01d18094100db92d38daa923c95661512db203John McCall unsigned Access : 2; 1070c01d18094100db92d38daa923c95661512db203John McCall unsigned IsMember : 1; 1080c01d18094100db92d38daa923c95661512db203John McCall NamedDecl *TargetDecl; 1090c01d18094100db92d38daa923c95661512db203John McCall CXXRecordDecl *NamingClass; 1100c01d18094100db92d38daa923c95661512db203John McCall } AccessData; 1110c01d18094100db92d38daa923c95661512db203John McCall }; 1120c01d18094100db92d38daa923c95661512db203John McCall}; 1130c01d18094100db92d38daa923c95661512db203John McCall 1140c01d18094100db92d38daa923c95661512db203John McCall/// 1150c01d18094100db92d38daa923c95661512db203John McCall 1160c01d18094100db92d38daa923c95661512db203John McCall/// An iterator over the dependent diagnostics in a dependent context. 1170c01d18094100db92d38daa923c95661512db203John McCallclass DeclContext::ddiag_iterator { 1180c01d18094100db92d38daa923c95661512db203John McCallpublic: 1190c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator() : Ptr(0) {} 1200c01d18094100db92d38daa923c95661512db203John McCall explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {} 1210c01d18094100db92d38daa923c95661512db203John McCall 1220c01d18094100db92d38daa923c95661512db203John McCall typedef DependentDiagnostic *value_type; 1230c01d18094100db92d38daa923c95661512db203John McCall typedef DependentDiagnostic *reference; 1240c01d18094100db92d38daa923c95661512db203John McCall typedef DependentDiagnostic *pointer; 1250c01d18094100db92d38daa923c95661512db203John McCall typedef int difference_type; 1260c01d18094100db92d38daa923c95661512db203John McCall typedef std::forward_iterator_tag iterator_category; 1270c01d18094100db92d38daa923c95661512db203John McCall 1280c01d18094100db92d38daa923c95661512db203John McCall reference operator*() const { return Ptr; } 1290c01d18094100db92d38daa923c95661512db203John McCall 1300c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator &operator++() { 1310c01d18094100db92d38daa923c95661512db203John McCall assert(Ptr && "attempt to increment past end of diag list"); 1320c01d18094100db92d38daa923c95661512db203John McCall Ptr = Ptr->NextDiagnostic; 1330c01d18094100db92d38daa923c95661512db203John McCall return *this; 1340c01d18094100db92d38daa923c95661512db203John McCall } 1350c01d18094100db92d38daa923c95661512db203John McCall 1360c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator operator++(int) { 1370c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator tmp = *this; 1380c01d18094100db92d38daa923c95661512db203John McCall ++*this; 1390c01d18094100db92d38daa923c95661512db203John McCall return tmp; 1400c01d18094100db92d38daa923c95661512db203John McCall } 1410c01d18094100db92d38daa923c95661512db203John McCall 1420c01d18094100db92d38daa923c95661512db203John McCall bool operator==(ddiag_iterator Other) const { 1430c01d18094100db92d38daa923c95661512db203John McCall return Ptr == Other.Ptr; 1440c01d18094100db92d38daa923c95661512db203John McCall } 1450c01d18094100db92d38daa923c95661512db203John McCall 1460c01d18094100db92d38daa923c95661512db203John McCall bool operator!=(ddiag_iterator Other) const { 1470c01d18094100db92d38daa923c95661512db203John McCall return Ptr != Other.Ptr; 1480c01d18094100db92d38daa923c95661512db203John McCall } 1490c01d18094100db92d38daa923c95661512db203John McCall 1500c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator &operator+=(difference_type N) { 1510c01d18094100db92d38daa923c95661512db203John McCall assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator"); 1520c01d18094100db92d38daa923c95661512db203John McCall while (N--) 1530c01d18094100db92d38daa923c95661512db203John McCall ++*this; 1540c01d18094100db92d38daa923c95661512db203John McCall return *this; 1550c01d18094100db92d38daa923c95661512db203John McCall } 1560c01d18094100db92d38daa923c95661512db203John McCall 1570c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator operator+(difference_type N) const { 1580c01d18094100db92d38daa923c95661512db203John McCall ddiag_iterator tmp = *this; 1590c01d18094100db92d38daa923c95661512db203John McCall tmp += N; 1600c01d18094100db92d38daa923c95661512db203John McCall return tmp; 1610c01d18094100db92d38daa923c95661512db203John McCall } 1620c01d18094100db92d38daa923c95661512db203John McCall 1630c01d18094100db92d38daa923c95661512db203John McCallprivate: 1640c01d18094100db92d38daa923c95661512db203John McCall DependentDiagnostic *Ptr; 1650c01d18094100db92d38daa923c95661512db203John McCall}; 1660c01d18094100db92d38daa923c95661512db203John McCall 1670c01d18094100db92d38daa923c95661512db203John McCallinline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const { 1680c01d18094100db92d38daa923c95661512db203John McCall assert(isDependentContext() 1690c01d18094100db92d38daa923c95661512db203John McCall && "cannot iterate dependent diagnostics of non-dependent context"); 1700c01d18094100db92d38daa923c95661512db203John McCall const DependentStoredDeclsMap *Map 1710c01d18094100db92d38daa923c95661512db203John McCall = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->LookupPtr); 1720c01d18094100db92d38daa923c95661512db203John McCall 1730c01d18094100db92d38daa923c95661512db203John McCall if (!Map) return ddiag_iterator(); 1740c01d18094100db92d38daa923c95661512db203John McCall return ddiag_iterator(Map->FirstDiagnostic); 1750c01d18094100db92d38daa923c95661512db203John McCall} 1760c01d18094100db92d38daa923c95661512db203John McCall 1770c01d18094100db92d38daa923c95661512db203John McCallinline DeclContext::ddiag_iterator DeclContext::ddiag_end() const { 1780c01d18094100db92d38daa923c95661512db203John McCall return ddiag_iterator(); 1790c01d18094100db92d38daa923c95661512db203John McCall} 1800c01d18094100db92d38daa923c95661512db203John McCall 1810c01d18094100db92d38daa923c95661512db203John McCall} 1820c01d18094100db92d38daa923c95661512db203John McCall 1830c01d18094100db92d38daa923c95661512db203John McCall#endif 184