DelayedDiagnostic.h revision f85e193739c953358c865005855253af4f68a497
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
249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/AST/DeclCXX.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
439c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessedEntity(ASTContext &Context,
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),
509c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall      BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) {
519c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
529c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
539c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessedEntity(ASTContext &Context,
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),
619c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall      Diag(0, Context.getDiagAllocator()) {
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,
125ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer                                           const NamedDecl *D,
12629233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor                                           llvm::StringRef Msg);
1279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  static DelayedDiagnostic makeAccess(SourceLocation Loc,
1299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                                      const AccessedEntity &Entity) {
1309c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DelayedDiagnostic DD;
1319c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Kind = Access;
1329c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Triggered = false;
1339c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Loc = Loc;
1349c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    new (&DD.getAccessData()) AccessedEntity(Entity);
1359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return DD;
1369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1379c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
138f85e193739c953358c865005855253af4f68a497John McCall  static DelayedDiagnostic makeForbiddenType(SourceLocation loc,
139f85e193739c953358c865005855253af4f68a497John McCall                                             unsigned diagnostic,
140f85e193739c953358c865005855253af4f68a497John McCall                                             QualType type,
141f85e193739c953358c865005855253af4f68a497John McCall                                             unsigned argument) {
142f85e193739c953358c865005855253af4f68a497John McCall    DelayedDiagnostic DD;
143f85e193739c953358c865005855253af4f68a497John McCall    DD.Kind = ForbiddenType;
144f85e193739c953358c865005855253af4f68a497John McCall    DD.Triggered = false;
145f85e193739c953358c865005855253af4f68a497John McCall    DD.Loc = loc;
146f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.Diagnostic = diagnostic;
147f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr();
148f85e193739c953358c865005855253af4f68a497John McCall    DD.ForbiddenTypeData.Argument = argument;
149f85e193739c953358c865005855253af4f68a497John McCall    return DD;
150f85e193739c953358c865005855253af4f68a497John McCall  }
151f85e193739c953358c865005855253af4f68a497John McCall
1529c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessedEntity &getAccessData() {
153ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Access && "Not an access diagnostic.");
1549c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return *reinterpret_cast<AccessedEntity*>(AccessData);
1559c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1569c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  const AccessedEntity &getAccessData() const {
157ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Access && "Not an access diagnostic.");
1589c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return *reinterpret_cast<const AccessedEntity*>(AccessData);
1599c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
160ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
161ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  const NamedDecl *getDeprecationDecl() const {
162ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
163ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    return DeprecationData.Decl;
164ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  }
165ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
166ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  llvm::StringRef getDeprecationMessage() const {
167ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
168ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    return llvm::StringRef(DeprecationData.Message,
169ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer                           DeprecationData.MessageLen);
170ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  }
171ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
172f85e193739c953358c865005855253af4f68a497John McCall  /// The diagnostic ID to emit.  Used like so:
173f85e193739c953358c865005855253af4f68a497John McCall  ///   Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
174f85e193739c953358c865005855253af4f68a497John McCall  ///     << diag.getForbiddenTypeOperand()
175f85e193739c953358c865005855253af4f68a497John McCall  ///     << diag.getForbiddenTypeArgument();
176f85e193739c953358c865005855253af4f68a497John McCall  unsigned getForbiddenTypeDiagnostic() const {
177f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
178f85e193739c953358c865005855253af4f68a497John McCall    return ForbiddenTypeData.Diagnostic;
179f85e193739c953358c865005855253af4f68a497John McCall  }
180f85e193739c953358c865005855253af4f68a497John McCall
181f85e193739c953358c865005855253af4f68a497John McCall  unsigned getForbiddenTypeArgument() const {
182f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
183f85e193739c953358c865005855253af4f68a497John McCall    return ForbiddenTypeData.Argument;
184f85e193739c953358c865005855253af4f68a497John McCall  }
185f85e193739c953358c865005855253af4f68a497John McCall
186f85e193739c953358c865005855253af4f68a497John McCall  QualType getForbiddenTypeOperand() const {
187f85e193739c953358c865005855253af4f68a497John McCall    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
188f85e193739c953358c865005855253af4f68a497John McCall    return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
189f85e193739c953358c865005855253af4f68a497John McCall  }
190f85e193739c953358c865005855253af4f68a497John McCall
191ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramerprivate:
192ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  union {
193ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    /// Deprecation.
194ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    struct {
195ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      const NamedDecl *Decl;
196ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      const char *Message;
197ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      size_t MessageLen;
198ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    } DeprecationData;
199ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
200f85e193739c953358c865005855253af4f68a497John McCall    struct {
201f85e193739c953358c865005855253af4f68a497John McCall      unsigned Diagnostic;
202f85e193739c953358c865005855253af4f68a497John McCall      unsigned Argument;
203f85e193739c953358c865005855253af4f68a497John McCall      void *OperandType;
204f85e193739c953358c865005855253af4f68a497John McCall    } ForbiddenTypeData;
205f85e193739c953358c865005855253af4f68a497John McCall
206ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    /// Access control.
207ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    char AccessData[sizeof(AccessedEntity)];
208ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  };
2099c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall};
2109c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
2119c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
2129c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
2139c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
2149c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#endif
215