//===- Scope.h - Scope interface --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
//  This file defines the Scope interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_SCOPE_H
#define LLVM_CLANG_SEMA_SCOPE_H

#include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include <cassert>

namespace llvm {

class raw_ostream;

} // namespace llvm

namespace clang {

class Decl;
class DeclContext;
class UsingDirectiveDecl;
class VarDecl;

/// Scope - A scope is a transient data structure that is used while parsing the
/// program.  It assists with resolving identifiers to the appropriate
/// declaration.
class Scope {
public:
  /// ScopeFlags - These are bitfields that are or'd together when creating a
  /// scope, which defines the sorts of things the scope contains.
  enum ScopeFlags {
    /// This indicates that the scope corresponds to a function, which
    /// means that labels are set here.
    FnScope       = 0x01,

    /// This is a while, do, switch, for, etc that can have break
    /// statements embedded into it.
    BreakScope    = 0x02,

    /// This is a while, do, for, which can have continue statements
    /// embedded into it.
    ContinueScope = 0x04,

    /// This is a scope that can contain a declaration.  Some scopes
    /// just contain loop constructs but don't contain decls.
    DeclScope = 0x08,

    /// The controlling scope in a if/switch/while/for statement.
    ControlScope = 0x10,

    /// The scope of a struct/union/class definition.
    ClassScope = 0x20,

    /// This is a scope that corresponds to a block/closure object.
    /// Blocks serve as top-level scopes for some objects like labels, they
    /// also prevent things like break and continue.  BlockScopes always have
    /// the FnScope and DeclScope flags set as well.
    BlockScope = 0x40,

    /// This is a scope that corresponds to the
    /// template parameters of a C++ template. Template parameter
    /// scope starts at the 'template' keyword and ends when the
    /// template declaration ends.
    TemplateParamScope = 0x80,

    /// This is a scope that corresponds to the
    /// parameters within a function prototype.
    FunctionPrototypeScope = 0x100,

    /// This is a scope that corresponds to the parameters within
    /// a function prototype for a function declaration (as opposed to any
    /// other kind of function declarator). Always has FunctionPrototypeScope
    /// set as well.
    FunctionDeclarationScope = 0x200,

    /// This is a scope that corresponds to the Objective-C
    /// \@catch statement.
    AtCatchScope = 0x400,

    /// This scope corresponds to an Objective-C method body.
    /// It always has FnScope and DeclScope set as well.
    ObjCMethodScope = 0x800,

    /// This is a scope that corresponds to a switch statement.
    SwitchScope = 0x1000,

    /// This is the scope of a C++ try statement.
    TryScope = 0x2000,

    /// This is the scope for a function-level C++ try or catch scope.
    FnTryCatchScope = 0x4000,

    /// This is the scope of OpenMP executable directive.
    OpenMPDirectiveScope = 0x8000,

    /// This is the scope of some OpenMP loop directive.
    OpenMPLoopDirectiveScope = 0x10000,

    /// This is the scope of some OpenMP simd directive.
    /// For example, it is used for 'omp simd', 'omp for simd'.
    /// This flag is propagated to children scopes.
    OpenMPSimdDirectiveScope = 0x20000,

    /// This scope corresponds to an enum.
    EnumScope = 0x40000,

    /// This scope corresponds to an SEH try.
    SEHTryScope = 0x80000,

    /// This scope corresponds to an SEH except.
    SEHExceptScope = 0x100000,

    /// We are currently in the filter expression of an SEH except block.
    SEHFilterScope = 0x200000,

    /// This is a compound statement scope.
    CompoundStmtScope = 0x400000,

    /// We are between inheritance colon and the real class/struct definition
    /// scope.
    ClassInheritanceScope = 0x800000,

    /// This is the scope of a C++ catch statement.
    CatchScope = 0x1000000,

    /// This is a scope in which a condition variable is currently being
    /// parsed. If such a scope is a ContinueScope, it's invalid to jump to the
    /// continue block from here.
    ConditionVarScope = 0x2000000,
  };

private:
  /// The parent scope for this scope.  This is null for the translation-unit
  /// scope.
  Scope *AnyParent;

  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
  /// interrelates with other control flow statements.
  unsigned Flags;

