//===--- DeclContext.h - Swift Language Context ASTs ------------*- 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 DeclContext class.  A DeclContext is the semantic
// construct that a declaration belongs to, such as the enclosing
// AbstractClosureExpr or declaration.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_DECLCONTEXT_H
#define SWIFT_DECLCONTEXT_H

#include "swift/AST/Identifier.h"
#include "swift/AST/LookupKinds.h"
#include "swift/AST/ResilienceExpansion.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/PointerEmbeddedInt.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/raw_ostream.h"

#include <type_traits>

namespace llvm {
  class raw_ostream;
}

namespace swift {
  class AbstractFunctionDecl;
  class GenericEnvironment;
  class ASTContext;
  class ASTWalker;
  class CanType;
  class Decl;
  class DeclContext;
  class EnumDecl;
  class ExtensionDecl;
  class Expr;
  class GenericParamList;
  class LazyResolver;
  class LazyMemberLoader;
  class GenericSignature;
  class GenericTypeParamDecl;
  class GenericTypeParamType;
  class ProtocolDecl;
  class Requirement;
  class SourceFile;
  class Type;
  class ModuleDecl;
  class GenericTypeDecl;
  class NominalTypeDecl;
  class ProtocolConformance;
  class ValueDecl;
  class Initializer;
  class ClassDecl;
  class SerializedAbstractClosureExpr;
  class SerializedPatternBindingInitializer;
  class SerializedDefaultArgumentInitializer;
  class SerializedTopLevelCodeDecl;
  class StructDecl;

namespace serialization {
using DeclID = llvm::PointerEmbeddedInt<unsigned, 31>;
}

enum class DeclContextKind : unsigned {
  AbstractClosureExpr,
  Initializer,
  TopLevelCodeDecl,
  SubscriptDecl,
  EnumElementDecl,
  AbstractFunctionDecl,
  SerializedLocal,
  Last_LocalDeclContextKind = SerializedLocal,

  Module,
  FileUnit,
  GenericTypeDecl,
  ExtensionDecl,
  Last_DeclContextKind = ExtensionDecl
};

/// Kinds of DeclContexts after deserialization.
///
/// \see SerializedLocalDeclContext.
enum class LocalDeclContextKind : uint8_t {
  AbstractClosure,
  PatternBindingInitializer,
  DefaultArgumentInitializer,
  TopLevelCodeDecl
};

/// Describes the kind of a particular conformance.
///
/// The following code involves conformances of the three different kinds:
/// \code
/// protocol P { }
/// protocol P2 : P { }
///
/// class Super : P2 { }
/// class Sub : Super { }
/// \endcode
///
/// \c Super conforms to \c P2 via an explicit conformance,
/// specified on the class declaration itself.
///
/// \c Super conforms to \c P via an implied conformance, whose
/// origin is the explicit conformance to \c P2.
///
/// \c Sub conforms to \c P2 and \c P via inherited conformances,
/// which link back to the conformances described above.
///
/// The enumerators are ordered in terms of decreasing preference:
/// an inherited conformance is best, followed by explicit
/// conformances, then synthesized and implied conformances. Earlier
/// conformance kinds supersede later conformance kinds, possibly with a
/// diagnostic (e.g., if an inherited conformance supersedes an
/// explicit conformance).
enum class ConformanceEntryKind : unsigned {
  /// Inherited from a superclass conformance.
  Inherited,

  /// Explicitly specified.
  Explicit,

  /// Implicitly synthesized.
  Synthesized,

  /// Implied by an explicitly-specified conformance.
  Implied,
};

/// Describes the kind of conformance lookup desired.
enum class ConformanceLookupKind : unsigned {
  /// All conformances.
  All,
  /// Only the explicit conformance.
  OnlyExplicit,
  /// All conformances except for inherited ones.
  NonInherited,
};

/// Describes a diagnostic for a conflict between two protocol
/// conformances.
struct ConformanceDiagnostic {
  /// The protocol with conflicting conformances.
  ProtocolDecl *Protocol;

  /// The location at which the diagnostic should occur.
  SourceLoc Loc;

  /// The kind of conformance that was superseded.
  ConformanceEntryKind Kind;

