You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
7.1 KiB
197 lines
7.1 KiB
//===--- AMapReferenceStorage.def - Non-default reference storage ---*- C++ -*-===// |
|
// |
|
// This source file is part of the Swift.org open source project |
|
// |
|
// Copyright (c) 2018 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 non-default reference storage kind macros used for |
|
// macro-metaprogramming. |
|
// |
|
//===----------------------------------------------------------------------===// |
|
|
|
/// There are two fundamental reference storage types: checked and unchecked. |
|
/// Checked storage types have runtime enforced correctness. |
|
/// Unchecked storage types have no runtime enforced correctness. |
|
/// |
|
/// Checked reference storage types are also subcategorized by loadability. |
|
/// * Always loadable: The compiler may move the reference or use registers. |
|
/// * Never loadable: The runtime (etc) tracks the address of the reference. |
|
/// * Sometimes loadable: If the reference is a native object, then it is |
|
/// always loadable. Otherwise fall back to never loadable semantics, a.k.a. |
|
/// "address only". |
|
/// |
|
/// Unchecked reference storage types are always loadable. |
|
/// |
|
/// The primary macros therefore are: |
|
/// * ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
|
/// * SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
/// * NEVER_LOADABLE_CHECKED_REF_STORAGE |
|
/// * UNCHECKED_REF_STORAGE |
|
/// |
|
/// Helper macros include: |
|
/// * CHECKED_REF_STORAGE -- Any checked reference storage type. Specifically |
|
/// "always", "sometimes", and "never" -- but not "unchecked". |
|
/// * LOADABLE_REF_STORAGE -- Any loadable reference storage type. Specifically |
|
/// "always", "sometimes", and "unchecked" -- but not "never". |
|
/// * ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE -- self describing. |
|
/// * NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE -- self describing. |
|
/// |
|
/// SUBSYSTEMS NOTES |
|
/// |
|
/// In general, reference storage types are barely visible in the user facing |
|
/// type system and therefore AST clients above SIL can get away with |
|
/// just REF_STORAGE, or CHECKED_REF_STORAGE with UNCHECKED_REF_STORAGE. |
|
/// |
|
/// When it comes to SIL aware AST clients, loadability matters. The best way |
|
/// to understand how the helper macros are used is to look at SILNodes.def. |
|
/// What follows is a short -- possibly not up to date -- summary: |
|
/// |
|
/// UNCHECKED_REF_STORAGE |
|
/// Name##RetainValueInst |
|
/// Name##ReleaseValueInst |
|
/// LOADABLE_REF_STORAGE |
|
/// Ref*ToNameInst |
|
/// Name*ToRefInst |
|
/// NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
/// Load##Name##Inst |
|
/// Store##Name##Inst |
|
/// ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
/// Copy##Name##ValueInst |
|
/// StrongRetain##Name##Inst |
|
/// Name##RetainInst |
|
/// Name##ReleaseInst |
|
/// |
|
/// After helper macro expansion: |
|
/// |
|
/// UNCHECKED_REF_STORAGE |
|
/// Ref*ToNameInst |
|
/// Name*ToRefInst |
|
/// Name##RetainValueInst |
|
/// Name##ReleaseValueInst |
|
/// ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
|
/// Ref*ToNameInst |
|
/// Name*ToRefInst |
|
/// Copy##Name##ValueInst |
|
/// StrongRetain##Name##Inst |
|
/// Name##RetainInst |
|
/// Name##ReleaseInst |
|
/// SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
/// Ref*ToNameInst |
|
/// Name*ToRefInst |
|
/// Load##Name##Inst |
|
/// Store##Name##Inst |
|
/// Copy##Name##ValueInst |
|
/// StrongRetain##Name##Inst |
|
/// Name##RetainInst |
|
/// Name##ReleaseInst |
|
/// NEVER_LOADABLE_CHECKED_REF_STORAGE |
|
/// Load##Name##Inst |
|
/// Store##Name##Inst |
|
/// |
|
/// Finally, a note about IRGen: TypeInfos need to be created per reference |
|
/// storage type, and SOMETIMES_LOADABLE_CHECKED_REF_STORAGE needs *two* |
|
/// TypeInfos to be created. One for the loadable scenario, and one for the |
|
/// address-only scenario. |
|
|
|
|
|
#ifndef REF_STORAGE |
|
#define REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifdef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
#if defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \ |
|
defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) |
|
#error Overlapping meta-programming macros |
|
#endif |
|
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
|
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifdef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
#if defined(NEVER_LOADABLE_CHECKED_REF_STORAGE) || \ |
|
defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) |
|
#error Overlapping meta-programming macros |
|
#endif |
|
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
|
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifdef LOADABLE_REF_STORAGE |
|
#if defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \ |
|
defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) || \ |
|
defined(UNCHECKED_REF_STORAGE) |
|
#error Overlapping meta-programming macros |
|
#endif |
|
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
LOADABLE_REF_STORAGE(Name, name, NAME) |
|
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
LOADABLE_REF_STORAGE(Name, name, NAME) |
|
#define UNCHECKED_REF_STORAGE(Name, name, NAME) \ |
|
LOADABLE_REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifdef CHECKED_REF_STORAGE |
|
#if defined(SOMETIMES_LOADABLE_CHECKED_REF_STORAGE) || \ |
|
defined(ALWAYS_LOADABLE_CHECKED_REF_STORAGE) || \ |
|
defined(NEVER_LOADABLE_CHECKED_REF_STORAGE) |
|
#error Overlapping meta-programming macros |
|
#endif |
|
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
CHECKED_REF_STORAGE(Name, name, NAME) |
|
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
CHECKED_REF_STORAGE(Name, name, NAME) |
|
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
CHECKED_REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifndef NEVER_LOADABLE_CHECKED_REF_STORAGE |
|
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifndef SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifndef ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
|
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, NAME) \ |
|
REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifndef UNCHECKED_REF_STORAGE |
|
#define UNCHECKED_REF_STORAGE(Name, name, NAME) \ |
|
REF_STORAGE(Name, name, NAME) |
|
#endif |
|
|
|
#ifndef REF_STORAGE_RANGE |
|
#define REF_STORAGE_RANGE(First, Last) |
|
#endif |
|
|
|
// NOTE: You will need to update ReferenceOwnership in ModuleFormat.h. |
|
//NEVER_LOADABLE_CHECKED_REF_STORAGE(Weak, weak, WEAK) |
|
//SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Unowned, unowned, UNOWNED) |
|
//UNCHECKED_REF_STORAGE(Unmanaged, unmanaged, UNMANAGED) |
|
REF_STORAGE_RANGE(Weak, Unmanaged) |
|
|
|
#undef REF_STORAGE |
|
#undef NEVER_LOADABLE_CHECKED_REF_STORAGE |
|
#undef ALWAYS_LOADABLE_CHECKED_REF_STORAGE |
|
#undef SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
#undef UNCHECKED_REF_STORAGE |
|
#undef REF_STORAGE_RANGE |
|
|
|
#undef ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
#undef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE |
|
#undef LOADABLE_REF_STORAGE |
|
#undef CHECKED_REF_STORAGE
|
|
|