Files
swift-mirror/include/swift/SIL/Lifetime.h
John McCall 46be95847b Extract TypeLowering's recursive type properties into a header, add
functions to compute them directly without a TypeLowering object, and
change a lot of getTypeLowering call sites to just use that.

There is one subtle change here that I think is okay: SILBuilder used to
use different TypeExpansionContexts when inserting into a global:
- getTypeLowering() always used a minimal context when inserting into
  a global
- getTypeExpansionContext() always returned a maximal context for the
  module scope
The latter seems more correct, as AFAIK global initializers are never
inlinable. If they are, we probably need to configure the builder with
an actual context properly rather than making global assumptions.

This is incremental progress towards computing this for most types
without a TypeLowering, and hopefully eventually removing TL entirely.
2025-08-01 15:00:57 -04:00

72 lines
2.5 KiB
C++

//===---- Lifetime.h - How long a value should be kept alive ----*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 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
//
//===----------------------------------------------------------------------===//
//
// Defines a simple type-safe wrapper type to indicate the kind of lifetime that
// a value has--whether it is tied to a lexical scope or not.
//
//===----------------------------------------------------------------------===//
#include "swift/AST/LifetimeAnnotation.h"
#ifndef SWIFT_SIL_LIFETIME_H
#define SWIFT_SIL_LIFETIME_H
namespace swift {
/// How long a value (such as instances of a type) should be kept alive--how
/// aggressively its destroys may be hoisted.
///
/// By default, types have lifetimes inferred from their structure, see
/// SILTypeProperties::isLexical. It can be overridden both on
/// the type level and the value level via attributes.
struct Lifetime {
enum Storage : uint8_t {
/// No lifetime. Applicable to values which aren't destroyed.
None,
/// A lifetime independent from the lexical scope of the value: its
/// releases are hoisted without respect to deinit barriers.
EagerMove,
/// A lifetime tied to the lexical scope of the value: its releases are
/// not hoisted over deinit barriers.
Lexical,
} value;
Lifetime(decltype(value) newValue) : value(newValue) {}
operator Storage() const { return value; }
bool isLexical() { return value == Lifetime::Lexical; }
bool isEagerMove() { return value == Lifetime::EagerMove; }
/// Given a lifetime for a type and the lifetime annotation on a value of that
/// type, the lifetime appropriate for that value.
///
/// Value annotations override a type's lifetime, so the result is just the
/// lifetime indicated by the annotation, if there is one; otherwise its the
/// lifetime from the type.
Lifetime getLifetimeForAnnotatedValue(LifetimeAnnotation annotation) const {
switch (annotation) {
case LifetimeAnnotation::None:
return *this;
case LifetimeAnnotation::EagerMove:
return Lifetime::EagerMove;
case LifetimeAnnotation::Lexical:
return Lifetime::Lexical;
}
}
};
} // end swift namespace
#endif