  /// The explicitly-specified protocol whose conformance implied the
  /// conflicting conformance.
  ProtocolDecl *ExplicitProtocol;

  /// The declaration context that declares the existing conformance.
  DeclContext *ExistingDC;

  /// The kind of existing conformance.
  ConformanceEntryKind ExistingKind;

  /// The explicitly-specified protocol whose conformance implied the
  /// existing conflicting conformance.
  ProtocolDecl *ExistingExplicitProtocol;
};

/// A DeclContext is an AST object which acts as a semantic container
/// for declarations.  As a policy matter, we currently define
/// contexts broadly: a lambda expression in a function is a new
/// DeclContext, but a new brace statement is not.  There's no
/// particular mandate for this, though.
///
/// Please note that DeclContext assumes that it prefaces AST type hierarchies
/// and therefore can safely access trailing memory. If you need to create a
/// macro context, please see GenericContext for how to minimize new entries in
/// the ASTHierarchy enum below.
class alignas(1 << DeclContextAlignInBits) DeclContext {
  enum class ASTHierarchy : unsigned {
    Decl,
    Expr,
    FileUnit,
    Initializer,
    SerializedLocal,
    // If you add a new AST hierarchies, then update the static_assert() below.
  };
  static_assert(unsigned(ASTHierarchy::SerializedLocal) <
                (1 << DeclContextAlignInBits),
                "ASTHierarchy exceeds bits available");

  llvm::PointerIntPair<DeclContext*, 3, ASTHierarchy> ParentAndKind;

  /// Change the parent of this context.  This should only be used
  /// very carefully.
  void setParent(DeclContext *parent) { ParentAndKind.setPointer(parent); }
  friend class Initializer; // uses setParent
  friend class AutoClosureExpr; // uses setParent
  friend class AbstractClosureExpr; // uses setParent
  
  template<class A, class B, class C>
  friend struct ::llvm::cast_convert_val;
  
  // See swift/AST/Decl.h
  static DeclContext *castDeclToDeclContext(const Decl *D);

  /// If this DeclContext is a GenericType declaration or an
  /// extension thereof, return the GenericTypeDecl.
  GenericTypeDecl *getSelfTypeDecl() const;

  static ASTHierarchy getASTHierarchyFromKind(DeclContextKind Kind) {
    switch (Kind) {
    case DeclContextKind::AbstractClosureExpr:
      return ASTHierarchy::Expr;
    case DeclContextKind::Initializer:
      return ASTHierarchy::Initializer;
    case DeclContextKind::SerializedLocal:
      return ASTHierarchy::SerializedLocal;
    case DeclContextKind::FileUnit:
      return ASTHierarchy::FileUnit;
    case DeclContextKind::Module:
    case DeclContextKind::TopLevelCodeDecl:
    case DeclContextKind::AbstractFunctionDecl:
    case DeclContextKind::SubscriptDecl:
    case DeclContextKind::EnumElementDecl:
    case DeclContextKind::GenericTypeDecl:
    case DeclContextKind::ExtensionDecl:
      return ASTHierarchy::Decl;
    }
    llvm_unreachable("Unhandled DeclContextKind");
  }

public:
  LLVM_READONLY
  Decl *getAsDecl() {
    return ParentAndKind.getInt() == ASTHierarchy::Decl ?
      reinterpret_cast<Decl*>(this + 1) : nullptr;
  }
  const Decl *getAsDecl() const {
    return const_cast<DeclContext*>(this)->getAsDecl();
  }

  DeclContext(DeclContextKind Kind, DeclContext *Parent)
      : ParentAndKind(Parent, getASTHierarchyFromKind(Kind)) {
    if (Kind != DeclContextKind::Module)
      assert(Parent != nullptr && "DeclContext must have a parent context");
  }

  /// Returns the kind of context this is.
  DeclContextKind getContextKind() const;

  /// Returns whether this context has value semantics.
  bool hasValueSemantics() const;

  /// Determines whether this context is itself a local scope in a
  /// code block.  A context that appears in such a scope, like a
  /// local type declaration, does not itself become a local context.
  bool isLocalContext() const {
    return getContextKind() <= DeclContextKind::Last_LocalDeclContextKind;
  }
  
  /// isModuleContext - Return true if this is a subclass of Module.
  LLVM_READONLY
  bool isModuleContext() const; // see swift/AST/Module.h

