Merge pull request #20825 from DougGregor/runtime-override-conforms-to-swift-protocol
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 93b6b65..a0c7dfd 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -378,7 +378,7 @@
function(_add_variant_link_flags)
set(oneValueArgs SDK ARCH BUILD_TYPE ENABLE_ASSERTIONS ANALYZE_CODE_COVERAGE
DEPLOYMENT_VERSION_OSX DEPLOYMENT_VERSION_IOS DEPLOYMENT_VERSION_TVOS DEPLOYMENT_VERSION_WATCHOS
- RESULT_VAR_NAME ENABLE_LTO LTO_OBJECT_NAME LIBRARY_SEARCH_DIRECTORIES_VAR_NAME)
+ RESULT_VAR_NAME ENABLE_LTO LTO_OBJECT_NAME LINK_LIBRARIES_VAR_NAME LIBRARY_SEARCH_DIRECTORIES_VAR_NAME)
cmake_parse_arguments(LFLAGS
""
"${oneValueArgs}"
@@ -389,6 +389,7 @@
precondition(LFLAGS_ARCH MESSAGE "Should specify an architecture")
set(result ${${LFLAGS_RESULT_VAR_NAME}})
+ set(link_libraries ${${LFLAGS_LINK_LIBRARIES_VAR_NAME}})
set(library_search_directories ${${LFLAGS_LIBRARY_SEARCH_DIRECTORIES_VAR_NAME}})
_add_variant_c_compile_link_flags(
@@ -405,9 +406,9 @@
RESULT_VAR_NAME result)
if("${LFLAGS_SDK}" STREQUAL "LINUX")
- list(APPEND result "-lpthread" "-latomic" "-ldl")
+ list(APPEND link_libraries "pthread" "atomic" "dl")
elseif("${LFLAGS_SDK}" STREQUAL "FREEBSD")
- list(APPEND result "-lpthread")
+ list(APPEND link_libraries "pthread")
elseif("${LFLAGS_SDK}" STREQUAL "CYGWIN")
# No extra libraries required.
elseif("${LFLAGS_SDK}" STREQUAL "WINDOWS")
@@ -425,9 +426,10 @@
list(APPEND library_search_directories
${CMAKE_BINARY_DIR}/winsdk_lib_${LFLAGS_ARCH}_symlinks)
elseif("${LFLAGS_SDK}" STREQUAL "HAIKU")
- list(APPEND result "-lbsd" "-latomic" "-Wl,-Bsymbolic")
+ list(APPEND link_libraries "bsd" "atomic")
+ list(APPEND result "-Wl,-Bsymbolic")
elseif("${LFLAGS_SDK}" STREQUAL "ANDROID")
- list(APPEND result "-ldl" "-llog" "-latomic" "-licudataswift" "-licui18nswift" "-licuucswift")
+ list(APPEND link_libraries "dl" "log" "atomic" "icudataswift" "icui18nswift" "icuucswift")
if("${LFLAGS_ARCH}" MATCHES armv7)
list(APPEND result "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so")
elseif("${LFLAGS_ARCH}" MATCHES aarch64)
@@ -437,7 +439,7 @@
endif()
swift_android_lib_for_arch(${LFLAGS_ARCH} ${LFLAGS_ARCH}_LIB)
foreach(path IN LISTS ${LFLAGS_ARCH}_LIB)
- list(APPEND library_search_directories ${path})
+ list(APPEND library_search_directories ${path})
endforeach()
else()
# If lto is enabled, we need to add the object path flag so that the LTO code
@@ -477,6 +479,7 @@
endif()
set("${LFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE)
+ set("${LFLAGS_LINK_LIBRARIES_VAR_NAME}" "${link_libraries}" PARENT_SCOPE)
set("${LFLAGS_LIBRARY_SEARCH_DIRECTORIES_VAR_NAME}" "${library_search_directories}" PARENT_SCOPE)
endfunction()
@@ -1209,6 +1212,7 @@
DEPLOYMENT_VERSION_TVOS "${SWIFTLIB_DEPLOYMENT_VERSION_TVOS}"
DEPLOYMENT_VERSION_WATCHOS "${SWIFTLIB_DEPLOYMENT_VERSION_WATCHOS}"
RESULT_VAR_NAME link_flags
+ LINK_LIBRARIES_VAR_NAME link_libraries
LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories
)
@@ -1253,6 +1257,7 @@
COMPILE_FLAGS " ${c_compile_flags}")
set_property(TARGET "${target}" APPEND_STRING PROPERTY
LINK_FLAGS " ${link_flags}")
+ set_property(TARGET "${target}" APPEND PROPERTY LINK_LIBRARIES ${link_libraries})
swift_target_link_search_directories("${target}" "${library_search_directories}")
# Adjust the linked libraries for windows targets. On Windows, the link is
@@ -2127,6 +2132,7 @@
LTO_OBJECT_NAME "${name}-${SWIFTEXE_SINGLE_SDK}-${SWIFTEXE_SINGLE_ARCHITECTURE}"
ANALYZE_CODE_COVERAGE "${SWIFT_ANALYZE_CODE_COVERAGE}"
RESULT_VAR_NAME link_flags
+ LINK_LIBRARIES_VAR_NAME link_libraries
LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories)
if(${SWIFTEXE_SINGLE_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
@@ -2192,6 +2198,7 @@
swift_target_link_search_directories("${name}" "${library_search_directories}")
set_property(TARGET ${name} APPEND_STRING PROPERTY
LINK_FLAGS " ${link_flags}")
+ set_property(TARGET ${name} APPEND PROPERTY LINK_LIBRARIES ${link_libraries})
if (SWIFT_PARALLEL_LINK_JOBS)
set_property(TARGET ${name} PROPERTY JOB_POOL_LINK swift_link_job_pool)
endif()
diff --git a/include/swift/Basic/Statistic.h b/include/swift/Basic/Statistic.h
index e2ea4a2..bc623bc 100644
--- a/include/swift/Basic/Statistic.h
+++ b/include/swift/Basic/Statistic.h
@@ -21,7 +21,9 @@
#include <thread>
#include <tuple>
-#define SWIFT_FUNC_STAT \
+#define SWIFT_FUNC_STAT SWIFT_FUNC_STAT_NAMED(DEBUG_TYPE)
+
+#define SWIFT_FUNC_STAT_NAMED(DEBUG_TYPE) \
do { \
static llvm::Statistic FStat = \
{DEBUG_TYPE, __func__, __func__, {0}, {false}}; \
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 78cc044..adfef30 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -67,6 +67,10 @@
/// Set of basic blocks where unreachable was inserted.
SmallPtrSet<SILBasicBlock *, 32> BlocksWithUnreachables;
+ // Keep track of the last cloned block in function order. For single block
+ // regions, this will be the start block.
+ SILBasicBlock *lastClonedBB = nullptr;
+
public:
using SILInstructionVisitor<ImplClass>::asImpl;
@@ -102,6 +106,10 @@
SILBuilder &getBuilder() { return Builder; }
+ // After cloning, returns a non-null pointer to the last cloned block in
+ // function order. For single block regions, this will be the start block.
+ SILBasicBlock *getLastClonedBB() { return lastClonedBB; }
+
/// Visit all blocks reachable from the given `StartBB` and all instructions
/// in those blocks.
///
@@ -655,7 +663,7 @@
// order they are created, which differs from the order they are
// cloned. Blocks are created in BFS order but cloned in DFS preorder (when no
// critical edges are present).
- SILBasicBlock *lastClonedBB = BBMap[startBB];
+ lastClonedBB = BBMap[startBB];
while (!dfsWorklist.empty()) {
auto *BB = dfsWorklist.pop_back_val();
preorderBlocks.push_back(BB);
diff --git a/include/swift/SILOptimizer/Utils/CFG.h b/include/swift/SILOptimizer/Utils/CFG.h
index 2913240..fe3581a 100644
--- a/include/swift/SILOptimizer/Utils/CFG.h
+++ b/include/swift/SILOptimizer/Utils/CFG.h
@@ -127,6 +127,16 @@
bool mergeBasicBlockWithSuccessor(SILBasicBlock *BB, DominanceInfo *DT,
SILLoopInfo *LI);
+/// Merge basic blocks in the given function by eliminating all unconditional
+/// branches to single-predecessor branch targets.
+///
+/// During optimization, SimplifyCFG also handles this, but this is a basic
+/// canonicalization after any pass that splits blocks, such as inlining. This
+/// is not done on-the-fly after splitting blocks because merging is linear in
+/// the number of instructions, so interleaved merging and splitting is
+/// quadratic.
+bool mergeBasicBlocks(SILFunction *F);
+
/// Given a list of \p UserBlocks and a list of \p DefBlocks, find a set of
/// blocks that together with \p UserBlocks joint-postdominate \p
/// DefBlocks. This is in a sense finding a set of blocks that "complete" \p
diff --git a/include/swift/SILOptimizer/Utils/SILInliner.h b/include/swift/SILOptimizer/Utils/SILInliner.h
index 8a7fcb6..12fe700 100644
--- a/include/swift/SILOptimizer/Utils/SILInliner.h
+++ b/include/swift/SILOptimizer/Utils/SILInliner.h
@@ -80,18 +80,32 @@
/// iterator to the first inlined instruction (or first instruction after the
/// call for an empty function).
///
- /// This may split basic blocks and delete instructions.
- ///
/// This only performs one step of inlining: it does not recursively
/// inline functions called by the callee.
///
+ /// This may split basic blocks and delete instructions anywhere.
+ ///
+ /// All inlined instructions must be either inside the original call block or
+ /// inside new basic blocks laid out after the original call block.
+ ///
+ /// Any instructions in the original call block after the inlined call must be
+ /// in a new basic block laid out after all inlined blocks.
+ ///
+ /// The above guarantees ensure that inlining is liner in the number of
+ /// instructions and that inlined instructions are revisited exactly once.
+ ///
/// *NOTE*: This attempts to perform inlining unconditionally and thus asserts
/// if inlining will fail. All users /must/ check that a function is allowed
/// to be inlined using SILInliner::canInlineApplySite before calling this
/// function.
- SILBasicBlock::iterator inlineFunction(SILFunction *calleeFunction,
- FullApplySite apply,
- ArrayRef<SILValue> appliedArgs);
+ ///
+ /// Returns an iterator to the first inlined instruction (or the end of the
+ /// caller block for empty functions) and the last block in function order
+ /// containing inlined instructions (the original caller block for
+ /// single-block functions).
+ std::pair<SILBasicBlock::iterator, SILBasicBlock *>
+ inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
+ ArrayRef<SILValue> appliedArgs);
};
} // end namespace swift
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index c1722dc..4cbb719 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -52,7 +52,7 @@
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t SWIFTMODULE_VERSION_MINOR = 468; // Last change: SelfProtocolConformance
+const uint16_t SWIFTMODULE_VERSION_MINOR = 469; // @_hasStorage
using DeclIDField = BCFixed<31>;
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index f0d6f5c..e621748 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -2111,7 +2111,9 @@
}
- CanType type = decl->getInterfaceType()->getCanonicalType();
+ CanType type = decl->getInterfaceType()
+ ->getReferenceStorageReferent()
+ ->getCanonicalType();
if (auto gft = dyn_cast<GenericFunctionType>(type)) {
genericSig = gft.getGenericSignature();
CurGenericSignature = gft.getGenericSignature();
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index ec97c83..1c6f0b7 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -591,11 +591,13 @@
return;
printAccess(D->getFormalAccess());
+ bool shouldSkipSetterAccess =
+ llvm::is_contained(Options.ExcludeAttrList, DAK_SetterAccess);
if (auto storageDecl = dyn_cast<AbstractStorageDecl>(D)) {
if (auto setter = storageDecl->getSetter()) {
AccessLevel setterAccess = setter->getFormalAccess();
- if (setterAccess != D->getFormalAccess())
+ if (setterAccess != D->getFormalAccess() && !shouldSkipSetterAccess)
printAccess(setterAccess, "(set)");
}
}
@@ -865,6 +867,10 @@
return setter && setter->isExplicitNonMutating();
}
+static bool hasLessAccessibleSetter(const AbstractStorageDecl *ASD) {
+ return ASD->getSetterFormalAccess() < ASD->getFormalAccess();
+}
+
void PrintAST::printAttributes(const Decl *D) {
if (Options.SkipAttributes)
return;
@@ -880,11 +886,20 @@
Options.ExcludeAttrList.push_back(DAK_Final);
}
- // Don't print @_hasInitialValue if we're printing an initializer
- // expression.
if (auto vd = dyn_cast<VarDecl>(D)) {
+ // Don't print @_hasInitialValue if we're printing an initializer
+ // expression.
if (vd->isInitExposedToClients())
Options.ExcludeAttrList.push_back(DAK_HasInitialValue);
+
+ if (!Options.PrintForSIL) {
+ // Don't print @_hasStorage if the value is simply stored, or the
+ // decl is resilient.
+ if (vd->isResilient() ||
+ (vd->getImplInfo().isSimpleStored() &&
+ !hasLessAccessibleSetter(vd)))
+ Options.ExcludeAttrList.push_back(DAK_HasStorage);
+ }
}
// Don't print any contextual decl modifiers.
@@ -1613,19 +1628,28 @@
if (isa<VarDecl>(ASD) && !Options.PrintPropertyAccessors)
return;
- // Never print anything for stored properties.
- if (ASD->getAllAccessors().empty())
- return;
-
auto impl = ASD->getImplInfo();
- // Treat StoredWithTrivialAccessors the same as Stored unless
- // we're printing for SIL, in which case we want to distinguish it
- // from a pure stored property.
+ // Don't print accessors for trivially stored properties...
if (impl.isSimpleStored()) {
+ // ...unless we're printing for SIL, which expects a { get set? } on
+ // trivial properties
if (Options.PrintForSIL) {
Printer << " { get " << (impl.supportsMutation() ? "set }" : "}");
}
+ // ...or you're private/internal(set), at which point we'll print
+ // @_hasStorage var x: T { get }
+ else if (ASD->isSettable(nullptr) && hasLessAccessibleSetter(ASD)) {
+ Printer << " {";
+ {
+ IndentRAII indentMore(*this);
+ indent();
+ Printer.printNewline();
+ Printer << "get";
+ Printer.printNewline();
+ }
+ Printer << "}";
+ }
return;
}
@@ -1762,12 +1786,8 @@
llvm_unreachable("simply-stored variable should have been filtered out");
case WriteImplKind::StoredWithObservers:
case WriteImplKind::InheritedWithObservers: {
- bool skippedWillSet = PrintAccessor(ASD->getWillSetFunc());
- bool skippedDidSet = PrintAccessor(ASD->getDidSetFunc());
- if (skippedDidSet && skippedWillSet) {
- PrintAccessor(ASD->getGetter());
- PrintAccessor(ASD->getSetter());
- }
+ PrintAccessor(ASD->getGetter());
+ PrintAccessor(ASD->getSetter());
break;
}
case WriteImplKind::Set:
@@ -2091,6 +2111,12 @@
SmallString<128> scratch;
Printer << " = " << entry.getInitStringRepresentation(scratch);
}
+
+ // HACK: If we're just printing a single pattern and it has accessors,
+ // print the accessors here.
+ if (decl->getNumPatternEntries() == 1) {
+ printAccessors(vd);
+ }
}
}
@@ -2322,7 +2348,6 @@
Options.BracketOptions.shouldCloseNominal(decl));
}
}
-
static bool isStructOrClassContext(DeclContext *dc) {
auto *nominal = dc->getSelfNominalTypeDecl();
if (nominal == nullptr)
diff --git a/lib/ClangImporter/MappedTypes.def b/lib/ClangImporter/MappedTypes.def
index 0fd435a..9afc664 100644
--- a/lib/ClangImporter/MappedTypes.def
+++ b/lib/ClangImporter/MappedTypes.def
@@ -161,6 +161,9 @@
// CoreFoundation types.
// Note that we're preserving the typealias for CFIndex.
+MAP_STDLIB_TYPE("CFTypeID", UnsignedWord, 0, "UInt", false, DefineAndUse)
+MAP_STDLIB_TYPE("CFOptionFlags", UnsignedWord, 0, "UInt", false, DefineAndUse)
+MAP_STDLIB_TYPE("CFHashCode", UnsignedWord, 0, "UInt", false, DefineAndUse)
MAP_STDLIB_TYPE("CFIndex", SignedWord, 0, "Int", false, DefineAndUse)
// Foundation types.
diff --git a/lib/Frontend/ParseableInterfaceSupport.cpp b/lib/Frontend/ParseableInterfaceSupport.cpp
index 5ff58c8..344baf9 100644
--- a/lib/Frontend/ParseableInterfaceSupport.cpp
+++ b/lib/Frontend/ParseableInterfaceSupport.cpp
@@ -344,10 +344,12 @@
}
LLVM_DEBUG(llvm::dbgs() << "Serializing " << OutPath << "\n");
+ FrontendOptions &FEOpts = SubInvocation.getFrontendOptions();
SerializationOptions SerializationOpts;
std::string OutPathStr = OutPath;
SerializationOpts.OutputPath = OutPathStr.c_str();
SerializationOpts.SerializeAllSIL = true;
+ SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
SmallVector<FileDependency, 16> Deps;
if (collectDepsForSerialization(FS, SubInstance, InPath, ModuleCachePath,
Deps, Diags, OuterTracker)) {
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index d46cfb4..71d485f 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -4777,6 +4777,72 @@
}
}
+/// Gets the storage info of the provided storage decl if it has the
+/// @_hasStorage attribute and it's not in SIL mode.
+///
+/// In this case, we say the decl is:
+///
+/// Read:
+/// - Stored, always
+/// Write:
+/// - Stored, if the decl is a 'var'.
+/// - StoredWithObservers, if the decl has a setter
+/// - This indicates that the original decl had a 'didSet' and/or 'willSet'
+/// - InheritedWithObservers, if the decl has a setter and is an overridde.
+/// - Immutable, if the decl is a 'let' or it does not have a setter.
+/// ReadWrite:
+/// - Stored, if the decl has no accessors listed.
+/// - Immutable, if the decl is a 'let' or it does not have a setter.
+/// - MaterializeToTemporary, if the decl has a setter.
+static StorageImplInfo classifyWithHasStorageAttr(
+ Parser::ParsedAccessors &accessors, ASTContext &ctx,
+ AbstractStorageDecl *storage, const DeclAttributes &attrs) {
+
+ // Determines if the storage is immutable, either by declaring itself as a
+ // `let` or by omitting a setter.
+ auto isImmutable = [&]() {
+ if (auto varDecl = dyn_cast<VarDecl>(storage))
+ return varDecl->isImmutable();
+ if (accessors.Set == nullptr) return true;
+ return false;
+ };
+
+ // Determines if the storage had a private setter, i.e. it's not a 'let' and
+ // it had a setter.
+ auto isPrivateSet = [&]() {
+ if (auto varDecl = dyn_cast<VarDecl>(storage))
+ return !varDecl->isImmutable() && accessors.Set == nullptr;
+ return false;
+ };
+
+ // Default to stored writes.
+ WriteImplKind writeImpl = WriteImplKind::Stored;
+ ReadWriteImplKind readWriteImpl = ReadWriteImplKind::Stored;
+
+ if (accessors.Get && accessors.Set) {
+ // If we see `@_hasStorage var x: T { get set }`, then our property has
+ // willSet/didSet observers.
+ writeImpl = attrs.hasAttribute<OverrideAttr>() ?
+ WriteImplKind::InheritedWithObservers :
+ WriteImplKind::StoredWithObservers;
+ readWriteImpl = ReadWriteImplKind::MaterializeToTemporary;
+ } else if (isImmutable()) {
+ writeImpl = WriteImplKind::Immutable;
+ readWriteImpl = ReadWriteImplKind::Immutable;
+ }
+
+ if (isPrivateSet()) {
+ // If we saw a 'var' with no setter, that means it was
+ // private/internal(set). Honor that with a synthesized attribute.
+ storage->getAttrs().add(
+ new (ctx) SetterAccessAttr(
+ SourceLoc(), SourceLoc(), AccessLevel::Private, /*implicit: */true));
+ }
+
+ // Always force Stored reads if @_hasStorage is present.
+ return StorageImplInfo(ReadImplKind::Stored, writeImpl, readWriteImpl);
+}
+
StorageImplInfo
Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
bool invalid, ParseDeclOptions flags,
@@ -4935,10 +5001,26 @@
readWriteImpl = ReadWriteImplKind::Immutable;
}
- // Allow the _hasStorage attribute to override all the accessors we parsed
+ // Allow the @_hasStorage attribute to override all the accessors we parsed
// when making the final classification.
if (attrs.hasAttribute<HasStorageAttr>()) {
- return StorageImplInfo::getSimpleStored(StorageIsMutable_t(Set != nullptr));
+ // The SIL rules for @_hasStorage are slightly different from the non-SIL
+ // rules. In SIL mode, @_hasStorage marks that the type is simply stored,
+ // and the only thing that determines mutability is the existence of the
+ // setter.
+ //
+ // FIXME: SIL should not be special cased here. The behavior should be
+ // consistent between SIL and non-SIL.
+ // The strategy here should be to keep track of all opaque accessors
+ // along with enough information to access the storage trivially
+ // if allowed. This could be a representational change to
+ // StorageImplInfo such that it keeps a bitset of listed accessors
+ // and dynamically determines the access strategy from that.
+ if (P.isInSILMode())
+ return StorageImplInfo::getSimpleStored(
+ StorageIsMutable_t(Set != nullptr));
+
+ return classifyWithHasStorageAttr(*this, P.Context, storage, attrs);
}
return StorageImplInfo(readImpl, writeImpl, readWriteImpl);
diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp
index 159c252..ea4d808 100644
--- a/lib/SIL/SILInstruction.cpp
+++ b/lib/SIL/SILInstruction.cpp
@@ -86,8 +86,10 @@
if (ThisParent == L2.getContainingBlock()) return;
// Update the parent fields in the instructions.
- for (; first != last; ++first)
+ for (; first != last; ++first) {
+ SWIFT_FUNC_STAT_NAMED("sil");
first->ParentBB = ThisParent;
+ }
}
//===----------------------------------------------------------------------===//
diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
index 9924339..8a98443 100644
--- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
+++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
@@ -49,7 +49,7 @@
/// and that the function implementing the closure consumes its capture
/// arguments.
static void fixupReferenceCounts(
- SILBasicBlock::iterator I, SILValue CalleeValue,
+ SILInstruction *I, SILValue CalleeValue,
SmallVectorImpl<std::pair<SILValue, ParameterConvention>> &CaptureArgs,
bool isCalleeGuaranteed) {
// Add a copy of each non-address type capture argument to lifetime extend the
@@ -60,7 +60,7 @@
if (!CaptureArg.first->getType().isAddress() &&
CaptureArg.second != ParameterConvention::Direct_Guaranteed &&
CaptureArg.second != ParameterConvention::Direct_Unowned) {
- createIncrementBefore(CaptureArg.first, &*I);
+ createIncrementBefore(CaptureArg.first, I);
} else {
// FIXME: What about indirectly owned parameters? The invocation of the
// closure would perform an indirect copy which we should mimick here.
@@ -190,35 +190,31 @@
class ClosureCleanup {
using DeadInstSet = SmallBlotSetVector<SILInstruction *, 4>;
- /// A helper class to update an instruction iterator if
- /// removal of instructions would invalidate it.
+ /// A helper class to update the set of dead instructions.
///
/// Since this is called by the SILModule callback, the instruction may longer
/// be well-formed. Do not visit its operands. However, it's position in the
/// basic block is still valid.
///
- /// FIXME: Using the Module's callback mechanism is undesirable. Instead,
- /// cleanupCalleeValue could be easily rewritten to use its own instruction
- /// deletion helper and pass a callback to tryDeleteDeadClosure and
- /// recursivelyDeleteTriviallyDeadInstructions.
- class IteratorUpdateHandler : public DeleteNotificationHandler {
+ /// FIXME: Using the Module's callback mechanism for this is terrible.
+ /// Instead, cleanupCalleeValue could be easily rewritten to use its own
+ /// instruction deletion helper and pass a callback to tryDeleteDeadClosure
+ /// and recursivelyDeleteTriviallyDeadInstructions.
+ class DeleteUpdateHandler : public DeleteNotificationHandler {
SILModule &Module;
- SILBasicBlock::iterator CurrentI;
DeadInstSet &DeadInsts;
public:
- IteratorUpdateHandler(SILBasicBlock::iterator I, DeadInstSet &DeadInsts)
- : Module(I->getModule()), CurrentI(I), DeadInsts(DeadInsts) {
+ DeleteUpdateHandler(SILModule &M, DeadInstSet &DeadInsts)
+ : Module(M), DeadInsts(DeadInsts) {
Module.registerDeleteNotificationHandler(this);
}
- ~IteratorUpdateHandler() override {
+ ~DeleteUpdateHandler() override {
// Unregister the handler.
Module.removeDeleteNotificationHandler(this);
}
- SILBasicBlock::iterator getIterator() const { return CurrentI; }
-
// Handling of instruction removal notifications.
bool needsNotifications() override { return true; }
@@ -229,9 +225,6 @@
return;
DeadInsts.erase(deletedI);
-
- if (CurrentI == SILBasicBlock::iterator(deletedI))
- ++CurrentI;
}
};
@@ -260,8 +253,8 @@
// Note: instructions in the `deadFunctionVals` set may use each other, so the
// set needs to continue to be updated (by this handler) when deleting
// instructions. This assumes that DeadFunctionValSet::erase() is stable.
- SILBasicBlock::iterator cleanupDeadClosures(SILBasicBlock::iterator II) {
- IteratorUpdateHandler iteratorUpdate(II, deadFunctionVals);
+ void cleanupDeadClosures(SILFunction *F) {
+ DeleteUpdateHandler deleteUpdate(F->getModule(), deadFunctionVals);
for (Optional<SILInstruction *> I : deadFunctionVals) {
if (!I.hasValue())
continue;
@@ -269,7 +262,6 @@
if (auto *SVI = dyn_cast<SingleValueInstruction>(I.getValue()))
cleanupCalleeValue(SVI);
}
- return iteratorUpdate.getIterator();
}
};
} // end of namespace
@@ -472,21 +464,21 @@
return CalleeFunction;
}
-static std::tuple<FullApplySite, SILBasicBlock::iterator>
-tryDevirtualizeApplyHelper(FullApplySite InnerAI, SILBasicBlock::iterator I,
- ClassHierarchyAnalysis *CHA) {
+static SILInstruction *tryDevirtualizeApplyHelper(FullApplySite InnerAI,
+ ClassHierarchyAnalysis *CHA) {
auto NewInst = tryDevirtualizeApply(InnerAI, CHA);
- if (!NewInst) {
- return std::make_tuple(InnerAI, I);
- }
+ if (!NewInst)
+ return InnerAI.getInstruction();
deleteDevirtualizedApply(InnerAI);
+ // FIXME: Comments at the use of this helper indicate that devirtualization
+ // may return SILArgument. Yet here we assert that it must return an
+ // instruction.
auto newApplyAI = NewInst.getInstruction();
assert(newApplyAI && "devirtualized but removed apply site?");
- return std::make_tuple(FullApplySite::isa(newApplyAI),
- newApplyAI->getIterator());
+ return newApplyAI;
}
/// \brief Inlines all mandatory inlined functions into the body of a function,
@@ -532,23 +524,34 @@
SmallVector<std::pair<SILValue, ParameterConvention>, 16> CaptureArgs;
SmallVector<SILValue, 32> FullArgs;
- for (auto BI = F->begin(), BE = F->end(); BI != BE; ++BI) {
+ // Visiting blocks in reverse order avoids revisiting instructions after block
+ // splitting, which would be quadratic.
+ for (auto BI = F->rbegin(), BE = F->rend(), nextBB = BI; BI != BE;
+ BI = nextBB) {
+ // After inlining, the block iterator will be adjusted to point to the last
+ // block containing inlined instructions. This way, the inlined function
+ // body will be reprocessed within the caller's context without revisiting
+ // any original instructions.
+ nextBB = std::next(BI);
+
// While iterating over this block, instructions are inserted and deleted.
- for (auto II = BI->begin(), nextI = II; II != BI->end(); II = nextI) {
- nextI = std::next(II);
-
+ // To avoid quadratic block splitting, instructions must be processed in
+ // reverse order (block splitting reassigned the parent pointer of all
+ // instructions below the split point).
+ for (auto II = BI->rbegin(); II != BI->rend(); ++II) {
FullApplySite InnerAI = FullApplySite::isa(&*II);
-
if (!InnerAI)
continue;
- auto *ApplyBlock = InnerAI.getParent();
-
- // *NOTE* If devirtualization succeeds, sometimes II will not be InnerAI,
+ // *NOTE* If devirtualization succeeds, devirtInst may not be InnerAI,
// but a casted result of InnerAI or even a block argument due to
- // abstraction changes when calling the witness or class method. We still
- // know that InnerAI dominates II though.
- std::tie(InnerAI, II) = tryDevirtualizeApplyHelper(InnerAI, II, CHA);
+ // abstraction changes when calling the witness or class method.
+ auto *devirtInst = tryDevirtualizeApplyHelper(InnerAI, CHA);
+ // Restore II to the current apply site.
+ II = devirtInst->getReverseIterator();
+ // If the devirtualized call result is no longer a invalid FullApplySite,
+ // then it has succeeded, but the result is not immediately inlinable.
+ InnerAI = FullApplySite::isa(devirtInst);
if (!InnerAI)
continue;
@@ -597,13 +600,8 @@
SILInliner Inliner(FuncBuilder, SILInliner::InlineKind::MandatoryInline,
Subs, OpenedArchetypesTracker);
- if (!Inliner.canInlineApplySite(InnerAI)) {
- // See comment above about casting when devirtualizing and how this
- // sometimes causes II and InnerAI to be different and even in different
- // blocks.
- II = InnerAI.getInstruction()->getIterator();
+ if (!Inliner.canInlineApplySite(InnerAI))
continue;
- }
// Inline function at I, which also changes I to refer to the first
// instruction inlined in the case that it succeeds. We purposely
@@ -620,7 +618,8 @@
bool IsCalleeGuaranteed =
PAI &&
PAI->getType().castTo<SILFunctionType>()->isCalleeGuaranteed();
- fixupReferenceCounts(II, CalleeValue, CaptureArgs, IsCalleeGuaranteed);
+ fixupReferenceCounts(InnerAI.getInstruction(), CalleeValue, CaptureArgs,
+ IsCalleeGuaranteed);
}
// Register a callback to record potentially unused function values after
@@ -632,20 +631,23 @@
// Inlining deletes the apply, and can introduce multiple new basic
// blocks. After this, CalleeValue and other instructions may be invalid.
- nextI = Inliner.inlineFunction(CalleeFunction, InnerAI, FullArgs);
+ // nextBB will point to the last inlined block
+ auto firstInlinedInstAndLastBB =
+ Inliner.inlineFunction(CalleeFunction, InnerAI, FullArgs);
+ nextBB = firstInlinedInstAndLastBB.second->getReverseIterator();
++NumMandatoryInlines;
// The IR is now valid, and trivial dead arguments are removed. However,
// we may be able to remove dead callee computations (e.g. dead
// partial_apply closures).
- nextI = closureCleanup.cleanupDeadClosures(nextI);
+ closureCleanup.cleanupDeadClosures(F);
- assert(nextI == ApplyBlock->end()
- || nextI->getParent() == ApplyBlock
- && "Mismatch between the instruction and basic block");
+ // Resume inlining within nextBB, which contains only the inlined
+ // instructions and possibly instructions in the original call block that
+ // have not yet been visited.
+ break;
}
}
-
// Keep track of full inlined functions so we don't waste time recursively
// reprocessing them.
FullyInlinedSet.insert(F);
@@ -680,6 +682,9 @@
runOnFunctionRecursively(FuncBuilder, &F,
FullApplySite(), FullyInlinedSet, SetFactory,
SetFactory.getEmptySet(), CHA);
+ // The inliner splits blocks at call sites. Re-merge trivial branches
+ // to reestablish a canonical CFG.
+ mergeBasicBlocks(&F);
}
if (!ShouldCleanup)
diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
index 33eb20b..8e99a66 100644
--- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
+++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
@@ -17,6 +17,7 @@
#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
+#include "swift/SILOptimizer/Utils/CFG.h"
#include "swift/SILOptimizer/Utils/Devirtualize.h"
#include "swift/SILOptimizer/Utils/Generics.h"
#include "swift/SILOptimizer/Utils/PerformanceInlinerUtils.h"
@@ -903,6 +904,9 @@
Inliner.inlineFunction(Callee, AI, Args);
NumFunctionsInlined++;
}
+ // The inliner splits blocks at call sites. Re-merge trivial branches to
+ // reestablish a canonical CFG.
+ mergeBasicBlocks(Caller);
return true;
}
diff --git a/lib/SILOptimizer/Utils/CFG.cpp b/lib/SILOptimizer/Utils/CFG.cpp
index 14f215b..de2ce17 100644
--- a/lib/SILOptimizer/Utils/CFG.cpp
+++ b/lib/SILOptimizer/Utils/CFG.cpp
@@ -493,6 +493,19 @@
return true;
}
+bool swift::mergeBasicBlocks(SILFunction *F) {
+ bool merged = false;
+ for (auto BBIter = F->begin(); BBIter != F->end();) {
+ if (mergeBasicBlockWithSuccessor(&*BBIter, /*DT*/ nullptr, /*LI*/ nullptr)) {
+ merged = true;
+ // Continue to merge the current block without advancing.
+ continue;
+ }
+ ++BBIter;
+ }
+ return merged;
+}
+
/// Splits the critical edges between from and to. This code assumes there is
/// only one edge between the two basic blocks.
SILBasicBlock *swift::splitIfCriticalEdge(SILBasicBlock *From,
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index 418188a..d995992 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -388,7 +388,7 @@
};
} // namespace swift
-SILBasicBlock::iterator
+std::pair<SILBasicBlock::iterator, SILBasicBlock *>
SILInliner::inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
ArrayRef<SILValue> appliedArgs) {
assert(canInlineApplySite(apply)
@@ -396,7 +396,8 @@
SILInlineCloner cloner(calleeFunction, apply, FuncBuilder, IKind, ApplySubs,
OpenedArchetypesTracker, DeletionCallback);
- return cloner.cloneInline(appliedArgs);
+ auto nextI = cloner.cloneInline(appliedArgs);
+ return std::make_pair(nextI, cloner.getLastClonedBB());
}
SILInlineCloner::SILInlineCloner(
@@ -512,23 +513,16 @@
// NextIter is initialized during `fixUp`.
cloneFunctionBody(getCalleeFunction(), callerBB, entryArgs);
- // As a trivial optimization, if the apply block falls through, merge it. The
- // fall through is likely the ReturnToBB, but that is not guaranteed.
- if (auto *BI = dyn_cast<BranchInst>(callerBB->getTerminator())) {
- // FIXME: should be an assert once critical edges are fixed.
- // assert(BI->getDestBB()->getSinglePredecessorBlock() &&
- // "the return block cannot have other predecessors.");
- if (BI->getDestBB()->getSinglePredecessorBlock()) {
- SILInstruction *firstInlinedInst = &*NextIter;
- if (firstInlinedInst == BI)
- firstInlinedInst = &BI->getDestBB()->front();
-
- mergeBasicBlockWithSuccessor(BI->getParent(), /*DT*/ nullptr,
- /*LI*/ nullptr);
- NextIter = firstInlinedInst->getIterator();
- ReturnToBB = nullptr;
- }
- }
+ // For non-throwing applies, the inlined body now unconditionally branches to
+ // the returned-to-code, which was previously part of the call site's basic
+ // block. We could trivially merge these blocks now, however, this would be
+ // quadratic: O(num-calls-in-block * num-instructions-in-block). Also,
+ // guaranteeing that caller instructions following the inlined call are in a
+ // separate block gives the inliner control over revisiting only the inlined
+ // instructions.
+ //
+ // Once all calls in a function are inlined, unconditional branches are
+ // eliminated by mergeBlocks.
return NextIter;
}
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 69902e2..5577763 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -85,6 +85,7 @@
IGNORED_ATTR(FixedLayout)
IGNORED_ATTR(ForbidSerializingReference)
IGNORED_ATTR(Frozen)
+ IGNORED_ATTR(HasStorage)
IGNORED_ATTR(Implements)
IGNORED_ATTR(ImplicitlyUnwrappedOptional)
IGNORED_ATTR(Infix)
@@ -285,7 +286,6 @@
void visitAccessControlAttr(AccessControlAttr *attr);
void visitSetterAccessAttr(SetterAccessAttr *attr);
bool visitAbstractAccessControlAttr(AbstractAccessControlAttr *attr);
- void visitHasStorageAttr(HasStorageAttr *attr);
void visitObjCMembersAttr(ObjCMembersAttr *attr);
};
} // end anonymous namespace
@@ -428,16 +428,6 @@
attr->getAttrName());
}
-void AttributeEarlyChecker::visitHasStorageAttr(HasStorageAttr *attr) {
- auto *VD = cast<VarDecl>(D);
- if (VD->getDeclContext()->getSelfClassDecl())
- return;
- auto nominalDecl = VD->getDeclContext()->getSelfNominalTypeDecl();
- if (nominalDecl && isa<StructDecl>(nominalDecl))
- return;
- diagnoseAndRemoveAttr(attr, diag::invalid_decl_attribute_simple);
-}
-
static Optional<Diag<bool,Type>>
isAcceptableOutletType(Type type, bool &isArray, TypeChecker &TC) {
if (type->isObjCExistentialType() || type->isAny())
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index ab09d49..9f8ac22 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4057,6 +4057,10 @@
auto *VD = cast<VarDecl>(D);
auto *PBD = VD->getParentPatternBinding();
+ // Add the '@_hasStorage' attribute if this property is stored.
+ if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
+ VD->getAttrs().add(new (Context) HasStorageAttr(/*isImplicit=*/true));
+
// Note that we need to handle the fact that some VarDecls don't
// have a PatternBindingDecl, for example the iterator in a
// 'for ... in ...' loop.
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index 5878682..727e2c7 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -1205,6 +1205,7 @@
UNINTERESTING_ATTR(Convenience)
UNINTERESTING_ATTR(Semantics)
UNINTERESTING_ATTR(SetterAccess)
+ UNINTERESTING_ATTR(HasStorage)
UNINTERESTING_ATTR(UIApplicationMain)
UNINTERESTING_ATTR(UsableFromInline)
UNINTERESTING_ATTR(ObjCNonLazyRealization)
@@ -1224,7 +1225,6 @@
UNINTERESTING_ATTR(SynthesizedProtocol)
UNINTERESTING_ATTR(RequiresStoredPropertyInits)
UNINTERESTING_ATTR(Transparent)
- UNINTERESTING_ATTR(HasStorage)
UNINTERESTING_ATTR(Testable)
UNINTERESTING_ATTR(WarnUnqualifiedAccess)
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 8b4cfa3..26dff8f 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -3018,21 +3018,29 @@
configureStorage(var, opaqueReadOwnership,
readImpl, writeImpl, readWriteImpl, accessors);
-
- if (auto accessLevel = getActualAccessLevel(rawAccessLevel)) {
- var->setAccess(*accessLevel);
- } else {
+ auto accessLevel = getActualAccessLevel(rawAccessLevel);
+ if (!accessLevel) {
error();
return nullptr;
}
+ var->setAccess(*accessLevel);
+
if (var->isSettable(nullptr)) {
- if (auto setterAccess = getActualAccessLevel(rawSetterAccessLevel)) {
- var->setSetterAccess(*setterAccess);
- } else {
+ auto setterAccess = getActualAccessLevel(rawSetterAccessLevel);
+ if (!setterAccess) {
error();
return nullptr;
}
+ var->setSetterAccess(*setterAccess);
+
+ // If we have a less-accessible setter, honor that by adding the
+ // setter access attribute.
+ if (*setterAccess < *accessLevel) {
+ AddAttribute(
+ new (ctx) SetterAccessAttr(SourceLoc(), SourceLoc(),
+ *setterAccess, /*implicit*/true));
+ }
}
if (isImplicit)
@@ -3043,6 +3051,10 @@
if (var->getOverriddenDecl())
AddAttribute(new (ctx) OverrideAttr(SourceLoc()));
+ // Add the @_hasStorage attribute if this var has storage.
+ if (var->hasStorage())
+ AddAttribute(new (ctx) HasStorageAttr(/*isImplicit:*/true));
+
break;
}
diff --git a/stdlib/public/core/StringGutsSlice.swift b/stdlib/public/core/StringGutsSlice.swift
index 820dbb9..3c6d25d4 100644
--- a/stdlib/public/core/StringGutsSlice.swift
+++ b/stdlib/public/core/StringGutsSlice.swift
@@ -16,22 +16,18 @@
// A sliced _StringGuts, convenient for unifying String/Substring comparison,
// hashing, and RRC.
-@_fixed_layout
-@usableFromInline
internal struct _StringGutsSlice {
- @usableFromInline
internal var _guts: _StringGuts
- @usableFromInline
internal var _offsetRange: Range<Int>
- @inlinable @inline(__always)
+ @inline(__always)
internal init(_ guts: _StringGuts) {
self._guts = guts
self._offsetRange = 0..<self._guts.count
}
- @inlinable @inline(__always)
+ @inline(__always)
internal init(_ guts: _StringGuts, _ offsetRange: Range<Int>) {
self._guts = guts
self._offsetRange = offsetRange
@@ -83,7 +79,7 @@
}
}
- @inlinable @inline(__always)
+ @inline(__always)
internal func withFastUTF8<R>(
_ f: (UnsafeBufferPointer<UInt8>) throws -> R
) rethrows -> R {
diff --git a/stdlib/public/core/StringHashable.swift b/stdlib/public/core/StringHashable.swift
index 3e335a3..9512337 100644
--- a/stdlib/public/core/StringHashable.swift
+++ b/stdlib/public/core/StringHashable.swift
@@ -45,7 +45,6 @@
}
extension _StringGutsSlice {
- @usableFromInline // @opaque
@inline(never) // slow-path
internal func _normalizedHash(into hasher: inout Hasher) {
if self.isNFCFastUTF8 {
diff --git a/stdlib/public/core/StringProtocol.swift b/stdlib/public/core/StringProtocol.swift
index 2927db9..433f104 100644
--- a/stdlib/public/core/StringProtocol.swift
+++ b/stdlib/public/core/StringProtocol.swift
@@ -132,7 +132,6 @@
get { return String(self) }
}
- @inlinable // Eliminate for String, Substring
internal var _gutsSlice: _StringGutsSlice {
@_specialize(where Self == String)
@_specialize(where Self == Substring)
@@ -152,7 +151,8 @@
@inline(__always) get {
let start = startIndex
let end = endIndex
- _internalInvariant(start.transcodedOffset == 0 && end.transcodedOffset == 0)
+ _internalInvariant(
+ start.transcodedOffset == 0 && end.transcodedOffset == 0)
return Range(uncheckedBounds: (start.encodedOffset, end.encodedOffset))
}
}
diff --git a/test/ClangImporter/ctypes_parse_objc.swift b/test/ClangImporter/ctypes_parse_objc.swift
index 415eb49..9a5e396 100644
--- a/test/ClangImporter/ctypes_parse_objc.swift
+++ b/test/ClangImporter/ctypes_parse_objc.swift
@@ -70,8 +70,17 @@
}
func testImportCFTypes() {
- let t1_unqual: Int = CFIndex_test
- _ = t1_unqual as CoreFoundation.CFIndex
+ let t1_unqual: UInt = CFTypeID_test
+ _ = t1_unqual as CoreFoundation.CFTypeID
+
+ let t2_unqual: UInt = CFOptionFlags_test
+ _ = t2_unqual as CoreFoundation.CFOptionFlags
+
+ let t3_unqual: UInt = CFHashCode_test
+ _ = t3_unqual as CoreFoundation.CFHashCode
+
+ let t4_unqual: Int = CFIndex_test
+ _ = t4_unqual as CoreFoundation.CFIndex
}
func testImportSEL() {
diff --git a/test/DebugInfo/returnlocation.swift b/test/DebugInfo/returnlocation.swift
index 9d964cd..0b4eda2 100644
--- a/test/DebugInfo/returnlocation.swift
+++ b/test/DebugInfo/returnlocation.swift
@@ -184,10 +184,10 @@
public required init?() {
print("hello")
// CHECK_INIT: call {{.*}}@"$ss5print_9separator10terminatoryypd_S2StF"{{.*}}, !dbg [[printLoc:![0-9]+]]
- // CHECK_INIT: br label {{.*}}, !dbg [[retnLoc:![0-9]+]]
+ // CHECK_INIT: ret i{{32|64}} 0, !dbg [[retnLoc:![0-9]+]]
- // CHECK_INIT: [[printLoc]] = !DILocation(line: [[@LINE-4]]
- // CHECK_INIT: [[retnLoc]] = !DILocation(line: [[@LINE+1]]
+ // CHECK_INIT: [[retnLoc]] = !DILocation(line: 0
+ // CHECK_INIT: [[printLoc]] = !DILocation(line: [[@LINE-5]]
return nil
}
}
diff --git a/test/IRGen/nondominant.sil b/test/IRGen/nondominant.sil
index 0f408f3..038628f 100644
--- a/test/IRGen/nondominant.sil
+++ b/test/IRGen/nondominant.sil
@@ -16,11 +16,9 @@
br bb2
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc i8 @test0()
-// CHECK: br
// CHECK-NOT: }
// CHECK: ret i8 7
// CHECK-NOT: }
-// CHECK: br
// CHECK: }
// Just don't crash on this one.
diff --git a/test/IRGen/objc_properties.swift b/test/IRGen/objc_properties.swift
index d66b6e8..8e87328 100644
--- a/test/IRGen/objc_properties.swift
+++ b/test/IRGen/objc_properties.swift
@@ -235,10 +235,10 @@
// CHECK: @_INSTANCE_METHODS__TtC15objc_properties4Tree =
// CHECK: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(parent)", i64 0, i64 0),
// CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0),
-// CHECK: i8* bitcast (%2* (%2*, i8*)* @"$s15objc_properties4TreeC6parentACSgXwvgTo" to i8*)
+// CHECK: i8* bitcast (%2* (%2*, i8*)* @"$s15objc_properties4TreeC6parentACSgvgTo" to i8*)
// CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"\01L_selector_data(setParent:)", i64 0, i64 0),
// CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0),
-// CHECK: i8* bitcast (void (%2*, i8*, %2*)* @"$s15objc_properties4TreeC6parentACSgXwvsTo" to i8*)
+// CHECK: i8* bitcast (void (%2*, i8*, %2*)* @"$s15objc_properties4TreeC6parentACSgvsTo" to i8*)
// CHECK: @_PROTOCOL__TtP15objc_properties5Proto_ = private constant { {{.+}} } {
// CHECK: i8* null,
diff --git a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
index 508e499..51cd769 100644
--- a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
+++ b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
@@ -18,8 +18,21 @@
typedef CFTypeRef CFAliasForTypeRef;
-
+#if __LLP64__
+typedef unsigned long long CFTypeID;
+typedef unsigned long long CFOptionFlags;
+typedef unsigned long long CFHashCode;
+typedef signed long long CFIndex;
+#else
+typedef unsigned long CFTypeID;
+typedef unsigned long CFOptionFlags;
+typedef unsigned long CFHashCode;
typedef signed long CFIndex;
+#endif
+
+extern CFTypeID CFTypeID_test;
+extern CFOptionFlags CFOptionFlags_test;
+extern CFHashCode CFHashCode_test;
extern CFIndex CFIndex_test;
#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
diff --git a/test/ParseableInterface/Inputs/TestModule.swift b/test/ParseableInterface/Inputs/TestModule.swift
new file mode 100644
index 0000000..4d60117
--- /dev/null
+++ b/test/ParseableInterface/Inputs/TestModule.swift
@@ -0,0 +1,3 @@
+public struct TestStruct {
+ public init() {}
+}
diff --git a/test/ParseableInterface/access-filter.swift b/test/ParseableInterface/access-filter.swift
index 64e2a75..b499dda 100644
--- a/test/ParseableInterface/access-filter.swift
+++ b/test/ParseableInterface/access-filter.swift
@@ -109,7 +109,9 @@
// CHECK: extension PublicStruct {{[{]$}}
extension PublicStruct {
- // CHECK: public private(set) static var secretlySettable: Int{{$}}
+ // CHECK: @_hasInitialValue public static var secretlySettable: Int {
+ // CHECK-NEXT: get
+ // CHECK-NEXT: }
public private(set) static var secretlySettable: Int = 0
} // CHECK: {{^[}]$}}
diff --git a/test/ParseableInterface/linking-to-module.swift b/test/ParseableInterface/linking-to-module.swift
new file mode 100644
index 0000000..ee9dd64
--- /dev/null
+++ b/test/ParseableInterface/linking-to-module.swift
@@ -0,0 +1,10 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-build-swift -emit-library -module-name TestModule -module-link-name coreTestModuleKitUtilsTool %S/Inputs/TestModule.swift -emit-parseable-module-interface -o %t/libcoreTestModuleKitUtilsTool.%target-dylib-extension
+// RUN: %target-swift-frontend -emit-ir -I %t -L %t -enable-parseable-module-interface %s | %FileCheck %s
+
+import TestModule
+
+_ = TestStruct()
+
+// CHECK: -lcoreTestModuleKitUtilsTool
diff --git a/test/ParseableInterface/stored-properties-client.swift b/test/ParseableInterface/stored-properties-client.swift
new file mode 100644
index 0000000..a7e04fd
--- /dev/null
+++ b/test/ParseableInterface/stored-properties-client.swift
@@ -0,0 +1,143 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -typecheck %S/stored-properties.swift -module-name StoredProperties -emit-parseable-module-interface-path %t/StoredProperties.swiftinterface
+// RUN: %target-swift-frontend -emit-ir %s -I %t -enable-parseable-module-interface | %FileCheck %s -check-prefix CHECK -check-prefix COMMON
+
+// RUN: %target-swift-frontend -typecheck %S/stored-properties.swift -enable-resilience -module-name StoredProperties -emit-parseable-module-interface-path %t/StoredProperties.swiftinterface
+// RUN: %target-swift-frontend -emit-ir %s -I %t -enable-parseable-module-interface | %FileCheck %s -check-prefix RESILIENT -check-prefix COMMON
+
+import StoredProperties
+
+/// This test makes sure clients of a parseable interface see correct type
+/// layout and use the right access patterns in the presence of a
+/// .swiftinterface file, in both resilient and non-resilient cases.
+
+// COMMON: %[[BAGOFVARIABLES:T16StoredProperties14BagOfVariablesV]] = type <{ %TSi, %TSb, [{{(3|7)}} x i8], %TSi }>
+
+// This type is non-@_fixed_layout, so it becomes opaque in a resilient module
+// CHECK: %[[HASSTOREDPROPERTIES:T16StoredProperties03HasaB0V]] = type <{ %TSi, %TSi, %TSb, [{{(3|7)}} x i8], %TSi, %TSb }>
+// RESILIENT: %[[HASSTOREDPROPERTIES:swift.opaque]] = type opaque
+
+// COMMON: %[[HASSTOREDPROPERTIESFIXEDLAYOUT:T16StoredProperties03HasaB11FixedLayoutV]] = type <{ %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]] }>
+
+// These are here just to make sure the compiler doesn't optimize away accesses.
+// They're overloaded instead of generic so we avoid generic dispatch.
+
+@inline(never)
+func _blackHole(_ value: Int) {}
+
+@inline(never)
+func _blackHole(_ value: Bool) {}
+
+@inline(never)
+func _blackHole(_ value: BagOfVariables) {}
+
+/// In the following code, getting and setting is split because otherwise
+/// the resulting IR is ordered differently.
+
+/// Test that we call the correct accessors in a resilient module, and that
+/// we use trivial storage accesses in a non-resilient module.
+
+func testGetting() {
+ // CHECK: %[[VALUE:.*]] = alloca %[[HASSTOREDPROPERTIES]]
+ // CHECK: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* {{.*}} %[[VALUE]])
+ // RESILIENT: %[[VALUE:.*]] = alloca i8, [[WORD:i[0-9]+]] %size
+ // RESILIENT: %[[VALUECAST:.*]] = bitcast i8* %value to %[[HASSTOREDPROPERTIES]]*
+ // RESILIENT: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* noalias nocapture sret %[[VALUECAST]])
+ var value = HasStoredProperties()
+
+ // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 1
+ // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 2
+
+ // These are accessed in declaration order so the IR is emitted in the same
+ // order.
+
+ // COMMON: call swiftcc [[WORD:i[0-9]+]] @"$s16StoredProperties03HasaB0V14computedGetterSivg"
+ _blackHole(value.computedGetter)
+
+ // COMMON: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V14computedGetSetSivg"
+ _blackHole(value.computedGetSet)
+
+ // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 0
+ // CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 4
+
+ // RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V06simpleA9ImmutableSivg"
+ _blackHole(value.simpleStoredImmutable)
+
+ // RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V06simpleA7MutableSivg"
+ _blackHole(value.simpleStoredMutable)
+
+ // RESILIENT: call swiftcc i1 @"$s16StoredProperties03HasaB0V19storedWithObserversSbvg"
+ _blackHole(value.storedWithObservers)
+
+ // RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V16storedPrivateSetSivg"
+ _blackHole(value.storedPrivateSet)
+}
+
+func testSetting() {
+ // CHECK: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* {{.*}})
+ // RESILIENT: call swiftcc %swift.metadata_response @"$s16StoredProperties03HasaB0VMa"([[WORD]] 0)
+ // RESILIENT: %[[VALUEALLOC:.*]] = alloca i8, [[WORD]] %size
+ // RESILIENT: bitcast i8* %[[VALUEALLOC]] to %[[HASSTOREDPROPERTIES]]*
+ var value = HasStoredProperties()
+
+ // COMMON: call swiftcc void @"$s16StoredProperties03HasaB0V19storedWithObserversSbvs"(i1 false, %[[HASSTOREDPROPERTIES]]* {{.*}})
+ value.storedWithObservers = false
+
+ // COMMON-NEXT: call swiftcc void @"$s16StoredProperties03HasaB0V14computedGetSetSivs"([[WORD]] 4, %[[HASSTOREDPROPERTIES]]* {{.*}})
+ value.computedGetSet = 4
+
+ // CHECK: %[[MUTABLE_PTR:.*]] = getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* {{.*}}, i32 0, i32 1
+ // CHECK: %[[MUTABLE_INT_PTR:.*]] = getelementptr inbounds %TSi, %TSi* %[[MUTABLE_PTR]], i32 0, i32 0
+ // CHECK: store [[WORD]] 4, [[WORD]]* %[[MUTABLE_INT_PTR]]
+ // RESILIENT: call swiftcc void @"$s16StoredProperties03HasaB0V06simpleA7MutableSivs"([[WORD]] 4, %[[HASSTOREDPROPERTIES]]* {{.*}})
+ value.simpleStoredMutable = 4
+}
+
+testGetting()
+testSetting()
+
+/// Test that we always use trivial access patterns for @_fixed_layout types
+/// in resilient or non-resilient modules.
+
+func testFixedLayoutGetting() {
+ // COMMON: %[[VALUEALLOCA:.*]] = alloca %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]
+ // COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutVACycfC"(%[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* {{.*}} %[[VALUEALLOCA]])
+ var value = HasStoredPropertiesFixedLayout()
+
+ // These next two tests just make sure we don't use resilient access patterns
+ // for these fixed_layout structs.
+
+ // COMMON: getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %[[VALUEALLOCA]], i32 0, i32 0
+ // COMMON: getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %[[VALUEALLOCA]], i32 0, i32 1
+
+ // COMMON: call swiftcc void @"$s4main10_blackHoleyy16StoredProperties14BagOfVariablesVF"([[WORD]] %{{.*}}, i1 %{{.*}}, [[WORD]] %{{.*}})
+ _blackHole(value.simpleStoredMutable)
+
+ // COMMON: call swiftcc void @"$s4main10_blackHoleyy16StoredProperties14BagOfVariablesVF"([[WORD]] %{{.*}}, i1 %{{.*}}, [[WORD]] %{{.*}})
+ _blackHole(value.storedWithObservers)
+}
+
+func testFixedLayoutSetting() {
+ // COMMON: %[[VALUEALLOCA:.*]] = alloca %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]
+ // COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutVACycfC"(%[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* {{.*}} %[[VALUEALLOCA]])
+ var value = HasStoredPropertiesFixedLayout()
+
+ // COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutV19storedWithObserversAA14BagOfVariablesVvs"
+ value.storedWithObservers = BagOfVariables()
+
+ // COMMON: %[[PROP:.*]] = getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %value, i32 0, i32 0
+ // COMMON: %[[PROPA:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 0
+ // COMMON: %[[PROPAVAL:.*]] = getelementptr inbounds %TSi, %TSi* %[[PROPA]], i32 0, i32 0
+ // COMMON: store [[WORD]] {{.*}} %[[PROPAVAL]]
+ // COMMON: %[[PROPB:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 1
+ // COMMON: %[[PROPBVAL:.*]] = getelementptr inbounds %TSb, %TSb* %[[PROPB]], i32 0, i32 0
+ // COMMON: store i1 {{.*}} %[[PROPBVAL]]
+ // COMMON: %[[PROPC:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 3
+ // COMMON: %[[PROPCVAL:.*]] = getelementptr inbounds %TSi, %TSi* %[[PROPC]], i32 0, i32 0
+ // COMMON: store [[WORD]] {{.*}} %[[PROPCVAL]]
+ value.simpleStoredMutable = BagOfVariables()
+}
+
+testFixedLayoutGetting()
+testFixedLayoutSetting()
diff --git a/test/ParseableInterface/stored-properties.swift b/test/ParseableInterface/stored-properties.swift
new file mode 100644
index 0000000..35e7682
--- /dev/null
+++ b/test/ParseableInterface/stored-properties.swift
@@ -0,0 +1,104 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.swiftinterface %s
+// RUN: %FileCheck %s < %t.swiftinterface --check-prefix CHECK --check-prefix COMMON
+
+// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t-resilient.swiftinterface -enable-resilience %s
+// RUN: %FileCheck %s < %t-resilient.swiftinterface --check-prefix RESILIENT --check-prefix COMMON
+
+// RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule %t.swiftinterface -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -module-name Test -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix CHECK --check-prefix COMMON
+
+// RUN: %target-swift-frontend -emit-module -o %t/TestResilient.swiftmodule -enable-resilience %t-resilient.swiftinterface -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/TestResilient.swiftmodule -module-name TestResilient -enable-resilience -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix RESILIENT --check-prefix COMMON
+
+// COMMON: public struct HasStoredProperties {
+public struct HasStoredProperties {
+ // COMMON: public var computedGetter: [[INT:.*Int]] {
+ // COMMON-NEXT: get
+ // COMMON-NEXT: }
+ public var computedGetter: Int { return 3 }
+
+ // COMMON: public var computedGetSet: [[INT]] {
+ // COMMON-NEXT: get
+ // COMMON-NEXT: set
+ // COMMON-NEXT: }
+ public var computedGetSet: Int {
+ get { return 3 }
+ set {}
+ }
+
+ // COMMON: public let simpleStoredImmutable: [[INT]]{{$}}
+ public let simpleStoredImmutable: Int
+
+ // COMMON: public var simpleStoredMutable: [[INT]]{{$}}
+ public var simpleStoredMutable: Int
+
+ // CHECK: @_hasStorage public var storedWithObservers: [[BOOL:.*Bool]] {
+ // RESILIENT: {{^}} public var storedWithObservers: [[BOOL:.*Bool]] {
+ // COMMON-NEXT: get
+ // COMMON-NEXT: set
+ // COMMON-NEXT: }
+ public var storedWithObservers: Bool {
+ willSet {}
+ }
+
+ // CHECK: @_hasStorage public var storedPrivateSet: [[INT]] {
+ // RESILIENT: {{^}} public var storedPrivateSet: [[INT]] {
+ // COMMON-NEXT: get
+ // COMMON-NEXT: }
+ public private(set) var storedPrivateSet: Int
+
+ // CHECK: private var _: [[BOOL]]
+ private var privateVar: Bool
+
+ // COMMON: public init(){{$}}
+ public init() {
+ self.simpleStoredImmutable = 0
+ self.simpleStoredMutable = 0
+ self.storedPrivateSet = 0
+ self.storedWithObservers = false
+ self.privateVar = false
+ }
+
+// COMMON: }
+}
+
+// COMMON: @_fixed_layout public struct BagOfVariables {
+@_fixed_layout
+public struct BagOfVariables {
+ // COMMON: public let a: [[INT]] = 0
+ public let a: Int = 0
+
+ // COMMON: public var b: [[BOOL]] = false
+ public var b: Bool = false
+
+ // COMMON: public var c: [[INT]] = 0
+ public var c: Int = 0
+
+ // COMMON: public init()
+ public init() {}
+
+// COMMON: }
+}
+
+// COMMON: @_fixed_layout public struct HasStoredPropertiesFixedLayout {
+@_fixed_layout
+public struct HasStoredPropertiesFixedLayout {
+ // COMMON: public var simpleStoredMutable: [[BAGOFVARIABLES:.*BagOfVariables]]
+ public var simpleStoredMutable: BagOfVariables
+
+ // COMMON: @_hasStorage public var storedWithObservers: [[BAGOFVARIABLES]] {
+ // COMMON-NEXT: get
+ // COMMON-NEXT: set
+ // COMMON-NEXT: }
+ public var storedWithObservers: BagOfVariables {
+ didSet {}
+ }
+
+ // COMMON: public init(){{$}}
+ public init() {
+ self.simpleStoredMutable = BagOfVariables()
+ self.storedWithObservers = BagOfVariables()
+ }
+}
diff --git a/test/SIL/Parser/final.swift b/test/SIL/Parser/final.swift
index 6be8eef..7f0e30f 100644
--- a/test/SIL/Parser/final.swift
+++ b/test/SIL/Parser/final.swift
@@ -1,7 +1,7 @@
// RUN: %target-swift-frontend %s -emit-silgen | %FileCheck %s
// CHECK: final class Rect
-// CHECK: @_hasStorage @_hasInitialValue final var orgx: Double
+// CHECK: @_hasInitialValue @_hasStorage final var orgx: Double
final class Rect {
var orgx = 0.0
}
diff --git a/test/SILGen/modify.swift b/test/SILGen/modify.swift
index 212979a..1b975ae 100644
--- a/test/SILGen/modify.swift
+++ b/test/SILGen/modify.swift
@@ -224,7 +224,7 @@
class HasWeak {
weak var weakvar: HasWeak?
}
-// CHECK-LABEL: sil hidden [transparent] @$s6modify7HasWeakC7weakvarACSgXwvM : $@yield_once @convention(method) (@guaranteed HasWeak) -> @yields @inout Optional<HasWeak> {
+// CHECK-LABEL: sil hidden [transparent] @$s6modify7HasWeakC7weakvarACSgvM : $@yield_once @convention(method) (@guaranteed HasWeak) -> @yields @inout Optional<HasWeak> {
// CHECK: bb0([[SELF:%.*]] : @guaranteed $HasWeak):
// CHECK: [[PROP:%.*]] = ref_element_addr [[SELF]] : $HasWeak, #HasWeak.weakvar
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[PROP]] : $*@sil_weak Optional<HasWeak>
diff --git a/test/SILGen/struct_resilience.swift b/test/SILGen/struct_resilience.swift
index cbb2404..dc85336 100644
--- a/test/SILGen/struct_resilience.swift
+++ b/test/SILGen/struct_resilience.swift
@@ -120,6 +120,11 @@
// CHECK-LABEL: sil @$s17struct_resilience6MySizeV1hSivg : $@convention(method) (@in_guaranteed MySize) -> Int
public let h: Int
+ // Weak property
+
+// CHECK-LABEL: sil @$s17struct_resilience6MySizeV1iyXlSgvg : $@convention(method) (@in_guaranteed MySize) -> @owned Optional<AnyObject>
+ public weak var i: AnyObject?
+
// Static stored property
// CHECK-LABEL: sil @$s17struct_resilience6MySizeV9copyrightSivgZ : $@convention(method) (@thin MySize.Type) -> Int
diff --git a/test/SILOptimizer/accessed_storage_analysis.sil b/test/SILOptimizer/accessed_storage_analysis.sil
index e12d8ff..124749d 100644
--- a/test/SILOptimizer/accessed_storage_analysis.sil
+++ b/test/SILOptimizer/accessed_storage_analysis.sil
@@ -340,7 +340,7 @@
// CHECK-LABEL: @readIdentifiedClass
// CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @readIdentifiedClass : $@convention(thin) (@guaranteed C) -> Int {
bb0(%0 : $C):
%1 = ref_element_addr %0 : $C, #C.property
@@ -352,7 +352,7 @@
// CHECK-LABEL: @writeIdentifiedClass
// CHECK: [modify] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @writeIdentifiedClass : $@convention(thin) (@guaranteed C, Int) -> () {
bb0(%0 : $C, %1 : $Int):
%2 = ref_element_addr %0 : $C, #C.property
@@ -365,7 +365,7 @@
// CHECK-LABEL: @readWriteIdentifiedClass
// CHECK: [modify] Class %1 = alloc_ref $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @readWriteIdentifiedClass : $@convention(thin) (Int) -> (Int) {
bb0(%0 : $Int):
%1 = alloc_ref $C
@@ -380,7 +380,7 @@
// CHECK-LABEL: @readIdentifiedNestedClass
// CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @readIdentifiedNestedClass : $@convention(thin) (@guaranteed C) -> Int {
bb0(%0 : $C):
%1 = ref_element_addr %0 : $C, #C.property
@@ -394,7 +394,7 @@
// CHECK-LABEL: @writeIdentifiedNestedClass
// CHECK: [modify] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @writeIdentifiedNestedClass : $@convention(thin) (@guaranteed C, Int) -> () {
bb0(%0 : $C, %1 : $Int):
%2 = ref_element_addr %0 : $C, #C.property
@@ -409,7 +409,7 @@
// CHECK-LABEL: @readWriteIdentifiedNestedClass
// CHECK: [modify] Class %1 = alloc_ref $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @readWriteIdentifiedNestedClass : $@convention(thin) (Int) -> (Int) {
bb0(%0 : $Int):
%1 = alloc_ref $C
@@ -541,7 +541,7 @@
// Test directly recursive argument access.
// CHECK-LABEL: @readRecursiveArgument
// CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @readRecursiveArgument : $@convention(thin) (@guaranteed C, Int) -> Int {
bb0(%0 : $C, %1 : $Int):
%propaddr = ref_element_addr %0 : $C, #C.property
@@ -556,7 +556,7 @@
// Test a class argument access from an optional caller value.
// CHECK-LABEL: @readOptionalArgumentInCallee
// CHECK: [read] Class %1 = unchecked_enum_data %0 : $Optional<C>, #Optional.some!enumelt.1
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil @readOptionalArgumentInCallee : $@convention(thin) (@guaranteed Optional<C>) -> Int {
bb0(%0 : $Optional<C>):
%c = unchecked_enum_data %0 : $Optional<C>, #Optional.some!enumelt.1
@@ -567,7 +567,7 @@
// CHECK-LABEL: @readOptionalArgumentInCalleeHelper
// CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @_hasStorage var property: Int
+// CHECK: Field: var property: Int
sil private @readOptionalArgumentInCalleeHelper : $@convention(thin) (@guaranteed C) -> Int {
bb0(%0 : $C):
%propaddr = ref_element_addr %0 : $C, #C.property
diff --git a/test/SILOptimizer/definite_init_failable_initializers.swift b/test/SILOptimizer/definite_init_failable_initializers.swift
index 4e07dbd..fca7369 100644
--- a/test/SILOptimizer/definite_init_failable_initializers.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers.swift
@@ -38,12 +38,8 @@
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers14FailableStructV24failBeforeInitializationACSgyt_tcfC
// CHECK: bb0(%0 : $@thin FailableStruct.Type):
// CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableStruct
-// CHECK: br bb1
-// CHECK: bb1:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
+// CHECK: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[SELF]]
init?(failBeforeInitialization: ()) {
return nil
@@ -57,14 +53,10 @@
// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[WRITE]]
// CHECK-NEXT: store [[CANARY]] to [[X_ADDR]]
// CHECK-NEXT: end_access [[WRITE]] : $*FailableStruct
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]
// CHECK-NEXT: destroy_addr [[X_ADDR]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[SELF]]
init?(failAfterPartialInitialization: ()) {
x = Canary()
@@ -84,13 +76,9 @@
// CHECK-NEXT: [[Y_ADDR:%.*]] = struct_element_addr [[WRITE]]
// CHECK-NEXT: store [[CANARY2]] to [[Y_ADDR]]
// CHECK-NEXT: end_access [[WRITE]] : $*FailableStruct
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[NEW_SELF]]
init?(failAfterFullInitialization: ()) {
x = Canary()
@@ -105,13 +93,9 @@
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [static] [[SELF_BOX]] : $*FailableStruct
// CHECK-NEXT: store [[CANARY]] to [[WRITE]]
// CHECK-NEXT: end_access [[WRITE]] : $*FailableStruct
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[SELF_VALUE:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[SELF_VALUE]]
init?(failAfterWholeObjectInitializationByAssignment: ()) {
self = FailableStruct(noFail: ())
@@ -124,13 +108,9 @@
// CHECK: [[INIT_FN:%.*]] = function_ref @$s35definite_init_failable_initializers14FailableStructV6noFailACyt_tcfC
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0)
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[NEW_SELF]]
init?(failAfterWholeObjectInitializationByDelegation: ()) {
self.init(noFail: ())
@@ -147,7 +127,9 @@
//
// CHECK: [[FAIL_BB]]:
// CHECK-NEXT: release_value [[SELF_OPTIONAL]]
-// CHECK-NEXT: br [[FAIL_EPILOG_BB:bb[0-9]+]]
+// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
+// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
+// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableStruct>)
//
// CHECK: [[SUCC_BB]]:
// CHECK-NEXT: [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]]
@@ -158,11 +140,6 @@
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableStruct>)
//
-// CHECK: [[FAIL_EPILOG_BB]]:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableStruct>)
-//
// CHECK: [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<FailableStruct>)
// CHECK-NEXT: return [[NEW_SELF]]
// Optional to optional
@@ -212,12 +189,8 @@
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers22FailableAddrOnlyStructV{{[_0-9a-zA-Z]*}}failBeforeInitialization{{.*}}tcfC
// CHECK: bb0(%0 : $*Optional<FailableAddrOnlyStruct<T>>, %1 : $@thin FailableAddrOnlyStruct<T>.Type):
// CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableAddrOnlyStruct<T>
-// CHECK: br bb1
-// CHECK: bb1:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
+// CHECK: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: inject_enum_addr %0
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK: return
init?(failBeforeInitialization: ()) {
return nil
@@ -235,14 +208,10 @@
// CHECK-NEXT: copy_addr [take] [[X_BOX]] to [initialization] [[X_ADDR]]
// CHECK-NEXT: end_access [[WRITE]] : $*FailableAddrOnlyStruct<T>
// CHECK-NEXT: dealloc_stack [[X_BOX]]
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]
// CHECK-NEXT: destroy_addr [[X_ADDR]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: inject_enum_addr %0
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK: return
init?(failAfterPartialInitialization: ()) {
x = T()
@@ -270,13 +239,9 @@
// CHECK-NEXT: copy_addr [take] [[Y_BOX]] to [initialization] [[Y_ADDR]]
// CHECK-NEXT: end_access [[WRITE]] : $*FailableAddrOnlyStruct<T>
// CHECK-NEXT: dealloc_stack [[Y_BOX]]
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: inject_enum_addr %0
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK: return
init?(failAfterFullInitialization: ()) {
x = T()
@@ -548,8 +513,10 @@
// CHECK-NEXT: cond_br [[COND]], [[SUCC_BB:bb[0-9]+]], [[FAIL_BB:bb[0-9]+]]
//
// CHECK: [[FAIL_BB]]:
-// CHECK-NEXT: release_value [[SELF_OPTIONAL]]
-// CHECK-NEXT: br [[FAIL_EPILOG_BB:bb[0-9]+]]
+// CHECK: release_value [[SELF_OPTIONAL]]
+// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
+// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<ThrowStruct>, #Optional.none!enumelt
+// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<ThrowStruct>)
//
// CHECK: [[SUCC_BB]]:
// CHECK-NEXT: [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]]
@@ -560,21 +527,13 @@
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<ThrowStruct>)
//
-// CHECK: [[FAIL_EPILOG_BB]]:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<ThrowStruct>, #Optional.none!enumelt
-// CHECK-NEXT: br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<ThrowStruct>)
-//
// CHECK: [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<ThrowStruct>):
// CHECK-NEXT: return [[NEW_SELF]] : $Optional<ThrowStruct>
//
-// CHECK: [[TRY_APPLY_FAIL_TRAMPOLINE_BB:bb[0-9]+]]:
+// CHECK: [[TRY_APPLY_FAIL_BB]]([[ERROR]] : $Error):
// CHECK-NEXT: strong_release [[ERROR:%.*]] : $Error
// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<ThrowStruct>, #Optional.none!enumelt
// CHECK-NEXT: br [[TRY_APPLY_CONT]]([[NEW_SELF]] : $Optional<ThrowStruct>)
-//
-// CHECK: [[TRY_APPLY_FAIL_BB]]([[ERROR]] : $Error):
-// CHECK-NEXT: br [[TRY_APPLY_FAIL_TRAMPOLINE_BB]]
init?(throwsToOptional: Int) {
try? self.init(failDuringDelegation: throwsToOptional)
}
@@ -767,12 +726,8 @@
// CHECK-NEXT: [[WRITE:%.*]] = begin_access [modify] [dynamic] [[MEMBER_ADDR]] : $*Canary
// CHECK-NEXT: store [[CANARY]] to [[WRITE]]
// CHECK-NEXT: end_access [[WRITE]] : $*Canary
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: strong_release %0
// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[NEW_SELF]]
init?(failAfterFullInitialization: ()) {
member = Canary()
@@ -782,12 +737,8 @@
// CHECK-LABEL: sil hidden @$s35definite_init_failable_initializers17FailableBaseClassC20failBeforeDelegationACSgyt_tcfC
// CHECK: bb0(%0 : $@thick FailableBaseClass.Type):
// CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
-// CHECK: br bb1
-// CHECK: bb1:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
+// CHECK: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[RESULT]]
convenience init?(failBeforeDelegation: ()) {
return nil
@@ -799,13 +750,9 @@
// CHECK: [[INIT_FN:%.*]] = class_method %0
// CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0)
// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[RESULT]]
convenience init?(failAfterDelegation: ()) {
self.init(noFail: ())
@@ -834,8 +781,8 @@
// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableBaseClass>)
//
// CHECK: [[FAIL_TRAMPOLINE_BB]]:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
+// CHECK: dealloc_stack [[SELF_BOX]]
+// CHECK: [[NEW_SELF:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
// CHECK-NEXT: br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableBaseClass>)
//
// CHECK: [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<FailableBaseClass>):
@@ -875,14 +822,10 @@
// CHECK: bb0(%0 : $FailableDerivedClass):
// CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableDerivedClass
// CHECK: store %0 to [[SELF_BOX]]
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick FailableDerivedClass.Type
// CHECK-NEXT: dealloc_partial_ref %0 : $FailableDerivedClass, [[METATYPE]] : $@thick FailableDerivedClass.Type
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<FailableDerivedClass>, #Optional.none!enumelt
-// CHECK-NEXT: br bb2
-// CHECK: bb2:
// CHECK-NEXT: return [[RESULT]]
init?(derivedFailBeforeDelegation: ()) {
return nil
@@ -905,7 +848,9 @@
//
// CHECK: [[FAIL_BB]]:
// CHECK-NEXT: release_value [[SELF_OPTIONAL]]
-// CHECK-NEXT: br [[FAIL_TRAMPOLINE_BB:bb[0-9]+]]
+// CHECK: dealloc_stack [[SELF_BOX]]
+// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableDerivedClass>, #Optional.none!enumelt
+// CHECK-NEXT: br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableDerivedClass>)
//
// CHECK: [[SUCC_BB]]:
// CHECK-NEXT: [[BASE_SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]]
@@ -917,11 +862,6 @@
// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]([[NEW_SELF]] : $Optional<FailableDerivedClass>)
//
-// CHECK: [[FAIL_TRAMPOLINE_BB]]:
-// CHECK-NEXT: dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional<FailableDerivedClass>, #Optional.none!enumelt
-// CHECK-NEXT: br [[EPILOG_BB]]([[NEW_SELF]] : $Optional<FailableDerivedClass>)
-//
// CHECK: [[EPILOG_BB]]([[NEW_SELF:%.*]] : $Optional<FailableDerivedClass>):
// CHECK-NEXT: return [[NEW_SELF]] : $Optional<FailableDerivedClass>
init?(derivedFailDuringDelegation: ()) {
diff --git a/test/SILOptimizer/definite_init_failable_initializers_objc.swift b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
index 04abe6b..c19d1bb 100644
--- a/test/SILOptimizer/definite_init_failable_initializers_objc.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
@@ -39,12 +39,15 @@
// CHECK-NEXT: cond_br [[COND]], bb1, bb2
// CHECK: bb1:
- // CHECK-NEXT: br bb4
+ // CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr %2 : $Cat, #Cat.x
+ // CHECK-NEXT: destroy_addr [[FIELD_ADDR]] : $*LifetimeTracked
+ // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type
+ // CHECK-NEXT: dealloc_partial_ref %2 : $Cat, [[METATYPE]] : $@thick Cat.Type
+ // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
+ // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.none!enumelt
+ // CHECK-NEXT: br bb3([[RESULT]] : $Optional<Cat>)
// CHECK: bb2:
- // ChECK-NEXT br bb3
-
- // CHECK: bb3:
// CHECK-NEXT: [[SUPER:%.*]] = upcast %2 : $Cat to $FakeNSObject
// CHECK-NEXT: [[SUB:%.*]] = unchecked_ref_cast [[SUPER]] : $FakeNSObject to $Cat
// CHECK-NEXT: [[SUPER_FN:%.*]] = objc_super_method [[SUB]] : $Cat, #FakeNSObject.init!initializer.1.foreign : (FakeNSObject.Type) -> () -> FakeNSObject, $@convention(objc_method) (@owned FakeNSObject) -> @owned FakeNSObject
@@ -56,18 +59,9 @@
// CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.some!enumelt.1, [[NEW_SELF]] : $Cat
// CHECK-NEXT: destroy_addr [[SELF_BOX]]
// CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
- // CHECK-NEXT: br bb5([[RESULT]] : $Optional<Cat>)
+ // CHECK-NEXT: br bb3([[RESULT]] : $Optional<Cat>)
- // CHECK: bb4:
- // CHECK-NEXT: [[FIELD_ADDR:%.*]] = ref_element_addr %2 : $Cat, #Cat.x
- // CHECK-NEXT: destroy_addr [[FIELD_ADDR]] : $*LifetimeTracked
- // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick Cat.Type
- // CHECK-NEXT: dealloc_partial_ref %2 : $Cat, [[METATYPE]] : $@thick Cat.Type
- // CHECK-NEXT: dealloc_stack [[SELF_BOX]] : $*Cat
- // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional<Cat>, #Optional.none!enumelt
- // CHECK-NEXT: br bb5([[RESULT]] : $Optional<Cat>)
-
- // CHECK: bb5([[RESULT:%.*]] : $Optional<Cat>):
+ // CHECK: bb3([[RESULT:%.*]] : $Optional<Cat>):
// CHECK-NEXT: return [[RESULT]] : $Optional<Cat>
init?(n: Int, after: Bool) {
diff --git a/test/SILOptimizer/inline_begin_apply.sil b/test/SILOptimizer/inline_begin_apply.sil
index 0bf0a83..2be4c42 100644
--- a/test/SILOptimizer/inline_begin_apply.sil
+++ b/test/SILOptimizer/inline_begin_apply.sil
@@ -54,41 +54,29 @@
// CHECK: [[MK_IND:%.*]] = function_ref @make_indirect
// CHECK: apply [[MK_IND]]<SomeSubclass>([[TEMP]])
// CHECK: destroy_addr [[TEMP]] : $*Indirect<SomeSubclass>
-// CHECK: cond_br %0, bb3, bb5
+// CHECK: cond_br %0, bb1, bb2
-// CHECK:bb1:
+// CHECK: bb1:
+// CHECK: [[I4:%.*]] = integer_literal $Builtin.Int32, 10
+// CHECK: apply [[MARKER]]([[I4]])
// CHECK: [[I2:%.*]] = integer_literal $Builtin.Int32, 2000
// CHECK: apply [[MARKER2]]([[I2]])
// CHECK: dealloc_stack [[TEMP]] : $*Indirect<SomeSubclass>
-// CHECK: br bb4
+// CHECK: [[I5:%.*]] = integer_literal $Builtin.Int32, 20
+// CHECK: apply [[MARKER]]([[I5]])
+// CHECK: br bb3
// CHECK: bb2:
+// CHECK: [[I6:%.*]] = integer_literal $Builtin.Int32, 11
+// CHECK: apply [[MARKER]]([[I6]])
// CHECK: [[I3:%.*]] = integer_literal $Builtin.Int32, 3000
// CHECK: apply [[MARKER2]]([[I3]])
// CHECK: dealloc_stack [[TEMP]] : $*Indirect<SomeSubclass>
-// CHECK: br bb6
-
-// CHECK: bb3:
-// CHECK: [[I4:%.*]] = integer_literal $Builtin.Int32, 10
-// CHECK: apply [[MARKER]]([[I4]])
-// CHECK: br bb1
-
-// CHECK: bb4:
-// CHECK: [[I5:%.*]] = integer_literal $Builtin.Int32, 20
-// CHECK: apply [[MARKER]]([[I5]])
-// CHECK: br bb7
-
-// CHECK: bb5:
-// CHECK: [[I6:%.*]] = integer_literal $Builtin.Int32, 11
-// CHECK: apply [[MARKER]]([[I6]])
-// CHECK: br bb2
-
-// CHECK: bb6:
// CHECK: [[I7:%.*]] = integer_literal $Builtin.Int32, 21
// CHECK: [[MARKER]]([[I7]])
-// CHECK: br bb7
+// CHECK: br bb3
-// CHECK:bb7:
+// CHECK:bb3:
// CHECK: return
// CHECK:}
@@ -197,34 +185,19 @@
// CHECK-NEXT: %2 = function_ref @marker
// CHECK-NEXT: %3 = integer_literal $Builtin.Int32, 1000
// CHECK-NEXT: %4 = apply %2(%3)
-// CHECK-NEXT: cond_br %0, bb3, bb5
-
+// CHECK-NEXT: cond_br %0, bb1, bb2
// CHECK: bb1:
// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int32, 2000
// CHECK-NEXT: apply %2([[T0]])
// CHECK-NEXT: destroy_value %1 : $SomeClass
// CHECK-NEXT: tuple ()
-// CHECK-NEXT: br bb4
-
+// CHECK-NEXT: br bb3
// CHECK: bb2:
// CHECK-NEXT: [[T1:%.*]] = integer_literal $Builtin.Int32, 3000
// CHECK-NEXT: apply %2([[T1]])
// CHECK-NEXT: destroy_value %1 : $SomeClass
-// CHECK-NEXT: br bb6
-
+// CHECK-NEXT: br bb3
// CHECK: bb3:
-// CHECK-NEXT: br bb1
-
-// CHECK: bb4:
-// CHECK-NEXT: br bb7
-
-// CHECK: bb5:
-// CHECK-NEXT: br bb2
-
-// CHECK: bb6:
-// CHECK-NEXT: br bb7
-
-// CHECK: bb7:
// CHECK-NEXT: [[T0:%.*]] = tuple ()
// CHECK-NEXT: return [[T0]] : $()
@@ -298,15 +271,17 @@
// CHECK-NEXT: %1 = alloc_stack $Builtin.Int8
// CHECK-NEXT: %2 = integer_literal $Builtin.Int8, 8
// CHECK-NEXT: store %2 to [trivial] %1 : $*Builtin.Int8
-// CHECK-NEXT: cond_br %0, bb3, bb5
+// CHECK-NEXT: cond_br %0, bb1, bb2
// CHECK: bb1:
+// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int8, 8
+// CHECK-NEXT: store [[T0]] to [trivial] %1 : $*Builtin.Int8
// CHECK-NEXT: // function_ref
// CHECK-NEXT: [[USE:%.*]] = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> ()
// CHECK-NEXT: apply [[USE]](%1) : $@convention(thin) (@in Builtin.Int8) -> ()
// CHECK-NEXT: dealloc_stack %1 : $*Builtin.Int8
// CHECK-NEXT: tuple ()
-// CHECK-NEXT: br bb4
+// CHECK-NEXT: br bb3
// CHECK: bb2:
// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int32, 3000
@@ -314,23 +289,9 @@
// CHECK-NEXT: [[MARKER:%.*]] = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
// CHECK-NEXT: apply [[MARKER]]([[T0]]) : $@convention(thin) (Builtin.Int32) -> ()
// CHECK-NEXT: dealloc_stack %1 : $*Builtin.Int8
-// CHECK-NEXT: br bb6
+// CHECK-NEXT: br bb3
// CHECK: bb3:
-// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int8, 8
-// CHECK-NEXT: store [[T0]] to [trivial] %1 : $*Builtin.Int8
-// CHECK-NEXT: br bb1
-
-// CHECK: bb4:
-// CHECK-NEXT: br bb7
-
-// CHECK: bb5:
-// CHECK-NEXT: br bb2
-
-// CHECK: bb6:
-// CHECK-NEXT: br bb7
-
-// CHECK: bb7:
// CHECK-NEXT: [[T0:%.*]] = tuple ()
// CHECK-NEXT: return [[T0]] : $()
// CHECK: }
@@ -471,8 +432,6 @@
// CHECK-NEXT: store [[I1000]] to [trivial] [[A32]]
// CHECK-NEXT: [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
// CHECK-NEXT: apply [[MARKER]]([[I2000]])
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
// CHECK-NEXT: apply [[MARKER]]([[I3000]])
// CHECK-NEXT: dealloc_stack [[A32]] : $*Builtin.Int32
@@ -481,8 +440,6 @@
// CHECK-NEXT: [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
// CHECK-NEXT: apply [[MARKER]]([[I4000]])
// CHECK-NEXT: tuple ()
-// CHECK-NEXT: br [[END:bb[0-9]+]]
-// CHECK: [[END]]:
// CHECK-NEXT: [[RET:%.*]] = tuple ()
// CHECK-NEXT: return [[RET]] : $()
// CHECK-LABEL: // end sil function 'test_stack_overlap_dealloc'
@@ -507,15 +464,11 @@
// CHECK-NEXT: [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
// CHECK-NEXT: apply [[MARKER]]([[I2000]])
// CHECK-NEXT: [[A16:%.*]] = alloc_stack $Builtin.Int16
-// CHECK-NEXT: br bb1
-// CHECK: bb1:
// CHECK-NEXT: [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
// CHECK-NEXT: apply [[MARKER]]([[I3000]])
// CHECK-NEXT: [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
// CHECK-NEXT: apply [[MARKER]]([[I4000]])
// CHECK-NEXT: tuple ()
-// CHECK-NEXT: br [[END:bb[0-9]+]]
-// CHECK: [[END]]:
// CHECK-NEXT: dealloc_stack [[A16]] : $*Builtin.Int16
// Note that this has been delayed to follow stack discipline.
// CHECK-NEXT: dealloc_stack [[A32]] : $*Builtin.Int32
diff --git a/test/SILOptimizer/mandatory_inlining.sil b/test/SILOptimizer/mandatory_inlining.sil
index a269fca..d5a7ba3 100644
--- a/test/SILOptimizer/mandatory_inlining.sil
+++ b/test/SILOptimizer/mandatory_inlining.sil
@@ -353,19 +353,13 @@
// CHECK: [[BB5]]:
// CHECK: [[VAL50:%.*]] = load [[PB16]]
- // CHECK: br [[BB6:.*]]([[VAL50]]
-
-// CHECK: [[BB6]]([[VAL52:%.*]] : $Float):
// CHECK: strong_release [[VAL16]]
// CHECK: strong_release [[VAL15]]
- // CHECK: br [[BB7:.*]]([[VAL52]]
-
-// CHECK: [[BB7]]([[VAL56:%.*]] : $Float):
// CHECK: [[VAL57:%.*]] = function_ref @convertFromBuiltinFloatLiteral
// CHECK: [[VAL58:%.*]] = metatype $@thin Float.Type
// CHECK: [[VAL59:%.*]] = float_literal $Builtin.FPIEEE64, 0x4008000000000000
// CHECK: [[VAL60:%.*]] = apply [[VAL57]]([[VAL59]], [[VAL58]])
- // CHECK: [[VAL61:%.*]] = apply [[VAL3]]([[VAL56]], [[VAL60]])
+ // CHECK: [[VAL61:%.*]] = apply [[VAL3]]([[VAL50]], [[VAL60]])
// CHECK: strong_release [[VAL1]]
// CHECK: return [[VAL61]]
@@ -512,22 +506,14 @@
// CHECK-LABEL: sil [transparent] @test_partial_nativeobject_foo : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
// CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject):
// CHECK: [[FN:%.*]] = function_ref @test_partial_nativeobject_baz :
-// CHECK: br bb1
-//
-// CHECK: bb1:
// CHECK: strong_retain [[ARG]]
// CHECK: [[PAI:%.*]] = partial_apply [[FN]]([[ARG]])
-// CHECK: br bb2
-//
-// CHECK: bb2:
// CHECK: strong_retain [[ARG]]
// CHECK: strong_retain [[PAI]]
// CHECK: strong_retain [[ARG]]
// CHECK: strong_release [[PAI]]
// CHECK: [[FN2:%.*]] = function_ref @nativeobject_plus :
// CHECK: [[RESULT:%.*]] = apply [[FN2]]([[ARG]], [[ARG]])
-//
-// CHECK: bb3:
// CHECK: strong_retain [[PAI]]
// CHECK: [[OPAQUE_FN:%.*]] = function_ref @partial_apply_user
// CHECK: apply [[OPAQUE_FN]]([[PAI]])
@@ -631,9 +617,6 @@
// CHECK: br [[BB3]](
// CHECK: [[BB3]](
- // CHECK: br [[BB4:.*]](
-
-// CHECK: [[BB4]](
// CHECK: strong_release [[VAL4]]
// CHECK: return {{.*}}
@@ -681,9 +664,6 @@
// CHECK: br [[BB3]](
// CHECK: [[BB3]](
- // CHECK: br [[BB4:.*]](
-
-// CHECK: [[BB4]](
// CHECK: strong_release [[VAL3]]
// CHECK: return {{.*}}
diff --git a/test/SILOptimizer/mandatory_inlining_ownership.sil b/test/SILOptimizer/mandatory_inlining_ownership.sil
index 4712c3b..2ba9b37 100644
--- a/test/SILOptimizer/mandatory_inlining_ownership.sil
+++ b/test/SILOptimizer/mandatory_inlining_ownership.sil
@@ -57,14 +57,15 @@
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $C
// CHECK: [[ADDR:%.*]] = ref_element_addr [[BORROW]] : $C, #C.i
// CHECK: [[VAL:%.*]] = load [trivial] [[ADDR]] : $*Builtin.Int64
-// CHECK: bb{{.*}}([[RET:%.*]] : @trivial $Builtin.Int64):
-// CHECK: end_borrow [[BORROW]] : $C
-// CHECK: destroy_value %0 : $C
-// CHECK: return [[RET]] : $Builtin.Int64
-// CHECK: bb{{.*}}([[ERR:%.*]] : @owned $Error):
+// CHECK: bb{{.*}}:
+// CHECK: [[ERR:%.*]] = alloc_existential_box $Error, $MyError
// CHECK: end_borrow [[BORROW]] : $C
// CHECK: destroy_value %0 : $C
// CHECK: throw [[ERR]] : $Error
+// CHECK: bb{{.*}}:
+// CHECK: end_borrow [[BORROW]] : $C
+// CHECK: destroy_value %0 : $C
+// CHECK: return [[VAL]] : $Builtin.Int64
// CHECK-LABEL: } // end sil function 'callerWithThrow'
sil @callerWithThrow : $@convention(thin) (@owned C) -> (Builtin.Int64, @error Error) {
bb(%0 : @owned $C):
diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/cake-abi.json
index dc86703..1eab10e 100644
--- a/test/api-digester/Outputs/cake-abi.json
+++ b/test/api-digester/Outputs/cake-abi.json
@@ -246,7 +246,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C3InsACSgXwvg",
+ "usr": "s:4cake2C1C3InsACSgvg",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -279,7 +279,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C3InsACSgXwvs",
+ "usr": "s:4cake2C1C3InsACSgvs",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -288,11 +288,12 @@
}
],
"declKind": "Var",
- "usr": "s:4cake2C1C3InsACSgXwvp",
+ "usr": "s:4cake2C1C3InsACSgvp",
"moduleName": "cake",
"declAttributes": [
"HasInitialValue",
- "ReferenceOwnership"
+ "ReferenceOwnership",
+ "HasStorage"
],
"fixedbinaryorder": 0,
"ownership": 1,
@@ -321,7 +322,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C4Ins2ACXovg",
+ "usr": "s:4cake2C1C4Ins2ACvg",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -346,7 +347,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C4Ins2ACXovs",
+ "usr": "s:4cake2C1C4Ins2ACvs",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -355,11 +356,12 @@
}
],
"declKind": "Var",
- "usr": "s:4cake2C1C4Ins2ACXovp",
+ "usr": "s:4cake2C1C4Ins2ACvp",
"moduleName": "cake",
"declAttributes": [
"HasInitialValue",
- "ReferenceOwnership"
+ "ReferenceOwnership",
+ "HasStorage"
],
"fixedbinaryorder": 1,
"ownership": 2,
@@ -743,7 +745,8 @@
"usr": "s:4cake17fixedLayoutStructV1aSivp",
"moduleName": "cake",
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"fixedbinaryorder": 0,
"hasStorage": true
@@ -786,7 +789,8 @@
"moduleName": "cake",
"isInternal": true,
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"fixedbinaryorder": 1,
"hasStorage": true,
@@ -831,7 +835,8 @@
"moduleName": "cake",
"isInternal": true,
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"fixedbinaryorder": 2,
"hasStorage": true
@@ -873,7 +878,8 @@
"moduleName": "cake",
"declAttributes": [
"HasInitialValue",
- "Available"
+ "Available",
+ "HasStorage"
],
"fixedbinaryorder": 3,
"isLet": true,
@@ -1135,7 +1141,8 @@
"usr": "s:4cake9GlobalVarSivp",
"moduleName": "cake",
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"isLet": true,
"hasStorage": true
@@ -1193,7 +1200,8 @@
"moduleName": "cake",
"isInternal": true,
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"fixedbinaryorder": 0,
"hasStorage": true
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index 10e7ad1..346e4ef 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -289,7 +289,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C3InsACSgXwvg",
+ "usr": "s:4cake2C1C3InsACSgvg",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -322,7 +322,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C3InsACSgXwvs",
+ "usr": "s:4cake2C1C3InsACSgvs",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -331,11 +331,12 @@
}
],
"declKind": "Var",
- "usr": "s:4cake2C1C3InsACSgXwvp",
+ "usr": "s:4cake2C1C3InsACSgvp",
"moduleName": "cake",
"declAttributes": [
"HasInitialValue",
- "ReferenceOwnership"
+ "ReferenceOwnership",
+ "HasStorage"
],
"ownership": 1,
"hasStorage": true
@@ -363,7 +364,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C4Ins2ACXovg",
+ "usr": "s:4cake2C1C4Ins2ACvg",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -388,7 +389,7 @@
}
],
"declKind": "Accessor",
- "usr": "s:4cake2C1C4Ins2ACXovs",
+ "usr": "s:4cake2C1C4Ins2ACvs",
"moduleName": "cake",
"implicit": true,
"declAttributes": [
@@ -397,11 +398,12 @@
}
],
"declKind": "Var",
- "usr": "s:4cake2C1C4Ins2ACXovp",
+ "usr": "s:4cake2C1C4Ins2ACvp",
"moduleName": "cake",
"declAttributes": [
"HasInitialValue",
- "ReferenceOwnership"
+ "ReferenceOwnership",
+ "HasStorage"
],
"ownership": 2,
"hasStorage": true
@@ -807,7 +809,8 @@
"usr": "s:4cake17fixedLayoutStructV1aSivp",
"moduleName": "cake",
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"hasStorage": true
}
@@ -1084,7 +1087,8 @@
"usr": "s:4cake9GlobalVarSivp",
"moduleName": "cake",
"declAttributes": [
- "HasInitialValue"
+ "HasInitialValue",
+ "HasStorage"
],
"isLet": true,
"hasStorage": true
diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
index ba9d048..e2348bb 100644
--- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
@@ -483,6 +483,23 @@
Protocol _NSFastEnumeration has been removed
Protocol _ShadowProtocol has been removed
+Constructor _StringGutsSlice.init(_:) has been removed
+Constructor _StringGutsSlice.init(_:_:) has been removed
+Func _StringGutsSlice._normalizedHash(into:) has been removed
+Func _StringGutsSlice.compare(with:expecting:) has been removed
+Func _StringGutsSlice.withFastUTF8(_:) has been removed
+Struct _StringGutsSlice is now without @_fixed_layout
+Var StringProtocol._gutsSlice has been removed
+Var _StringGutsSlice._guts has been removed
+Var _StringGutsSlice._offsetRange has been removed
+Var _StringGutsSlice.count has been removed
+Var _StringGutsSlice.end has been removed
+Var _StringGutsSlice.isASCII has been removed
+Var _StringGutsSlice.isFastUTF8 has been removed
+Var _StringGutsSlice.isNFCFastUTF8 has been removed
+Var _StringGutsSlice.range has been removed
+Var _StringGutsSlice.start has been removed
+
Func ManagedBufferPointer._sanityCheckValidBufferClass(_:creating:) has been removed
Func _sanityCheck(_:_:file:line:) has been removed
Func _sanityCheckFailure(_:file:line:) has been removed
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 1db82b3..8e13c28 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -839,19 +839,19 @@
}
var observingAccessorsVar1: Int {
- // CHECK: @objc var observingAccessorsVar1: Int {
+ // CHECK: @_hasStorage @objc var observingAccessorsVar1: Int {
willSet {}
- // CHECK-NEXT: {{^}} willSet {}
+ // CHECK-NEXT: {{^}} @objc get
didSet {}
- // CHECK-NEXT: {{^}} didSet {}
+ // CHECK-NEXT: {{^}} @objc set
}
@objc var observingAccessorsVar1_: Int {
- // CHECK: {{^}} @objc var observingAccessorsVar1_: Int {
+ // CHECK: {{^}} @objc @_hasStorage var observingAccessorsVar1_: Int {
willSet {}
- // CHECK-NEXT: {{^}} willSet {}
+ // CHECK-NEXT: {{^}} @objc get
didSet {}
- // CHECK-NEXT: {{^}} didSet {}
+ // CHECK-NEXT: {{^}} @objc set
}
@@ -1709,14 +1709,20 @@
@NSManaged
var goodManaged: Class_ObjC1
- // CHECK-LABEL: {{^}} @objc @NSManaged dynamic var goodManaged: Class_ObjC1
+ // CHECK-LABEL: {{^}} @objc @NSManaged @_hasStorage dynamic var goodManaged: Class_ObjC1 {
+ // CHECK-NEXT: {{^}} @objc get
+ // CHECK-NEXT: {{^}} @objc set
+ // CHECK-NEXT: {{^}} }
@NSManaged
var badManaged: PlainStruct
// expected-error@-1 {{property cannot be marked @NSManaged because its type cannot be represented in Objective-C}}
// expected-note@-2 {{Swift structs cannot be represented in Objective-C}}
// expected-error@-3{{'dynamic' property 'badManaged' must also be '@objc'}}
- // CHECK-LABEL: {{^}} @NSManaged var badManaged: PlainStruct
+ // CHECK-LABEL: {{^}} @NSManaged @_hasStorage var badManaged: PlainStruct {
+ // CHECK-NEXT: {{^}} get
+ // CHECK-NEXT: {{^}} set
+ // CHECK-NEXT: {{^}} }
}
//===---
diff --git a/test/attr/hasInitialValue.swift b/test/attr/hasInitialValue.swift
index e259b24..42594ab 100644
--- a/test/attr/hasInitialValue.swift
+++ b/test/attr/hasInitialValue.swift
@@ -12,7 +12,7 @@
// CHECK: {{^}} @_implicitly_unwrapped_optional @_hasInitialValue var iuo: Int!
var iuo: Int!
- // CHECK: {{^}} lazy var lazyIsntARealInit: Int
+ // CHECK: {{^}} @_hasStorage lazy var lazyIsntARealInit: Int
lazy var lazyIsntARealInit: Int = 0
init() {
diff --git a/test/lit.cfg b/test/lit.cfg
index 8dc375e..60957ae 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -846,7 +846,7 @@
config.target_swift_ide_test = \
('%r -target %s %s %s %s' % (config.swift_ide_test, \
config.variant_triple, \
- resource_dir_opt, pcp_opt, ccp_opt))
+ resource_dir_opt, mcp_opt, ccp_opt))
subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
subst_target_swift_ide_test_mock_sdk_after = ''
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index aac8587..66e59a8 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -688,6 +688,7 @@
case DAK_ShowInInterface:
case DAK_RawDocComment:
case DAK_HasInitialValue:
+ case DAK_HasStorage:
return None;
default:
break;
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index a00f122..512664e 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -804,6 +804,7 @@
android-icu-uc-include=%(arm_dir)s/icu/source/common
android-icu-i18n=%(arm_dir)s/libicui18nswift.so
android-icu-i18n-include=%(arm_dir)s/icu/source/i18n
+android-icu-data=%(arm_dir)s/libicudataswift.so
# Ubuntu 18.04 preset for backwards compat and future customizations.
[preset: buildbot_linux_1804]
diff --git a/utils/build-script b/utils/build-script
index 8afec0f..1c6f250 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -254,7 +254,7 @@
args.android_icu_data is None:
diagnostics.fatal(
"when building for Android, --android-ndk, "
- "--android-ndk-version, --android-icu-uc, "
+ "--android-api-level, --android-icu-uc, "
"--android-icu-uc-include, --android-icu-i18n, "
"--android-icu-i18n-include, and --android-icu-data "
"must be specified")
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 72f0f66..e85b97a 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -1181,6 +1181,7 @@
XCTEST_SOURCE_DIR="${WORKSPACE}/swift-corelibs-xctest"
FOUNDATION_SOURCE_DIR="${WORKSPACE}/swift-corelibs-foundation"
LIBDISPATCH_SOURCE_DIR="${WORKSPACE}/swift-corelibs-libdispatch"
+LIBDISPATCH_STATIC_SOURCE_DIR="${WORKSPACE}/swift-corelibs-libdispatch"
LIBICU_SOURCE_DIR="${WORKSPACE}/icu"
PLAYGROUNDSUPPORT_SOURCE_DIR="${WORKSPACE}/swift-xcode-playground-support"
@@ -1223,6 +1224,9 @@
# products first.
if [[ ! "${SKIP_BUILD_LIBDISPATCH}" ]] ; then
PRODUCTS=("${PRODUCTS[@]}" libdispatch)
+ if [[ -z "${SKIP_BUILD_SWIFT_STATIC_LIBDISPATCH}" ]] ; then
+ PRODUCTS=("${PRODUCTS[@]}" libdispatch_static)
+ fi
fi
if [[ ! "${SKIP_BUILD_FOUNDATION}" ]] ; then
PRODUCTS=("${PRODUCTS[@]}" foundation)
@@ -1570,7 +1574,7 @@
foundation)
echo "${root}/${FOUNDATION_BUILD_TYPE}/bin"
;;
- libdispatch)
+ libdispatch|libdispatch_static)
echo "${root}/${LIBDISPATCH_BUILD_TYPE}/bin"
;;
libicu)
@@ -1715,7 +1719,7 @@
foundation)
echo "--config ${FOUNDATION_BUILD_TYPE}"
;;
- libdispatch)
+ libdispatch|libdispatch_static)
echo "--config ${LIBDISPATCH_BUILD_TYPE}"
;;
libicu)
@@ -2286,7 +2290,6 @@
-DSWIFT_PATH_TO_CMARK_SOURCE:PATH="${CMARK_SOURCE_DIR}"
-DSWIFT_PATH_TO_CMARK_BUILD:PATH="$(build_directory ${host} cmark)"
-DSWIFT_PATH_TO_LIBDISPATCH_SOURCE:PATH="${LIBDISPATCH_SOURCE_DIR}"
- -DSWIFT_PATH_TO_LIBDISPATCH_BUILD:PATH="$(build_directory ${host} libdispatch)"
)
if [[ ! "${SKIP_BUILD_LIBICU}" ]] ; then
@@ -2662,7 +2665,7 @@
)
;;
- libdispatch)
+ libdispatch|libdispatch_static)
LIBDISPATCH_BUILD_DIR=$(build_directory ${host} ${product})
SWIFT_BUILD_PATH="$(build_directory ${host} swift)"
SWIFTC_BIN="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc"
@@ -2726,6 +2729,7 @@
-DSwift_DIR="${SWIFT_BUILD_PATH}/lib/cmake/swift"
-DENABLE_TESTING=YES
+ -DBUILD_SHARED_LIBS=$([[ ${product} == libdispatch_static ]] && echo "NO" || echo "YES")
)
;;
esac
@@ -3282,6 +3286,11 @@
;;
esac
;;
+ libdispatch_static)
+ # FIXME: merge with libdispatch once the unit tests work with
+ # libdispatch_static
+ continue
+ ;;
libicu)
if [[ "${SKIP_TEST_LIBICU}" ]]; then
continue
@@ -3526,7 +3535,7 @@
fi
;;
- libdispatch)
+ libdispatch|libdispatch_static)
if [[ -z "${INSTALL_LIBDISPATCH}" ]] ; then
continue
fi
diff --git a/validation-test/compiler_scale/array_init.swift.gyb b/validation-test/compiler_scale/array_init.swift.gyb
new file mode 100644
index 0000000..18d2096
--- /dev/null
+++ b/validation-test/compiler_scale/array_init.swift.gyb
@@ -0,0 +1,13 @@
+// RUN: %scale-test -Onone --begin 0 --end 10 --step 1 --select transferNodesFromList %s
+// REQUIRES: OS=macosx
+// REQUIRES: asserts
+
+// Test that mandatory inlining is linear on a long series of integer
+// initialization calls.
+
+ let _: [Int] = [
+ %for i in range(0, N):
+ 1,
+ %end
+ 1
+ ]