-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AST] NFC: Enable reference storage type meta-programming #16237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
rjmccall
merged 13 commits into
swiftlang:master
from
davezarzycki:metaprogram_ref_storage_types
Jul 5, 2018
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
c7fc239
[AST] NFC: Enable reference storage type meta-programming
davezarzycki 5b9f506
[AST] NFC: Adopt reference storage type meta-programming macros
davezarzycki 8e1c903
[Parse] NFC: Adopt reference storage type meta-programming macros
davezarzycki 6dc2b7f
[Sema] NFC: Adopt reference storage type meta-programming macros
davezarzycki 476d869
[SIL] NFC: Adopt reference storage type meta-programming macros
davezarzycki 54e85ba
[SILGen] NFC: Adopt reference storage type meta-programming macros
davezarzycki 03b7eae
[SILOptimizer] NFC: Adopt reference storage type meta-programming macros
davezarzycki b61c111
[Serialization] NFC: Adopt reference storage type meta-programming ma…
davezarzycki 7d6c696
[Mangling] NFC: Adopt reference storage type meta-programming macros
davezarzycki da506fc
[Reflection] NFC: Adopt reference storage type meta-programming macros
davezarzycki efce6fc
[Runtime] NFC: Adopt reference storage type meta-programming macros
davezarzycki b91bde4
[swift-api-digester] NFC: Adopt reference storage type meta-programmi…
davezarzycki 057bbb3
[IRGen] Adopt reference storage type meta-programming macros
davezarzycki File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
//===--- ReferenceStorage.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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super happy with dumping all of these in the
swift::
namespace. Maybe there should be a sub-namespace?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems separable and larger than the pull request at hand. As the person to "blame" for many of these
Num*Bits
enums, I'd be happy to discuss in the forums what the "right" tradeoff is and then implement it. Do you want to start a thread?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not the Num*Bits I care about, it's
keywordOf
andOptionality
and things like that. I know the type signature shows what they're for, but this is still a header that gets included all over the place, and it's weird to put these generically-named declarations in the common namespace.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find any convention in Swift for how to workaround the fact that C++ doesn't allow methods on enum types. I'm open to suggestions.
In the case of this patch series and the way it is evolving, I could probably just move this logic to methods on
ReferenceStorageType
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've just begrudgingly accepted the need to have fairly general-looking function names in the Swift namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optionality
in particular is really bad, compared toOptionalTypeKind
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not in love with the name either. I just want to abstract away the hardcoded knowledge about the "optionality" of the reference storage types. How about
OwnershipOptionality
? OrReferenceStorageOptionality
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either of those is better, yeah. I think I'd lean towards the latter—this is not something that needs to be particularly concise.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some thought, I'm going with
ReferenceOwnershipOptionality
overReferenceStorageOptionality
. The rational is threefold:ReferenceOwnership
is not a reference storage type.optionalityOf()
need to check forStrong
first before calling the API.