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//===----------------------------------------------------------------------===//
99c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//
109c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// This file defines the DelayedDiagnostic class, which is used to
119c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// record diagnostics that are being conditionally produced during
129c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// declarator parsing.  Certain kinds of diagnostics --- notably
139c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// deprecation and access control --- are suppressed based on
149c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// semantic properties of the parsed declaration that aren't known
159c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// until it is fully parsed.
169c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//
179c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall// This file also defines AccessedEntity.
189c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//
199c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall//===----------------------------------------------------------------------===//
209c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
219c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall#include "clang/Sema/Sema.h"
259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallnamespace clang {
279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallnamespace sema {
289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// A declaration being accessed, together with information about how
309c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// it was accessed.
319c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallclass AccessedEntity {
329c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallpublic:
339c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// A member declaration found through lookup.  The target is the
349c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// member.
359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  enum MemberNonce { Member };
369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// A hierarchy (base-to-derived or derived-to-base) conversion.
389c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// The target is the base class.
399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  enum BaseNonce { Base };
409c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
419c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool isMemberAccess() const { return IsMember; }
429c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
43478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer  AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
449c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 MemberNonce _,
459c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 CXXRecordDecl *NamingClass,
469c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 DeclAccessPair FoundDecl,
479c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 QualType BaseObjectType)
489c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    : Access(FoundDecl.getAccess()), IsMember(true),
499c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall      Target(FoundDecl.getDecl()), NamingClass(NamingClass),
50478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer      BaseObjectType(BaseObjectType), Diag(0, Allocator) {
519c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
529c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
53478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer  AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
549c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 BaseNonce _,
559c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 CXXRecordDecl *BaseClass,
569c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 CXXRecordDecl *DerivedClass,
579c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                 AccessSpecifier Access)
589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    : Access(Access), IsMember(false),
59d931b086984257de68868a64a235c2b4b34003fbJohn McCall      Target(BaseClass),
609c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall      NamingClass(DerivedClass),
61478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer      Diag(0, Allocator) {
629c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
639c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
649c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool isQuiet() const { return Diag.getDiagID() == 0; }
659c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
669c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
679c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
689c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  // These apply to member decls...
699c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  NamedDecl *getTargetDecl() const { return Target; }
709c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *getNamingClass() const { return NamingClass; }
719c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
729c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  // ...and these apply to hierarchy conversions.
739c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *getBaseClass() const {
74d931b086984257de68868a64a235c2b4b34003fbJohn McCall    assert(!IsMember); return cast<CXXRecordDecl>(Target);
759c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
769c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *getDerivedClass() const { return NamingClass; }
779c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
789c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// Retrieves the base object type, important when accessing
799c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// an instance member.
809c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  QualType getBaseObjectType() const { return BaseObjectType; }
819c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
829c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// Sets a diagnostic to be performed.  The diagnostic is given
839c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  /// four (additional) arguments:
849c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %0 - 0 if the entity was private, 1 if protected
859c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %1 - the DeclarationName of the entity
869c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %2 - the TypeDecl type of the naming class
879c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  ///   %3 - the TypeDecl type of the declaring class
889c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  void setDiag(const PartialDiagnostic &PDiag) {
899c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    assert(isQuiet() && "partial diagnostic already defined");
909c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    Diag = PDiag;
919c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
929c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  PartialDiagnostic &setDiag(unsigned DiagID) {
939c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    assert(isQuiet() && "partial diagnostic already defined");
949c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    assert(DiagID && "creating null diagnostic");
959c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    Diag.Reset(DiagID);
969c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return Diag;
979c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
989c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  const PartialDiagnostic &getDiag() const {
999c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return Diag;
1009c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1019c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1029c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallprivate:
1039c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  unsigned Access : 2;
104eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  unsigned IsMember : 1;
1059c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  NamedDecl *Target;
1069c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  CXXRecordDecl *NamingClass;
1079c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  QualType BaseObjectType;
1089c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  PartialDiagnostic Diag;
1099c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall};
1109c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1119c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// A diagnostic message which has been conditionally emitted pending
1129c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall/// the complete parsing of the current declaration.
1139c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallclass DelayedDiagnostic {
1149c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallpublic:
115f85e193739c953358c865005855253af4f68a497John McCall  enum DDKind { Deprecation, Access, ForbiddenType };
1169c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1179c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  unsigned char Kind; // actually a DDKind
1189c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool Triggered;
1199c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1209c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  SourceLocation Loc;
1219c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
12229233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor  void Destroy();
1239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
125b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian           const NamedDecl *D,
126b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian           const ObjCInterfaceDecl *UnknownObjCClass,
127fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian           const ObjCPropertyDecl  *ObjCProperty,
128b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian           StringRef Msg);
1299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1309c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  static DelayedDiagnostic makeAccess(SourceLocation Loc,
1319c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                                      const AccessedEntity &Entity) {
1329c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DelayedDiagnostic DD;
1339c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Kind = Access;
1349c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Triggered = false;
1359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Loc = Loc;
1369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    new (&DD.getAccessData()) AccessedEntity(Entity);
1379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return DD;
1389c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
140f85e193739c953358c865005855253af4f68a497John McCall  static DelayedDiagnostic makeForbiddenType(SourceLocation loc,
141f85e193739c953358c865005855253af4f68a497John McCall                                             unsigned diagnostic,
142f85e193739c953358c865005855253af4f68a497John McCall                                             QualType type,
143f85e193739c953358c865005855253af4f68a497John McCall                                             unsigned argument) {
144f85e193739c953358c865005855253af4f68a497John McCall    DelayedDiagnostic DD;
145f85e193739c953358c865005855253af4f68a497John McCall    DD.Kind = ForbiddenType;
146f85e193739c953358c865005855253af4f68a497John McCall    DD.Triggered = false;
147f85e193739c953358c865005855253af4f68a497John McCall    DD.Loc = loc;
148f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.Diagnostic = diagnostic;
149f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr();
150f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.Argument = argument;
151f85e193739c953358c865005855253af4f68a497John McCall    return DD;
152f85e193739c953358c865005855253af4f68a497John McCall  }
153f85e193739c953358c865005855253af4f68a497John McCall
1549c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessedEntity &getAccessData() {
155ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Access && "Not an access diagnostic.");
1569c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return *reinterpret_cast<AccessedEntity*>(AccessData);
1579c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  const AccessedEntity &getAccessData() const {
159ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Access && "Not an access diagnostic.");
1609c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return *reinterpret_cast<const AccessedEntity*>(AccessData);
1619c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
162ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
163ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  const NamedDecl *getDeprecationDecl() const {
164ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
165ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    return DeprecationData.Decl;
166ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  }
167ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
168686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  StringRef getDeprecationMessage() const {
169ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
170686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    return StringRef(DeprecationData.Message,
171ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer                           DeprecationData.MessageLen);
172ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  }
173ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
174f85e193739c953358c865005855253af4f68a497John McCall  /// The diagnostic ID to emit.  Used like so:
175f85e193739c953358c865005855253af4f68a497John McCall  ///   Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
176f85e193739c953358c865005855253af4f68a497John McCall  ///     << diag.getForbiddenTypeOperand()
177f85e193739c953358c865005855253af4f68a497John McCall  ///     << diag.getForbiddenTypeArgument();
178f85e193739c953358c865005855253af4f68a497John McCall  unsigned getForbiddenTypeDiagnostic() const {
179f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
180f85e193739c953358c865005855253af4f68a497John McCall    return ForbiddenTypeData.Diagnostic;
181f85e193739c953358c865005855253af4f68a497John McCall  }
182f85e193739c953358c865005855253af4f68a497John McCall
183f85e193739c953358c865005855253af4f68a497John McCall  unsigned getForbiddenTypeArgument() const {
184f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
185f85e193739c953358c865005855253af4f68a497John McCall    return ForbiddenTypeData.Argument;
186f85e193739c953358c865005855253af4f68a497John McCall  }
187f85e193739c953358c865005855253af4f68a497John McCall
188f85e193739c953358c865005855253af4f68a497John McCall  QualType getForbiddenTypeOperand() const {
189f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
190f85e193739c953358c865005855253af4f68a497John McCall    return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
191f85e193739c953358c865005855253af4f68a497John McCall  }
192b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian
193b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  const ObjCInterfaceDecl *getUnknownObjCClass() const {
194b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian    return DeprecationData.UnknownObjCClass;
195b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian  }
196f85e193739c953358c865005855253af4f68a497John McCall
197fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian  const ObjCPropertyDecl *getObjCProperty() const {
198fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian    return DeprecationData.ObjCProperty;
199fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian  }
200fd09088880f758c874edc8d3d22fa922baec0483Fariborz Jahanian
201ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramerprivate:
202e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
203e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct DD {
204e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const NamedDecl *Decl;
205e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const ObjCInterfaceDecl *UnknownObjCClass;
206e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const ObjCPropertyDecl  *ObjCProperty;
207e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    const char *Message;
208e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    size_t MessageLen;
209e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
210e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
211e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct FTD {
212e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned Diagnostic;
213e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned Argument;
214e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    void *OperandType;
215e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
216e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
217ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  union {
218e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// Deprecation
219e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct DD DeprecationData;
220e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct FTD ForbiddenTypeData;
221f85e193739c953358c865005855253af4f68a497John McCall
222ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    /// Access control.
223ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    char AccessData[sizeof(AccessedEntity)];
224ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  };
2259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall};
2269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
2279257664568bf375b7790131a84d9a4fa30a5b7e3John McCall/// DelayedDiagnosticPool - A collection of diagnostics which were
2289257664568bf375b7790131a84d9a4fa30a5b7e3John McCall/// delayed.
2299257664568bf375b7790131a84d9a4fa30a5b7e3John McCallclass DelayedDiagnosticPool {
2309257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  const DelayedDiagnosticPool *Parent;
231cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallVector<DelayedDiagnostic, 4> Diagnostics;
2329257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
233f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  DelayedDiagnosticPool(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
234f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  void operator=(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
2359257664568bf375b7790131a84d9a4fa30a5b7e3John McCallpublic:
2369257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}
2379257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  ~DelayedDiagnosticPool() {
238cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    for (SmallVectorImpl<DelayedDiagnostic>::iterator
2399257664568bf375b7790131a84d9a4fa30a5b7e3John McCall           i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
2409257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      i->Destroy();
2419257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2429257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2439257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  const DelayedDiagnosticPool *getParent() const { return Parent; }
2449257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2459257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// Does this pool, or any of its ancestors, contain any diagnostics?
2469257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  bool empty() const {
2479257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    return (Diagnostics.empty() && (Parent == NULL || Parent->empty()));
2489257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2499257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2509257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// Add a diagnostic to this pool.
2519257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  void add(const DelayedDiagnostic &diag) {
2529257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    Diagnostics.push_back(diag);
2539257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2549257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2559257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  /// Steal the diagnostics from the given pool.
2569257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  void steal(DelayedDiagnosticPool &pool) {
2579257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    if (pool.Diagnostics.empty()) return;
2589257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2599257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    if (Diagnostics.empty()) {
2609257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Diagnostics = llvm_move(pool.Diagnostics);
2619257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    } else {
2629257664568bf375b7790131a84d9a4fa30a5b7e3John McCall      Diagnostics.append(pool.pool_begin(), pool.pool_end());
2639257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    }
2649257664568bf375b7790131a84d9a4fa30a5b7e3John McCall    pool.Diagnostics.clear();
2659257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  }
2669257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
267cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator;
2689257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  pool_iterator pool_begin() const { return Diagnostics.begin(); }
2699257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  pool_iterator pool_end() const { return Diagnostics.end(); }
2709257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  bool pool_empty() const { return Diagnostics.empty(); }
2719257664568bf375b7790131a84d9a4fa30a5b7e3John McCall};
2729257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2739c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
2749257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2759257664568bf375b7790131a84d9a4fa30a5b7e3John McCall/// Add a diagnostic to the current delay pool.
2769257664568bf375b7790131a84d9a4fa30a5b7e3John McCallinline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
2779257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  assert(shouldDelayDiagnostics() && "trying to delay without pool");
2789257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  CurPool->add(diag);
2799257664568bf375b7790131a84d9a4fa30a5b7e3John McCall}
2809257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2819257664568bf375b7790131a84d9a4fa30a5b7e3John McCall
2829c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
2839c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
2849c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#endif
285