  /// \returns true if this is a context with module-wide scope, e.g. a module
  /// or a source file.
  LLVM_READONLY
  bool isModuleScopeContext() const; // see swift/AST/Module.h

  /// \returns true if this is a type context, e.g., a struct, a class, an
  /// enum, a protocol, or an extension.
  LLVM_READONLY
  bool isTypeContext() const;

  /// If this DeclContext is a NominalType declaration or an
  /// extension thereof, return the NominalTypeDecl.
  LLVM_READONLY
  NominalTypeDecl *getSelfNominalTypeDecl() const;

  /// If this DeclContext is a class, or an extension on a class, return the
  /// ClassDecl, otherwise return null.
  LLVM_READONLY
  ClassDecl *getSelfClassDecl() const;

  /// If this DeclContext is an enum, or an extension on an enum, return the
  /// EnumDecl, otherwise return null.
  LLVM_READONLY
  EnumDecl *getSelfEnumDecl() const;

  /// If this DeclContext is a struct, or an extension on a struct, return the
  /// StructDecl, otherwise return null.
  LLVM_READONLY
  StructDecl *getSelfStructDecl() const;

  /// If this DeclContext is a protocol, or an extension on a
  /// protocol, return the ProtocolDecl, otherwise return null.
  LLVM_READONLY
  ProtocolDecl *getSelfProtocolDecl() const;

  /// If this DeclContext is a protocol extension, return the extended protocol.
  LLVM_READONLY
  ProtocolDecl *getExtendedProtocolDecl() const;

  /// Retrieve the generic parameter 'Self' from a protocol or
  /// protocol extension.
  ///
  /// Only valid if \c getSelfProtocolDecl().
  GenericTypeParamType *getProtocolSelfType() const;

  /// Gets the type being declared by this context.
  ///
  /// - Generic types return a bound generic type using archetypes.
  /// - Non-type contexts return a null type.
  Type getDeclaredTypeInContext() const;
  
  /// Gets the type being declared by this context.
  ///
  /// - Generic types return a bound generic type using interface types.
  /// - Non-type contexts return a null type.
  Type getDeclaredInterfaceType() const;

  /// Get the type of `self` in this context.
  ///
  /// - Protocol types return the `Self` archetype.
  /// - Everything else falls back on getDeclaredTypeInContext().
  Type getSelfTypeInContext() const;

  /// Get the type of `self` in this context.
  ///
  /// - Protocol types return the `Self` interface type.
  /// - Everything else falls back on getDeclaredInterfaceType().
  Type getSelfInterfaceType() const;

  /// Visit the generic parameter list of every outer context, innermost first.
  void forEachGenericContext(
    llvm::function_ref<void (GenericParamList *)> fn) const;

  /// Returns the depth of this generic context, or in other words,
  /// the number of nested generic contexts minus one.
  ///
  /// This is (unsigned)-1 if none of the outer contexts are generic.
  unsigned getGenericContextDepth() const;

  /// Retrieve the innermost generic signature of this context or any
  /// of its parents.
  GenericSignature getGenericSignatureOfContext() const;

  /// Retrieve the innermost archetypes of this context or any
  /// of its parents.
  GenericEnvironment *getGenericEnvironmentOfContext() const;

  /// Map an interface type to a contextual type within this context.
  Type mapTypeIntoContext(Type type) const;

  /// Returns this or the first local parent context, or nullptr if it is not
  /// contained in one.
  LLVM_READONLY
  DeclContext *getLocalContext();
  const DeclContext *getLocalContext() const {
    return const_cast<DeclContext*>(this)->getLocalContext();
  }

  /// Returns the innermost method context.
  ///
  /// This routine looks through closure, initializer, and local function
  /// contexts to find the innermost method (including constructors and
  /// destructors).
  ///
  /// \returns the innermost method, or null if there is no such method.
  LLVM_READONLY
  AbstractFunctionDecl *getInnermostMethodContext();
  const AbstractFunctionDecl *getInnermostMethodContext() const {
    return const_cast<DeclContext*>(this)->getInnermostMethodContext();
  }

