//===- DelayedDiagnostic.h - Delayed declarator diagnostics -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines the classes clang::DelayedDiagnostic and
/// clang::AccessedEntity.
///
/// DelayedDiangostic is used to record diagnostics that are being
/// conditionally produced during declarator parsing.  Certain kinds of
/// diagnostics -- notably deprecation and access control -- are suppressed
/// based on semantic properties of the parsed declaration that aren't known
/// until it is fully parsed.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
#define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H

#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstddef>
#include <utility>

namespace clang {

class ObjCInterfaceDecl;
class ObjCPropertyDecl;

namespace sema {

/// A declaration being accessed, together with information about how
/// it was accessed.
class AccessedEntity {
public:
  /// A member declaration found through lookup.  The target is the
  /// member.
  enum MemberNonce { Member };

  /// A hierarchy (base-to-derived or derived-to-base) conversion.
  /// The target is the base class.
  enum BaseNonce { Base };

  AccessedEntity(PartialDiagnostic::DiagStorageAllocator &Allocator,
                 MemberNonce _, CXXRecordDecl *NamingClass,
                 DeclAccessPair FoundDecl, QualType BaseObjectType)
      : Access(FoundDecl.getAccess()), IsMember(true),
        Target(FoundDecl.getDecl()), NamingClass(NamingClass),
        BaseObjectType(BaseObjectType), Diag(0, Allocator) {}

  AccessedEntity(PartialDiagnostic::DiagStorageAllocator &Allocator,
                 BaseNonce _, CXXRecordDecl *BaseClass,
                 CXXRecordDecl *DerivedClass, AccessSpecifier Access)
      : Access(Access), IsMember(false), Target(BaseClass),
        NamingClass(DerivedClass), Diag(0, Allocator) {}

  bool isMemberAccess() const { return IsMember; }

  bool isQuiet() const { return Diag.getDiagID() == 0; }

  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }

  // These apply to member decls...
  NamedDecl *getTargetDecl() const { return Target; }
  CXXRecordDecl *getNamingClass() const { return NamingClass; }

  // ...and these apply to hierarchy conversions.
  CXXRecordDecl *getBaseClass() const {
    assert(!IsMember); return cast<CXXRecordDecl>(Target);
  }
  CXXRecordDecl *getDerivedClass() const { return NamingClass; }

  /// Retrieves the base object type, important when accessing
  /// an instance member.
  QualType getBaseObjectType() const { return BaseObjectType; }

  /// Sets a diagnostic to be performed.  The diagnostic is given
  /// four (additional) arguments:
  ///   %0 - 0 if the entity was private, 1 if protected
  ///   %1 - the DeclarationName of the entity
  ///   %2 - the TypeDecl type of the naming class
  ///   %3 - the TypeDecl type of the declaring class
  void setDiag(const PartialDiagnostic &PDiag) {
    assert(isQuiet() && "partial diagnostic already defined");
    Diag = PDiag;
  }
  PartialDiagnostic &setDiag(unsigned DiagID) {
    assert(isQuiet() && "partial diagnostic already defined");
    assert(DiagID && "creating null diagnostic");
    Diag.Reset(DiagID);
    return Diag;
  }
  const PartialDiagnostic &getDiag() const {
    return Diag;
  }

private:
  LLVM_PREFERRED_TYPE(AccessSpecifier)
  unsigned Access : 2;
  LLVM_PREFERRED_TYPE(bool)
  unsigned IsMember : 1;
  NamedDecl *Target;
  CXXRecordDecl *NamingClass;
  QualType BaseObjectType;
  PartialDiagnostic Diag;
};

/// A diagnostic message which has been conditionally emitted pending
/// the complete parsing of the current declaration.
class DelayedDiagnostic {
public:
  enum DDKind : unsigned char { Availability, Access, ForbiddenType };

  DDKind Kind;
  bool Triggered;

  SourceLocation Loc;

  void Destroy();

  static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
                                            ArrayRef<SourceLocation> Locs,
                                            const NamedDecl *ReferringDecl,
                                            const NamedDecl *OffendingDecl,
                                            const ObjCInterfaceDecl *UnknownObjCClass,
                                            const ObjCPropertyDecl  *ObjCProperty,
                                            StringRef Msg,
                                            bool ObjCPropertyAccess);

  static DelayedDiagnostic makeAccess(SourceLocation Loc,
                                      const AccessedEntity &Entity) {
    DelayedDiagnostic DD;
    DD.Kind = Access;
    DD.Triggered = false;
    DD.Loc = Loc;
    new (&DD.getAccessData()) AccessedEntity(Entity);
    return DD;
  }

  static DelayedDiagnostic makeForbiddenType(SourceLocation loc,
                                             unsigned diagnostic,
                                             QualType type,
                                             unsigned argument) {
    DelayedDiagnostic DD;
    DD.Kind = ForbiddenType;
    DD.Triggered = false;
    DD.Loc = loc;
    DD.ForbiddenTypeData.Diagnostic = diagnostic;
    DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr();
    DD.ForbiddenTypeData.Argument = argument;
    return DD;
  }

