//===--- ConcreteDeclRef.h - Reference to a concrete decl -------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the ConcreteDeclRef class, which provides a reference to
// a declaration that is potentially specialized.
//===----------------------------------------------------------------------===//

#ifndef SWIFT_AST_CONCRETEDECLREF_H
#define SWIFT_AST_CONCRETEDECLREF_H

#include "swift/Basic/LLVM.h"
#include "swift/AST/SubstitutionList.h"
#include "swift/AST/TypeAlignments.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <cstring>

namespace swift {

class ASTContext;
class SourceManager;
class ValueDecl;

/// A reference to a concrete representation of a particular declaration,
/// providing substitutions for all type parameters of the original,
/// underlying declaration.
class ConcreteDeclRef {
  /// A specialized declaration reference, which provides substitutions
  /// that fully specialize a generic declaration.
  class SpecializedDeclRef final :
      private llvm::TrailingObjects<SpecializedDeclRef, Substitution> {
    friend TrailingObjects;

    /// The declaration.
    ValueDecl *TheDecl;

    /// The number of substitutions, which are tail allocated.
    unsigned NumSubstitutions;

    SpecializedDeclRef(ValueDecl *decl, SubstitutionList substitutions)
      : TheDecl(decl), NumSubstitutions(substitutions.size())
    {
      std::uninitialized_copy(substitutions.begin(), substitutions.end(),
                              getTrailingObjects<Substitution>());
    }

  public:
    /// Retrieve the generic declaration.
    ValueDecl *getDecl() const { return TheDecl; }

    /// Retrieve the substitutions.
    SubstitutionList getSubstitutions() const {
      return {getTrailingObjects<Substitution>(), NumSubstitutions};
    }
    
    /// Allocate a new specialized declaration reference.
    static SpecializedDeclRef *create(ASTContext &ctx, ValueDecl *decl,
                                      SubstitutionList substitutions);
  };

  llvm::PointerUnion<ValueDecl *, SpecializedDeclRef *> Data;

  friend class llvm::PointerLikeTypeTraits<ConcreteDeclRef>;

public:
  /// Create an empty declaration reference.
  ConcreteDeclRef() : Data() { }

  /// Construct a reference to the given value.
  ConcreteDeclRef(ValueDecl *decl) : Data(decl) { }

  /// Construct a reference to the given value, specialized with the given
  /// substitutions.
  ///
  /// \param ctx The ASTContext in which to allocate the specialized
  /// declaration reference.
  ///
  /// \param decl The declaration to which this reference refers, which will
  /// be specialized by applying the given substitutions.
  ///
  /// \param substitutions The complete set of substitutions to apply to the
  /// given declaration. This array will be copied into the ASTContext by the
  /// constructor.
  ConcreteDeclRef(ASTContext &ctx, ValueDecl *decl,
                  SubstitutionList substitutions) {
    if (substitutions.empty())
      Data = decl;
    else
      Data = SpecializedDeclRef::create(ctx, decl, substitutions);
  }

  /// Determine whether this declaration reference refers to anything.
  explicit operator bool() const { return !Data.isNull(); }

  /// Retrieve the declarations to which this reference refers.
  ValueDecl *getDecl() const {
    if (Data.is<ValueDecl *>())
      return Data.get<ValueDecl *>();

    return Data.get<SpecializedDeclRef *>()->getDecl();
  }

  /// Retrieve a reference to the declaration this one overrides.
  ConcreteDeclRef
  getOverriddenDecl(ASTContext &ctx) const;

  /// Determine whether this reference specializes the declaration to which
  /// it refers.
  bool isSpecialized() const { return Data.is<SpecializedDeclRef *>(); }

  /// For a specialized reference, return the set of substitutions applied to
  /// the declaration reference.
  SubstitutionList getSubstitutions() const {
    if (!isSpecialized())
      return { };
    
    return Data.get<SpecializedDeclRef *>()->getSubstitutions();
  }

  bool operator==(ConcreteDeclRef rhs) const {
    return Data == rhs.Data;
  }
  
  /// Dump a debug representation of this reference.
  void dump(raw_ostream &os);
  void dump() LLVM_ATTRIBUTE_USED;
};

} // end namespace swift

namespace llvm {
  template<> class PointerLikeTypeTraits<swift::ConcreteDeclRef> {
    typedef llvm::PointerUnion<swift::ValueDecl *,
                               swift::ConcreteDeclRef::SpecializedDeclRef *>
      DataPointer;
    typedef PointerLikeTypeTraits<DataPointer> DataTraits;

  public:
    static inline void *
    getAsVoidPointer(swift::ConcreteDeclRef ref) {
      return ref.Data.getOpaqueValue();
    }

    static inline swift::ConcreteDeclRef getFromVoidPointer(void *ptr) {
      swift::ConcreteDeclRef ref;
      ref.Data = DataPointer::getFromOpaqueValue(ptr);
      return ref;
    }

    enum {
      NumLowBitsAvailable = DataTraits::NumLowBitsAvailable
    };
  };
} // end namespace llvm

#endif