  /// Returns the innermost type context.
  ///
  /// This routine looks through closure, initializer, and local function
  /// contexts to find the innermost type context -- nominal type or
  /// extension.
  LLVM_READONLY
  DeclContext *getInnermostTypeContext();
  const DeclContext *getInnermostTypeContext() const {
    return const_cast<DeclContext *>(this)->getInnermostTypeContext();
  }

  /// Returns the innermost context that is a declaration.
  ///
  /// This routine looks through contexts to find the innermost
  /// declaration context that is itself a declaration.
  LLVM_READONLY
  Decl *getInnermostDeclarationDeclContext();
  const Decl *getInnermostDeclarationDeclContext() const {
    return
        const_cast<DeclContext *>(this)->getInnermostDeclarationDeclContext();
  }

  /// Returns the innermost context that is an AbstractFunctionDecl whose
  /// body has been skipped.
  LLVM_READONLY
  DeclContext *getInnermostSkippedFunctionContext();
  const DeclContext *getInnermostSkippedFunctionContext() const {
    return
        const_cast<DeclContext *>(this)->getInnermostSkippedFunctionContext();
  }

  /// Returns the semantic parent of this context.  A context has a
  /// parent if and only if it is not a module context.
  DeclContext *getParent() const {
    return ParentAndKind.getPointer();
  }

  /// Returns the semantic parent for purposes of name lookup.
  DeclContext *getParentForLookup() const;

  /// Return true if this is a child of the specified other decl context.
  bool isChildContextOf(const DeclContext *Other) const {
    if (this == Other) return false;

    for (const DeclContext *CurContext = this; CurContext;
         CurContext = CurContext->getParent())
      if (CurContext == Other)
        return true;
    return false;
  }

  /// Returns the module context that contains this context.
  LLVM_READONLY
  ModuleDecl *getParentModule() const;

  /// Returns the module scope context that contains this context.
  ///
  /// This is either a \c Module or a \c FileUnit.
  LLVM_READONLY
  DeclContext *getModuleScopeContext() const;

  /// Returns the source file that contains this context, or null if this
  /// is not within a source file.
  LLVM_READONLY
  SourceFile *getParentSourceFile() const;

  /// Determine whether this declaration context is generic, meaning that it or
  /// any of its parents have generic parameters.
  bool isGenericContext() const;

  /// Determine whether the innermost context is generic.
  bool isInnermostContextGeneric() const;

  /// Get the most optimal resilience expansion for code in this context.
  /// If the body is able to be inlined into functions in other resilience
  /// domains, this ensures that only sufficiently-conservative access patterns
  /// are used.
  ResilienceExpansion getResilienceExpansion() const;

  /// Returns true if this context may possibly contain members visible to
  /// AnyObject dynamic lookup.
  bool mayContainMembersAccessedByDynamicLookup() const;

  /// Extensions are only allowed at the level in a file
  /// FIXME: do this for Protocols, too someday
  bool canBeParentOfExtension() const;

  /// Returns true if lookups within this context could affect downstream files.
  ///
  /// \param functionsAreNonCascading If true, functions are considered non-
  /// cascading contexts. If false, functions are considered non-cascading only
  /// if implicitly or explicitly marked private. When concerned only with a
  /// function's body, pass true.
  bool isCascadingContextForLookup(bool functionsAreNonCascading) const;

  /// Look for the set of declarations with the given name within a type,
  /// its extensions and, optionally, its supertypes.
  ///
  /// This routine performs name lookup within a given type, its extensions
  /// and, optionally, its supertypes and their extensions, from the perspective
  /// of the current DeclContext. It can eliminate non-visible, hidden, and
  /// overridden declarations from the result set. It does not, however, perform
  /// any filtering based on the semantic usefulness of the results.
  ///
  /// \param type The type to look into.
  ///
  /// \param member The member to search for.
  ///
  /// \param options Options that control name lookup, based on the
  /// \c NL_* constants in \c NameLookupOptions.
  ///
  /// \param[out] decls Will be populated with the declarations found by name
  /// lookup.
  ///
  /// \returns true if anything was found.
  bool lookupQualified(Type type, DeclName member, NLOptions options,
                       SmallVectorImpl<ValueDecl *> &decls) const;

