//===--- Scope.h - Declarations for scope RAII objects ----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the Scope and FullExpr RAII objects.
//
//===----------------------------------------------------------------------===//

#ifndef SCOPE_H
#define SCOPE_H

#include "SILGenFunction.h"
#include "swift/SIL/SILDebugScope.h"
#include "Cleanup.h"

namespace swift {
namespace Lowering {

/// A Scope is a RAII object recording that a scope (e.g. a brace
/// statement) has been entered.
class LLVM_LIBRARY_VISIBILITY Scope {
  CleanupManager &Cleanups;
  CleanupsDepth Depth;
  CleanupsDepth SavedInnermostScope;
  CleanupLocation Loc;

  void popImpl() {
    Cleanups.Stack.checkIterator(Depth);
    Cleanups.Stack.checkIterator(Cleanups.InnermostScope);
    assert(Cleanups.InnermostScope == Depth && "popping scopes out of order");

    Cleanups.InnermostScope = SavedInnermostScope;
    Cleanups.endScope(Depth, Loc);
    Cleanups.Stack.checkIterator(Cleanups.InnermostScope);
    Cleanups.popTopDeadCleanups(Cleanups.InnermostScope);
  }

public:
  explicit Scope(CleanupManager &Cleanups, CleanupLocation L)
    : Cleanups(Cleanups), Depth(Cleanups.getCleanupsDepth()),
      SavedInnermostScope(Cleanups.InnermostScope),
      Loc(L) {
    assert(Depth.isValid());
    Cleanups.Stack.checkIterator(Cleanups.InnermostScope);
    Cleanups.InnermostScope = Depth;
  }

  void pop() {
    assert(Depth.isValid() && "popping a scope twice!");
    popImpl();
    Depth = CleanupsDepth::invalid();
  }
  
  ~Scope() {
    if (Depth.isValid()) popImpl();
  }
};

/// A FullExpr is a RAII object recording that a full-expression has
/// been entered.  A full-expression is essentially a very small scope
/// for the temporaries in an expression, with the added complexity
/// that (eventually, very likely) we have to deal with expressions
/// that are only conditionally evaluated.
class LLVM_LIBRARY_VISIBILITY FullExpr : private Scope {
public:
  explicit FullExpr(CleanupManager &Cleanups, CleanupLocation Loc)
    : Scope(Cleanups, Loc) {}
  using Scope::pop;
};

/// A LexicalScope is a Scope that is also exposed to the debug info.
class LLVM_LIBRARY_VISIBILITY LexicalScope : private Scope {
  SILGenFunction& SGF;
public:
  explicit LexicalScope(CleanupManager &Cleanups,
                        SILGenFunction& SGF,
                        CleanupLocation Loc)
    : Scope(Cleanups, Loc), SGF(SGF) {
    SGF.enterDebugScope(Loc);
  }
  using Scope::pop;

  ~LexicalScope() {
    SGF.leaveDebugScope();
  }
};

/// A scope that only exists in the debug info.
class LLVM_LIBRARY_VISIBILITY DebugScope {
  SILGenFunction &SGF;

public:
  explicit DebugScope(SILGenFunction &SGF, CleanupLocation Loc) : SGF(SGF) {
    SGF.enterDebugScope(Loc);
  }

  ~DebugScope() { SGF.leaveDebugScope(); }
};

} // end namespace Lowering
} // end namespace swift

#endif