  /// Depth - This is the depth of this scope.  The translation-unit scope has
  /// depth 0.
  unsigned short Depth;

  /// Declarations with static linkage are mangled with the number of
  /// scopes seen as a component.
  unsigned short MSLastManglingNumber;

  unsigned short MSCurManglingNumber;

  /// PrototypeDepth - This is the number of function prototype scopes
  /// enclosing this scope, including this scope.
  unsigned short PrototypeDepth;

  /// PrototypeIndex - This is the number of parameters currently
  /// declared in this scope.
  unsigned short PrototypeIndex;

  /// FnParent - If this scope has a parent scope that is a function body, this
  /// pointer is non-null and points to it.  This is used for label processing.
  Scope *FnParent;
  Scope *MSLastManglingParent;

  /// BreakParent/ContinueParent - This is a direct link to the innermost
  /// BreakScope/ContinueScope which contains the contents of this scope
  /// for control flow purposes (and might be this scope itself), or null
  /// if there is no such scope.
  Scope *BreakParent, *ContinueParent;

  /// BlockParent - This is a direct link to the immediately containing
  /// BlockScope if this scope is not one, or null if there is none.
  Scope *BlockParent;

  /// TemplateParamParent - This is a direct link to the
  /// immediately containing template parameter scope. In the
  /// case of nested templates, template parameter scopes can have
  /// other template parameter scopes as parents.
  Scope *TemplateParamParent;

  /// DeclsInScope - This keeps track of all declarations in this scope.  When
  /// the declaration is added to the scope, it is set as the current
  /// declaration for the identifier in the IdentifierTable.  When the scope is
  /// popped, these declarations are removed from the IdentifierTable's notion
  /// of current declaration.  It is up to the current Action implementation to
  /// implement these semantics.
  using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
  DeclSetTy DeclsInScope;

  /// The DeclContext with which this scope is associated. For
  /// example, the entity of a class scope is the class itself, the
  /// entity of a function scope is a function, etc.
  DeclContext *Entity;

  using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
  UsingDirectivesTy UsingDirectives;

  /// Used to determine if errors occurred in this scope.
  DiagnosticErrorTrap ErrorTrap;

  /// A lattice consisting of undefined, a single NRVO candidate variable in
  /// this scope, or over-defined. The bit is true when over-defined.
  llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;

  void setFlags(Scope *Parent, unsigned F);

public:
  Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
      : ErrorTrap(Diag) {
    Init(Parent, ScopeFlags);
  }

  /// getFlags - Return the flags for this scope.
  unsigned getFlags() const { return Flags; }

  void setFlags(unsigned F) { setFlags(getParent(), F); }

  /// isBlockScope - Return true if this scope correspond to a closure.
  bool isBlockScope() const { return Flags & BlockScope; }

  /// getParent - Return the scope that this is nested in.
  const Scope *getParent() const { return AnyParent; }
  Scope *getParent() { return AnyParent; }

  /// getFnParent - Return the closest scope that is a function body.
  const Scope *getFnParent() const { return FnParent; }
  Scope *getFnParent() { return FnParent; }

  const Scope *getMSLastManglingParent() const {
    return MSLastManglingParent;
  }
  Scope *getMSLastManglingParent() { return MSLastManglingParent; }

  /// getContinueParent - Return the closest scope that a continue statement
  /// would be affected by.
  Scope *getContinueParent() {
    return ContinueParent;
  }

  const Scope *getContinueParent() const {
    return const_cast<Scope*>(this)->getContinueParent();
  }

  // Set whether we're in the scope of a condition variable, where 'continue'
  // is disallowed despite being a continue scope.
  void setIsConditionVarScope(bool InConditionVarScope) {
    Flags = (Flags & ~ConditionVarScope) |
            (InConditionVarScope ? ConditionVarScope : 0);
  }

  bool isConditionVarScope() const {
    return Flags & ConditionVarScope;
  }

  /// getBreakParent - Return the closest scope that a break statement
  /// would be affected by.
  Scope *getBreakParent() {
    return BreakParent;
  }
  const Scope *getBreakParent() const {
    return const_cast<Scope*>(this)->getBreakParent();
  }