  /// Look for the set of declarations with the given name within the
  /// given set of nominal type declarations.
  ///
  /// \param types The type declarations to look into.
  ///
  /// \param member The member to search for.
  ///
  /// \param options Options that control name lookup, based on the
  /// \c NL_* constants in \c NameLookupOptions.
  ///
  /// \param[out] decls Will be populated with the declarations found by name
  /// lookup.
  ///
  /// \returns true if anything was found.
  bool lookupQualified(ArrayRef<NominalTypeDecl *> types, DeclName member,
                       NLOptions options,
                       SmallVectorImpl<ValueDecl *> &decls) const;

  /// Perform qualified lookup for the given member in the given module.
  bool lookupQualified(ModuleDecl *module, DeclName member, NLOptions options,
                       SmallVectorImpl<ValueDecl *> &decls) const;

  /// Perform \c AnyObject lookup for the given member.
  bool lookupAnyObject(DeclName member, NLOptions options,
                       SmallVectorImpl<ValueDecl *> &decls) const;

  /// Look up all Objective-C methods with the given selector visible
  /// in the enclosing module.
  void lookupAllObjCMethods(
         ObjCSelector selector,
         SmallVectorImpl<AbstractFunctionDecl *> &results) const;

  /// Return the ASTContext for a specified DeclContext by
  /// walking up to the enclosing module and returning its ASTContext.
  LLVM_READONLY
  ASTContext &getASTContext() const;

  /// Retrieve the set of protocols whose conformances will be
  /// associated with this declaration context.
  ///
  /// This function differs from \c getLocalConformances() in that it
  /// returns protocol declarations, not protocol conformances, and
  /// therefore does not require the protocol conformances to be
  /// formed.
  ///
  /// \param lookupKind The kind of lookup to perform.
  ///
  /// \param diagnostics If non-null, will be populated with the set of
  /// diagnostics that should be emitted for this declaration context.
  /// FIXME: This likely makes more sense on IterableDeclContext or
  /// something similar.
  SmallVector<ProtocolDecl *, 2>
  getLocalProtocols(ConformanceLookupKind lookupKind
                      = ConformanceLookupKind::All,
                    SmallVectorImpl<ConformanceDiagnostic> *diagnostics
                      = nullptr) const;

  /// Retrieve the set of protocol conformances associated with this
  /// declaration context.
  ///
  /// \param lookupKind The kind of lookup to perform.
  ///
  /// \param diagnostics If non-null, will be populated with the set of
  /// diagnostics that should be emitted for this declaration context.
  ///
  /// FIXME: This likely makes more sense on IterableDeclContext or
  /// something similar.
  SmallVector<ProtocolConformance *, 2>
  getLocalConformances(ConformanceLookupKind lookupKind
                         = ConformanceLookupKind::All,
                       SmallVectorImpl<ConformanceDiagnostic> *diagnostics
                         = nullptr) const;

  /// Retrieve the syntactic depth of this declaration context, i.e.,
  /// the number of non-module-scoped contexts.
  ///
  /// For an extension of a nested type, the extension is depth 1.
  unsigned getSyntacticDepth() const;

  /// Retrieve the semantic depth of this declaration context, i.e.,
  /// the number of non-module-scoped contexts.
  ///
  /// For an extension of a nested type, the depth of the nested type itself
  /// is also included.
  unsigned getSemanticDepth() const;

  /// \returns true if traversal was aborted, false otherwise.
  bool walkContext(ASTWalker &Walker);

  void dumpContext() const;
  unsigned printContext(llvm::raw_ostream &OS, unsigned indent = 0,
                        bool onlyAPartialLine = false) const;

  // Only allow allocation of DeclContext using the allocator in ASTContext.
  void *operator new(size_t Bytes, ASTContext &C,
                     unsigned Alignment = alignof(DeclContext));
  
  // Some Decls are DeclContexts, but not all. See swift/AST/Decl.h
  static bool classof(const Decl *D);
};

/// SerializedLocalDeclContext - the base class for DeclContexts that were
/// serialized to preserve AST structure and accurate mangling after
/// deserialization.
class SerializedLocalDeclContext : public DeclContext {
private:
  unsigned LocalKind : 3;

protected:
  unsigned SpareBits : 29;

public:
  SerializedLocalDeclContext(LocalDeclContextKind LocalKind,
                             DeclContext *Parent)
    : DeclContext(DeclContextKind::SerializedLocal, Parent),
      LocalKind(static_cast<unsigned>(LocalKind)) {}

