//===--- 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