  Scope *getBlockParent() { return BlockParent; }
  const Scope *getBlockParent() const { return BlockParent; }

  Scope *getTemplateParamParent() { return TemplateParamParent; }
  const Scope *getTemplateParamParent() const { return TemplateParamParent; }

  /// Returns the depth of this scope. The translation-unit has scope depth 0.
  unsigned getDepth() const { return Depth; }

  /// Returns the number of function prototype scopes in this scope
  /// chain.
  unsigned getFunctionPrototypeDepth() const {
    return PrototypeDepth;
  }

  /// Return the number of parameters declared in this function
  /// prototype, increasing it by one for the next call.
  unsigned getNextFunctionPrototypeIndex() {
    assert(isFunctionPrototypeScope());
    return PrototypeIndex++;
  }

  using decl_range = llvm::iterator_range<DeclSetTy::iterator>;

  decl_range decls() const {
    return decl_range(DeclsInScope.begin(), DeclsInScope.end());
  }

  bool decl_empty() const { return DeclsInScope.empty(); }

  void AddDecl(Decl *D) {
    DeclsInScope.insert(D);
  }

  void RemoveDecl(Decl *D) {
    DeclsInScope.erase(D);
  }

  void incrementMSManglingNumber() {
    if (Scope *MSLMP = getMSLastManglingParent()) {
      MSLMP->MSLastManglingNumber += 1;
      MSCurManglingNumber += 1;
    }
  }

  void decrementMSManglingNumber() {
    if (Scope *MSLMP = getMSLastManglingParent()) {
      MSLMP->MSLastManglingNumber -= 1;
      MSCurManglingNumber -= 1;
    }
  }

  unsigned getMSLastManglingNumber() const {
    if (const Scope *MSLMP = getMSLastManglingParent())
      return MSLMP->MSLastManglingNumber;
    return 1;
  }

  unsigned getMSCurManglingNumber() const {
    return MSCurManglingNumber;
  }

  /// isDeclScope - Return true if this is the scope that the specified decl is
  /// declared in.
  bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; }

  /// Get the entity corresponding to this scope.
  DeclContext *getEntity() const {
    return isTemplateParamScope() ? nullptr : Entity;
  }

  /// Get the DeclContext in which to continue unqualified lookup after a
  /// lookup in this scope.
  DeclContext *getLookupEntity() const { return Entity; }

  void setEntity(DeclContext *E) {
    assert(!isTemplateParamScope() &&
           "entity associated with template param scope");
    Entity = E;
  }
  void setLookupEntity(DeclContext *E) { Entity = E; }

  /// Determine whether any unrecoverable errors have occurred within this
  /// scope. Note that this may return false even if the scope contains invalid
  /// declarations or statements, if the errors for those invalid constructs
  /// were suppressed because some prior invalid construct was referenced.
  bool hasUnrecoverableErrorOccurred() const {
    return ErrorTrap.hasUnrecoverableErrorOccurred();
  }