  AccessedEntity &getAccessData() {
    assert(Kind == Access && "Not an access diagnostic.");
    return *reinterpret_cast<AccessedEntity*>(AccessData);
  }
  const AccessedEntity &getAccessData() const {
    assert(Kind == Access && "Not an access diagnostic.");
    return *reinterpret_cast<const AccessedEntity*>(AccessData);
  }

  const NamedDecl *getAvailabilityReferringDecl() const {
    assert(Kind == Availability && "Not an availability diagnostic.");
    return AvailabilityData.ReferringDecl;
  }

  const NamedDecl *getAvailabilityOffendingDecl() const {
    return AvailabilityData.OffendingDecl;
  }

  StringRef getAvailabilityMessage() const {
    assert(Kind == Availability && "Not an availability diagnostic.");
    return StringRef(AvailabilityData.Message, AvailabilityData.MessageLen);
  }

  ArrayRef<SourceLocation> getAvailabilitySelectorLocs() const {
    assert(Kind == Availability && "Not an availability diagnostic.");
    return llvm::ArrayRef(AvailabilityData.SelectorLocs,
                          AvailabilityData.NumSelectorLocs);
  }

  AvailabilityResult getAvailabilityResult() const {
    assert(Kind == Availability && "Not an availability diagnostic.");
    return AvailabilityData.AR;
  }

  /// The diagnostic ID to emit.  Used like so:
  ///   Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
  ///     << diag.getForbiddenTypeOperand()
  ///     << diag.getForbiddenTypeArgument();
  unsigned getForbiddenTypeDiagnostic() const {
    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
    return ForbiddenTypeData.Diagnostic;
  }

  unsigned getForbiddenTypeArgument() const {
    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
    return ForbiddenTypeData.Argument;
  }

  QualType getForbiddenTypeOperand() const {
    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
    return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
  }

  const ObjCInterfaceDecl *getUnknownObjCClass() const {
    return AvailabilityData.UnknownObjCClass;
  }

  const ObjCPropertyDecl *getObjCProperty() const {
    return AvailabilityData.ObjCProperty;
  }

  bool getObjCPropertyAccess() const {
    return AvailabilityData.ObjCPropertyAccess;
  }

private:
  struct AD {
    const NamedDecl *ReferringDecl;
    const NamedDecl *OffendingDecl;
    const ObjCInterfaceDecl *UnknownObjCClass;
    const ObjCPropertyDecl  *ObjCProperty;
    const char *Message;
    size_t MessageLen;
    SourceLocation *SelectorLocs;
    size_t NumSelectorLocs;
    AvailabilityResult AR;
    bool ObjCPropertyAccess;
  };

  struct FTD {
    unsigned Diagnostic;
    unsigned Argument;
    void *OperandType;
  };

  union {
    struct AD AvailabilityData;
    struct FTD ForbiddenTypeData;

    /// Access control.
    char AccessData[sizeof(AccessedEntity)];
  };
};

/// A collection of diagnostics which were delayed.
class DelayedDiagnosticPool {
  const DelayedDiagnosticPool *Parent;
  SmallVector<DelayedDiagnostic, 4> Diagnostics;

public:
  DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}

  DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete;
  DelayedDiagnosticPool &operator=(const DelayedDiagnosticPool &) = delete;

  DelayedDiagnosticPool(DelayedDiagnosticPool &&Other)
      : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) {
    Other.Diagnostics.clear();
  }

  DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) {
    Parent = Other.Parent;
    Diagnostics = std::move(Other.Diagnostics);
    Other.Diagnostics.clear();
    return *this;
  }

  ~DelayedDiagnosticPool() {
    for (SmallVectorImpl<DelayedDiagnostic>::iterator
           i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
      i->Destroy();
  }

  const DelayedDiagnosticPool *getParent() const { return Parent; }

  /// Does this pool, or any of its ancestors, contain any diagnostics?
  bool empty() const {
    return (Diagnostics.empty() && (!Parent || Parent->empty()));
  }

  /// Add a diagnostic to this pool.
  void add(const DelayedDiagnostic &diag) {
    Diagnostics.push_back(diag);
  }

  /// Steal the diagnostics from the given pool.
  void steal(DelayedDiagnosticPool &pool) {
    if (pool.Diagnostics.empty()) return;

    if (Diagnostics.empty()) {
      Diagnostics = std::move(pool.Diagnostics);
    } else {
      Diagnostics.append(pool.pool_begin(), pool.pool_end());
    }
    pool.Diagnostics.clear();
  }

  using pool_iterator = SmallVectorImpl<DelayedDiagnostic>::const_iterator;

  pool_iterator pool_begin() const { return Diagnostics.begin(); }
  pool_iterator pool_end() const { return Diagnostics.end(); }
  bool pool_empty() const { return Diagnostics.empty(); }
};

} // namespace clang

/// Add a diagnostic to the current delay pool.
inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
  assert(shouldDelayDiagnostics() && "trying to delay without pool");
  CurPool->add(diag);
}

} // namespace clang

#endif // LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