  LocalDeclContextKind getLocalDeclContextKind() const {
    return static_cast<LocalDeclContextKind>(LocalKind);
  }

  static bool classof(const DeclContext *DC) {
    return DC->getContextKind() == DeclContextKind::SerializedLocal;
  }
};

/// An iterator that walks through a list of declarations stored
/// within some iterable declaration context.
class DeclIterator {
  Decl *Current;

public: 
  typedef std::forward_iterator_tag iterator_category;
  typedef Decl *value_type;
  typedef Decl *reference;
  typedef Decl *pointer; // Non-standard but convenient
  typedef std::ptrdiff_t difference_type;

  DeclIterator(Decl *current = nullptr) : Current(current) { }

  reference operator*() const { return Current; }
  pointer operator->() const { return Current; }

  DeclIterator &operator++();

  DeclIterator operator++(int) {
    DeclIterator old = *this;
    ++*this;
    return old;
  }

  friend bool operator==(DeclIterator lhs, DeclIterator rhs) {
    return lhs.Current == rhs.Current; 
  }

  friend bool operator!=(DeclIterator lhs, DeclIterator rhs) {
    return !(lhs == rhs);
  }
};

/// The range of declarations stored within an iterable declaration
/// context.
typedef IteratorRange<DeclIterator> DeclRange;

/// The kind of an \c IterableDeclContext.
enum class IterableDeclContextKind : uint8_t {  
  NominalTypeDecl = 0,
  ExtensionDecl,
};

/// A declaration context that tracks the declarations it (directly)
/// owns and permits iteration over them.
///
/// Note that an iterable declaration context must inherit from both
/// \c IterableDeclContext and \c DeclContext.
class IterableDeclContext {
  enum LazyMembers : unsigned {
    Present = 1 << 0,

    /// Lazy member loading has a variety of feedback loops that need to
    /// switch to pseudo-empty-member behaviour to avoid infinite recursion;
    /// we use this flag to control them.
    InProgress = 1 << 1,
  };

  /// The first declaration in this context along with a bit indicating whether
  /// the members of this context will be lazily produced.
  mutable llvm::PointerIntPair<Decl *, 2, LazyMembers> FirstDeclAndLazyMembers;

  /// The last declaration in this context, used for efficient insertion,
  /// along with the kind of iterable declaration context.
  mutable llvm::PointerIntPair<Decl *, 1, IterableDeclContextKind>
    LastDeclAndKind;

  /// The DeclID this IDC was deserialized from, if any. Used for named lazy
  /// member loading, as a key when doing lookup in this IDC.
  serialization::DeclID SerialID;

  /// Because \c parseDelayedDecl and lazy member adding can add members *after*
  /// an \c ASTScope tree is created, there must be some way for the tree to
  /// detect when a member has been added. A bit would suffice,
  /// but would be more fragile, The scope code could count the members each
  /// time, but I think it's a better trade to just keep a count here.
  unsigned MemberCount : 29;

  /// Whether we have already added the parsed members into the context.
  unsigned AddedParsedMembers : 1;

  /// Whether delayed parsing detected a possible operator definition
  /// while skipping the body of this context.
  unsigned HasOperatorDeclarations : 1;

  /// Whether delayed parsing detect a possible nested class definition
  /// while skipping the body of this context.
  unsigned HasNestedClassDeclarations : 1;

  template<class A, class B, class C>
  friend struct ::llvm::cast_convert_val;

  static IterableDeclContext *castDeclToIterableDeclContext(const Decl *D);

  /// Retrieve the \c ASTContext in which this iterable context occurs.
  ASTContext &getASTContext() const;

public:
  IterableDeclContext(IterableDeclContextKind kind)
    : LastDeclAndKind(nullptr, kind) {
    MemberCount = 0;
    AddedParsedMembers = 0;
    HasOperatorDeclarations = 0;
    HasNestedClassDeclarations = 0;
  }

  /// Determine the kind of iterable context we have.
  IterableDeclContextKind getIterableContextKind() const {
    return LastDeclAndKind.getInt();
  }

