19c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- C++ -*-===//
29c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//
39c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//                     The LLVM Compiler Infrastructure
49c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//
59c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// This file is distributed under the University of Illinois Open Source
69c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// License. See LICENSE.TXT for details.
79c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//
89c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//===----------------------------------------------------------------------===//
91b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett///
101b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// \file
111b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// \brief Defines the classes clang::DelayedDiagnostic and
121b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// clang::AccessedEntity.
131b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett///
141b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// DelayedDiangostic is used to record diagnostics that are being
151b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// conditionally produced during declarator parsing.  Certain kinds of
161b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// diagnostics -- notably deprecation and access control -- are suppressed
171b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// based on semantic properties of the parsed declaration that aren't known
181b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// until it is fully parsed.
191b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett///
209c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//===----------------------------------------------------------------------===//
219c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
259257664568bf375b7790131a84d9a4fa30a5b7e3John McCall#include "clang/Sema/Sema.h"
269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallnamespace clang {
289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallnamespace sema {
299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
309c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// A declaration being accessed, together with information about how
319c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// it was accessed.
329c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallclass AccessedEntity {
339c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallpublic:
349c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// A member declaration found through lookup.  The target is the
359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// member.
369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  enum MemberNonce { Member };
379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
389c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// A hierarchy (base-to-derived or derived-to-base) conversion.
399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// The target is the base class.
409c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  enum BaseNonce { Base };
419c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
429c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool isMemberAccess() const { return IsMember; }
439c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
44478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer  AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
459c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 MemberNonce _,
469c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 CXXRecordDecl *NamingClass,
479c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 DeclAccessPair FoundDecl,
489c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 QualType BaseObjectType)
499c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    : Access(FoundDecl.getAccess()), IsMember(true),
509c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall      Target(FoundDecl.getDecl()), NamingClass(NamingClass),
51478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer      BaseObjectType(BaseObjectType), Diag(0, Allocator) {
529c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
539c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
54478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer  AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
559c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 BaseNonce _,
569c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 CXXRecordDecl *BaseClass,
579c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 CXXRecordDecl *DerivedClass,
589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 AccessSpecifier Access)
599c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    : Access(Access), IsMember(false),
60d931b086984257de68868a64a235c2b4b34003fbJohn McCall      Target(BaseClass),
619c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall      NamingClass(DerivedClass),
62478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer      Diag(0, Allocator) {
639c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
649c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
659c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool isQuiet() const { return Diag.getDiagID() == 0; }
669c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
679c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
689c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
699c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  // These apply to member decls...
709c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  NamedDecl *getTargetDecl() const { return Target; }
719c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *getNamingClass() const { return NamingClass; }
729c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
739c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  // ...and these apply to hierarchy conversions.
749c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *getBaseClass() const {
75d931b086984257de68868a64a235c2b4b34003fbJohn McCall    assert(!IsMember); return cast<CXXRecordDecl>(Target);
769c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
779c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *getDerivedClass() const { return NamingClass; }
789c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
799c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// Retrieves the base object type, important when accessing
809c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// an instance member.
819c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  QualType getBaseObjectType() const { return BaseObjectType; }
829c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
839c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// Sets a diagnostic to be performed.  The diagnostic is given
849c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// four (additional) arguments:
859c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %0 - 0 if the entity was private, 1 if protected
869c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %1 - the DeclarationName of the entity
879c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %2 - the TypeDecl type of the naming class
889c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %3 - the TypeDecl type of the declaring class
899c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  void setDiag(const PartialDiagnostic &PDiag) {
909c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    assert(isQuiet() && "partial diagnostic already defined");
919c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    Diag = PDiag;
929c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
939c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  PartialDiagnostic &setDiag(unsigned DiagID) {
949c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    assert(isQuiet() && "partial diagnostic already defined");
959c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    assert(DiagID && "creating null diagnostic");
969c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    Diag.Reset(DiagID);
979c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return Diag;
989c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
999c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  const PartialDiagnostic &getDiag() const {
1009c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return Diag;
1019c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1029c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1039c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallprivate:
1049c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  unsigned Access : 2;
105eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  unsigned IsMember : 1;
1069c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  NamedDecl *Target;
1079c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *NamingClass;
1089c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  QualType BaseObjectType;
1099c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  PartialDiagnostic Diag;
1109c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall};
1119c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1129c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// A diagnostic message which has been conditionally emitted pending
1139c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// the complete parsing of the current declaration.
1149c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallclass DelayedDiagnostic {
1159c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallpublic:
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
1179c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1189c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  unsigned char Kind; // actually a DDKind
1199c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool Triggered;
1209c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1219c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  SourceLocation Loc;
1229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
12329233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor  void Destroy();
1249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                            SourceLocation Loc,
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                            const NamedDecl *D,
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                            const ObjCInterfaceDecl *UnknownObjCClass,
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                            const ObjCPropertyDecl  *ObjCProperty,
130ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                            StringRef Msg,
131ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                            bool ObjCPropertyAccess);
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1339c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1349c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  static DelayedDiagnostic makeAccess(SourceLocation Loc,
1359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                                      const AccessedEntity &Entity) {
1369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DelayedDiagnostic DD;
1379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Kind = Access;
1389c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Triggered = false;
1399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Loc = Loc;
1409c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    new (&DD.getAccessData()) AccessedEntity(Entity);
1419c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return DD;
1429c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1439c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
144f85e193739c953358c865005855253af4f68a497John McCall  static DelayedDiagnostic makeForbiddenType(SourceLocation loc,
145f85e193739c953358c865005855253af4f68a497John McCall                                             unsigned diagnostic,
146f85e193739c953358c865005855253af4f68a497John McCall                                             QualType type,
147f85e193739c953358c865005855253af4f68a497John McCall                                             unsigned argument) {
148f85e193739c953358c865005855253af4f68a497John McCall    DelayedDiagnostic DD;
149f85e193739c953358c865005855253af4f68a497John McCall    DD.Kind = ForbiddenType;
150f85e193739c953358c865005855253af4f68a497John McCall    DD.Triggered = false;
151f85e193739c953358c865005855253af4f68a497John McCall    DD.Loc = loc;
152f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.Diagnostic = diagnostic;
153f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr();
154f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.Argument = argument;
155f85e193739c953358c865005855253af4f68a497John McCall    return DD;
156f85e193739c953358c865005855253af4f68a497John McCall  }
157f85e193739c953358c865005855253af4f68a497John McCall
1589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessedEntity &getAccessData() {
159ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Access && "Not an access diagnostic.");
1609c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return *reinterpret_cast<AccessedEntity*>(AccessData);
1619c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1629c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  const AccessedEntity &getAccessData() const {
163ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Access && "Not an access diagnostic.");
1649c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return *reinterpret_cast<const AccessedEntity*>(AccessData);
1659c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
166ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
167ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  const NamedDecl *getDeprecationDecl() const {
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Kind == Deprecation || Kind == Unavailable) &&
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           "Not a deprecation diagnostic.");
170ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    return DeprecationData.Decl;
171ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  }
172ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
173686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  StringRef getDeprecationMessage() const {
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    assert((Kind == Deprecation || Kind == Unavailable) &&
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           "Not a deprecation diagnostic.");
176686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    return StringRef(DeprecationData.Message,
177ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer                           DeprecationData.MessageLen);
178ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  }
179ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
180f85e193739c953358c865005855253af4f68a497John McCall  /// The diagnostic ID to emit.  Used like so:
181f85e193739c953358c865005855253af4f68a497John McCall  ///   Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
182f85e193739c953358c865005855253af4f68a497John McCall  ///     << diag.getForbiddenTypeOperand()
183f85e193739c953358c865005855253af4f68a497John McCall  ///     << diag.getForbiddenTypeArgument();
184f85e193739c953358c865005855253af4f68a497John McCall  unsigned getForbiddenTypeDiagnostic() const {
185f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
186f85e193739c953358c865005855253af4f68a497John McCall    return ForbiddenTypeData.Diagnostic;
187f85e193739c953358c865005855253af4f68a497John McCall  }
188f85e193739c953358c865005855253af4f68a497John McCall
189f85e193739c953358c865005855253af4f68a497John McCall  unsigned getForbiddenTypeArgument() const {
190f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
191f85e193739c953358c865005855253af4f68a497John McCall    return ForbiddenTypeData.Argument;
192f85e193739c953358c865005855253af4f68a497John McCall  }
193f85e193739c953358c865005855253af4f68a497John McCall
194f85e193739c953358c865005855253af4f68a497John McCall  QualType getForbiddenTypeOperand() const {
195f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
196f85e193739c953358c865005855253af4f68a497John McCall    return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
197f85e193739c953358c865005855253af4f68a497John McCall  }
198b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian
199b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  const ObjCInterfaceDecl *getUnknownObjCClass() const {
200b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    return DeprecationData.UnknownObjCClass;
201b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
202f85e193739c953358c865005855253af4f68a497John McCall
203fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian  const ObjCPropertyDecl *getObjCProperty() const {
204fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian    return DeprecationData.ObjCProperty;
205fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian  }
206ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
207ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool getObjCPropertyAccess() const {
208ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return DeprecationData.ObjCPropertyAccess;
209ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
210fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian
211ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramerprivate:
212e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
213e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct DD {
214e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const NamedDecl *Decl;
215e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const ObjCInterfaceDecl *UnknownObjCClass;
216e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const ObjCPropertyDecl  *ObjCProperty;
217e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const char *Message;
218e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    size_t MessageLen;
219ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    bool ObjCPropertyAccess;
220e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
221e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
222e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct FTD {
223e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned Diagnostic;
224e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned Argument;
225e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    void *OperandType;
226e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
227e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
228ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  union {
229e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// Deprecation
230e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct DD DeprecationData;
231e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct FTD ForbiddenTypeData;
232f85e193739c953358c865005855253af4f68a497John McCall
233ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    /// Access control.
234ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    char AccessData[sizeof(AccessedEntity)];
235ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  };
2369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall};
2379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
2381b9e4eb5d60a567452434b9cfc953d69e85e2ee9James Dennett/// \brief A collection of diagnostics which were delayed.
2399257664568bf375b7790131a84d9a4fa30a5b7e3John McCallclass DelayedDiagnosticPool {
2409257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  const DelayedDiagnosticPool *Parent;
241cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallVector<DelayedDiagnostic, 4> Diagnostics;
2429257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
243f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  DelayedDiagnosticPool(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
244f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  void operator=(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
2459257664568bf375b7790131a84d9a4fa30a5b7e3John McCallpublic:
2469257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}
2479257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  ~DelayedDiagnosticPool() {
248cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    for (SmallVectorImpl<DelayedDiagnostic>::iterator
2499257664568bf375b7790131a84d9a4fa30a5b7e3John McCall           i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
2509257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      i->Destroy();
2519257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2529257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2539257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  const DelayedDiagnosticPool *getParent() const { return Parent; }
2549257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2559257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// Does this pool, or any of its ancestors, contain any diagnostics?
2569257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  bool empty() const {
2576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return (Diagnostics.empty() && (!Parent || Parent->empty()));
2589257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2599257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2609257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// Add a diagnostic to this pool.
2619257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  void add(const DelayedDiagnostic &diag) {
2629257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    Diagnostics.push_back(diag);
2639257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2649257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2659257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// Steal the diagnostics from the given pool.
2669257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  void steal(DelayedDiagnosticPool &pool) {
2679257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    if (pool.Diagnostics.empty()) return;
2689257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2699257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    if (Diagnostics.empty()) {
270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diagnostics = std::move(pool.Diagnostics);
2719257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    } else {
2729257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Diagnostics.append(pool.pool_begin(), pool.pool_end());
2739257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2749257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    pool.Diagnostics.clear();
2759257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2769257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
277cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator;
2789257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  pool_iterator pool_begin() const { return Diagnostics.begin(); }
2799257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  pool_iterator pool_end() const { return Diagnostics.end(); }
2809257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  bool pool_empty() const { return Diagnostics.empty(); }
2819257664568bf375b7790131a84d9a4fa30a5b7e3John McCall};
2829257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2839c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
2849257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2859257664568bf375b7790131a84d9a4fa30a5b7e3John McCall/// Add a diagnostic to the current delay pool.
2869257664568bf375b7790131a84d9a4fa30a5b7e3John McCallinline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
2879257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  assert(shouldDelayDiagnostics() && "trying to delay without pool");
2889257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  CurPool->add(diag);
2899257664568bf375b7790131a84d9a4fa30a5b7e3John McCall}
2909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2919257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2929c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
2939c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
2949c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#endif
295