DelayedDiagnostic.h revision ce2d186a421526e94d9e417ced141ae6c891cf48
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;
1049c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool IsMember;
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:
1159c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  enum DDKind { Deprecation, Access };
1169c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1179c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  unsigned char Kind; // actually a DDKind
1189c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  bool Triggered;
1199c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1209c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  SourceLocation Loc;
1219c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  void destroy() {
1239c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    switch (Kind) {
1249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    case Access: getAccessData().~AccessedEntity(); break;
1259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    case Deprecation: break;
1269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    }
1279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
130ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer                                           const NamedDecl *D,
131ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer                                           llvm::StringRef Msg) {
1329c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DelayedDiagnostic DD;
1339c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Kind = Deprecation;
1349c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Triggered = false;
1359c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Loc = Loc;
1369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.DeprecationData.Decl = D;
137ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    DD.DeprecationData.Message = Msg.data();
138ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    DD.DeprecationData.MessageLen = Msg.size();
1399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return DD;
1409c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1419c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1429c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  static DelayedDiagnostic makeAccess(SourceLocation Loc,
1439c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall                                      const AccessedEntity &Entity) {
1449c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DelayedDiagnostic DD;
1459c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Kind = Access;
1469c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Triggered = false;
1479c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    DD.Loc = Loc;
1489c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    new (&DD.getAccessData()) AccessedEntity(Entity);
1499c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall    return DD;
1509c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  }
1519c3087b0b0bea2fd782205c1274ebfc4290265e0John 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
172ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramerprivate:
173ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  union {
174ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    /// Deprecation.
175ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    struct {
176ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      const NamedDecl *Decl;
177ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      const char *Message;
178ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer      size_t MessageLen;
179ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    } DeprecationData;
180ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer
181ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    /// Access control.
182ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer    char AccessData[sizeof(AccessedEntity)];
183ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer  };
1849c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall};
1859c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1869c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
1879c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall}
1889c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall
1899c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#endif
190