blob: 21068786ef5a6725d7a4c80723ef480f7a6f009f [file] [log] [blame]
//===--- Scope.h - Declarations for scope RAII objects ----------*- 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 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