  bool hasUnparsedMembers() const;

  bool maybeHasOperatorDeclarations() const {
    return HasOperatorDeclarations;
  }

  void setMaybeHasOperatorDeclarations() {
    assert(hasUnparsedMembers());
    HasOperatorDeclarations = 1;
  }

  bool maybeHasNestedClassDeclarations() const {
    return HasNestedClassDeclarations;
  }

  void setMaybeHasNestedClassDeclarations() {
    assert(hasUnparsedMembers());
    HasNestedClassDeclarations = 1;
  }

  /// Retrieve the set of members in this context.
  DeclRange getMembers() const;

  /// Retrieve the set of members in this context without loading any from the
  /// associated lazy loader; this should only be used as part of implementing
  /// abstractions on top of member loading, such as a name lookup table.
  DeclRange getCurrentMembersWithoutLoading() const;

  /// Add a member to this context. If the hint decl is specified, the new decl
  /// is inserted immediately after the hint.
  void addMember(Decl *member, Decl *hint = nullptr);

  /// See \c MemberCount
  unsigned getMemberCount() const;

  /// Check whether there are lazily-loaded members.
  bool hasLazyMembers() const {
    return FirstDeclAndLazyMembers.getInt() & LazyMembers::Present;
  }

  bool isLoadingLazyMembers() {
    return FirstDeclAndLazyMembers.getInt() & LazyMembers::InProgress;
  }

  void setLoadingLazyMembers(bool inProgress) {
    LazyMembers status = FirstDeclAndLazyMembers.getInt();
    if (inProgress)
      status = LazyMembers(status | LazyMembers::InProgress);
    else
      status = LazyMembers(status & ~LazyMembers::InProgress);
    FirstDeclAndLazyMembers.setInt(status);
  }

  /// Setup the loader for lazily-loaded members.
  void setMemberLoader(LazyMemberLoader *loader, uint64_t contextData);

  /// Load all of the members of this context.
  void loadAllMembers() const;

  /// Determine whether this was deserialized (and thus SerialID is
  /// valid).
  bool wasDeserialized() const;

  /// Return 'this' as a \c Decl.
  const Decl *getDecl() const;

  /// Get the DeclID this Decl was deserialized from.
  serialization::DeclID getDeclID() const {
    assert(wasDeserialized());
    return SerialID;
  }

  /// Set the DeclID this Decl was deserialized from.
  void setDeclID(serialization::DeclID d) {
    assert(wasDeserialized());
    SerialID = d;
  }

  // Some Decls are IterableDeclContexts, but not all.
  static bool classof(const Decl *D);

private:
  /// Add a member to the list for iteration purposes, but do not notify the
  /// subclass that we have done so.
  ///
  /// This is used internally when loading members, because loading a
  /// member is an invisible addition.
  void addMemberSilently(Decl *member, Decl *hint = nullptr) const;
};

/// Define simple_display for DeclContexts but not for subclasses in order to
/// avoid ambiguities with Decl* arguments.
template <typename ParamT, typename = typename std::enable_if<
                               std::is_same<ParamT, DeclContext>::value>::type>
void simple_display(llvm::raw_ostream &out, const ParamT *dc) {
  if (dc)
    dc->printContext(out, 0, true);
  else
    out << "(null)";
}

void simple_display(llvm::raw_ostream &out, const IterableDeclContext *idc);

/// Extract the source location from the given declaration context.
SourceLoc extractNearestSourceLoc(const DeclContext *dc);

/// Extract the source location from the given declaration context.
SourceLoc extractNearestSourceLoc(const IterableDeclContext *idc);

} // end namespace swift

namespace llvm {
  template<class FromTy>
  struct cast_convert_val< ::swift::DeclContext, FromTy, FromTy> {
    static ::swift::DeclContext *doit(const FromTy &Val) {
      return ::swift::DeclContext::castDeclToDeclContext(Val);
    }
  };

  template<class FromTy>
  struct cast_convert_val< ::swift::IterableDeclContext, FromTy, FromTy> {
    static ::swift::IterableDeclContext *doit(const FromTy &Val) {
      return ::swift::IterableDeclContext::castDeclToIterableDeclContext(Val);
    }
  };
}

#endif