  /// isFunctionScope() - Return true if this scope is a function scope.
  bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }

  /// isClassScope - Return true if this scope is a class/struct/union scope.
  bool isClassScope() const {
    return (getFlags() & Scope::ClassScope);
  }

  /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
  /// method scope or is inside one.
  bool isInCXXInlineMethodScope() const {
    if (const Scope *FnS = getFnParent()) {
      assert(FnS->getParent() && "TUScope not created?");
      return FnS->getParent()->isClassScope();
    }
    return false;
  }

  /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
  /// Objective-C method body.  Note that this method is not constant time.
  bool isInObjcMethodScope() const {
    for (const Scope *S = this; S; S = S->getParent()) {
      // If this scope is an objc method scope, then we succeed.
      if (S->getFlags() & ObjCMethodScope)
        return true;
    }
    return false;
  }

  /// isInObjcMethodOuterScope - Return true if this scope is an
  /// Objective-C method outer most body.
  bool isInObjcMethodOuterScope() const {
    if (const Scope *S = this) {
      // If this scope is an objc method scope, then we succeed.
      if (S->getFlags() & ObjCMethodScope)
        return true;
    }
    return false;
  }

  /// isTemplateParamScope - Return true if this scope is a C++
  /// template parameter scope.
  bool isTemplateParamScope() const {
    return getFlags() & Scope::TemplateParamScope;
  }

  /// isFunctionPrototypeScope - Return true if this scope is a
  /// function prototype scope.
  bool isFunctionPrototypeScope() const {
    return getFlags() & Scope::FunctionPrototypeScope;
  }

  /// isFunctionDeclarationScope - Return true if this scope is a
  /// function prototype scope.
  bool isFunctionDeclarationScope() const {
    return getFlags() & Scope::FunctionDeclarationScope;
  }

  /// isAtCatchScope - Return true if this scope is \@catch.
  bool isAtCatchScope() const {
    return getFlags() & Scope::AtCatchScope;
  }

  /// isSwitchScope - Return true if this scope is a switch scope.
  bool isSwitchScope() const {
    for (const Scope *S = this; S; S = S->getParent()) {
      if (S->getFlags() & Scope::SwitchScope)
        return true;
      else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
                                Scope::BlockScope | Scope::TemplateParamScope |
                                Scope::FunctionPrototypeScope |
                                Scope::AtCatchScope | Scope::ObjCMethodScope))
        return false;
    }
    return false;
  }

  /// Determines whether this scope is the OpenMP directive scope
  bool isOpenMPDirectiveScope() const {
    return (getFlags() & Scope::OpenMPDirectiveScope);
  }

  /// Determine whether this scope is some OpenMP loop directive scope
  /// (for example, 'omp for', 'omp simd').
  bool isOpenMPLoopDirectiveScope() const {
    if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
      assert(isOpenMPDirectiveScope() &&
             "OpenMP loop directive scope is not a directive scope");
      return true;
    }
    return false;
  }

  /// Determine whether this scope is (or is nested into) some OpenMP
  /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
  bool isOpenMPSimdDirectiveScope() const {
    return getFlags() & Scope::OpenMPSimdDirectiveScope;
  }

  /// Determine whether this scope is a loop having OpenMP loop
  /// directive attached.
  bool isOpenMPLoopScope() const {
    const Scope *P = getParent();
    return P && P->isOpenMPLoopDirectiveScope();
  }

  /// Determine whether this scope is a C++ 'try' block.
  bool isTryScope() const { return getFlags() & Scope::TryScope; }

  /// Determine whether this scope is a SEH '__try' block.
  bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }

  /// Determine whether this scope is a SEH '__except' block.
  bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }

  /// Determine whether this scope is a compound statement scope.
  bool isCompoundStmtScope() const {
    return getFlags() & Scope::CompoundStmtScope;
  }

  /// Returns if rhs has a higher scope depth than this.
  ///
  /// The caller is responsible for calling this only if one of the two scopes
  /// is an ancestor of the other.
  bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }

  /// containedInPrototypeScope - Return true if this or a parent scope
  /// is a FunctionPrototypeScope.
  bool containedInPrototypeScope() const;

  void PushUsingDirective(UsingDirectiveDecl *UDir) {
    UsingDirectives.push_back(UDir);
  }

  using using_directives_range =
      llvm::iterator_range<UsingDirectivesTy::iterator>;

  using_directives_range using_directives() {
    return using_directives_range(UsingDirectives.begin(),
                                  UsingDirectives.end());
  }

  void addNRVOCandidate(VarDecl *VD) {
    if (NRVO.getInt())
      return;
    if (NRVO.getPointer() == nullptr) {
      NRVO.setPointer(VD);
      return;
    }
    if (NRVO.getPointer() != VD)
      setNoNRVO();
  }

  void setNoNRVO() {
    NRVO.setInt(true);
    NRVO.setPointer(nullptr);
  }

  void mergeNRVOIntoParent();

  /// Init - This is used by the parser to implement scope caching.
  void Init(Scope *parent, unsigned flags);

  /// Sets up the specified scope flags and adjusts the scope state
  /// variables accordingly.
  void AddFlags(unsigned Flags);

  void dumpImpl(raw_ostream &OS) const;
  void dump() const;
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_SCOPE_H
