Merge pull request #7256 from practicalswift/swiftc-28680-swift-typebase-getdesugaredtype
[swiftc (42 vs. 5451)] Add crasher in swift::TypeBase::getDesugaredType(...)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d66418c..b0adc8b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -149,6 +149,10 @@
set(SWIFT_PARALLEL_LINK_JOBS "" CACHE STRING
"Define the maximum number of linker jobs for swift.")
+option(SWIFT_FORCE_OPTIMIZED_TYPECHECKER "Override the optimization setting of
+ the type checker so that it always compiles with optimization. This eases
+ debugging after type checking occurs by speeding up type checking" FALSE)
+
#
# User-configurable Android specific options.
#
@@ -333,11 +337,14 @@
find_version("${SWIFT_PATH_TO_CMARK_BUILD}/src/cmark" "--version" FALSE)
endif()
- find_version(${CMAKE_C_COMPILER} "--version" FALSE)
- find_version(${CMAKE_CXX_COMPILER} "--version" FALSE)
-endfunction()
+ message(STATUS "Finding version for: ${CMAKE_C_COMPILER}")
+ message(STATUS "Found version: ${CMAKE_C_COMPILER_VERSION}")
+ message(STATUS "")
-print_versions()
+ message(STATUS "Finding version for: ${CMAKE_CXX_COMPILER}")
+ message(STATUS "Found version: ${CMAKE_CXX_COMPILER_VERSION}")
+ message(STATUS "")
+endfunction()
set(SWIFT_BUILT_STANDALONE FALSE)
@@ -381,6 +388,9 @@
include(CheckCXXSourceRuns)
include(CMakeParseArguments)
include(CMakePushCheckState)
+
+print_versions()
+
include(SwiftComponents)
include(SwiftHandleGybSources)
include(SwiftSetIfArchBitness)
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 7d83add..12eeb15 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -165,7 +165,7 @@
DEPLOYMENT_VERSION_OSX DEPLOYMENT_VERSION_IOS DEPLOYMENT_VERSION_TVOS DEPLOYMENT_VERSION_WATCHOS
RESULT_VAR_NAME ENABLE_LTO)
cmake_parse_arguments(CFLAGS
- ""
+ "FORCE_BUILD_OPTIMIZED"
"${oneValueArgs}"
""
${ARGN})
@@ -186,7 +186,7 @@
RESULT_VAR_NAME result)
is_build_type_optimized("${CFLAGS_BUILD_TYPE}" optimized)
- if(optimized)
+ if(optimized OR CFLAGS_FORCE_BUILD_OPTIMIZED)
list(APPEND result "-O2")
# Add -momit-leaf-frame-pointer on x86.
@@ -196,7 +196,6 @@
else()
list(APPEND result "-O0")
endif()
-
is_build_type_with_debuginfo("${CFLAGS_BUILD_TYPE}" debuginfo)
if(debuginfo)
_compute_lto_flag("${CFLAGS_ENABLE_LTO}" _lto_flag_out)
@@ -495,6 +494,7 @@
# [FILE_DEPENDS target1 ...]
# [DONT_EMBED_BITCODE]
# [IS_STDLIB]
+# [FORCE_BUILD_OPTIMIZED]
# [IS_STDLIB_CORE]
# [IS_SDK_OVERLAY]
# [FORCE_BUILD_FOR_HOST_SDK]
@@ -576,7 +576,7 @@
set(SWIFTLIB_SINGLE_options
SHARED STATIC OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE IS_SDK_OVERLAY
TARGET_LIBRARY FORCE_BUILD_FOR_HOST_SDK
- API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE)
+ API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE FORCE_BUILD_OPTIMIZED)
cmake_parse_arguments(SWIFTLIB_SINGLE
"${SWIFTLIB_SINGLE_options}"
"MODULE_TARGET;SDK;ARCHITECTURE;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS"
@@ -802,10 +802,14 @@
_set_target_prefix_and_suffix("${target}" "${libkind}" "${SWIFTLIB_SINGLE_SDK}")
if(SWIFTLIB_SINGLE_TARGET_LIBRARY)
- if(NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_UC_INCLUDE}" STREQUAL "")
+ if(NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_UC_INCLUDE}" STREQUAL "" AND
+ NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_UC_INCLUDE}" STREQUAL "/usr/include" AND
+ NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_UC_INCLUDE}" STREQUAL "/usr/${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_ARCH_${SWIFTLIB_SINGLE_ARCHITECTURE}_TRIPLE}/include")
target_include_directories("${target}" SYSTEM PRIVATE "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_UC_INCLUDE}")
endif()
- if(NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_I18N_INCLUDE}" STREQUAL "")
+ if(NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_I18N_INCLUDE}" STREQUAL "" AND
+ NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_I18N_INCLUDE}" STREQUAL "/usr/include" AND
+ NOT "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_I18N_INCLUDE}" STREQUAL "/usr/${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_ARCH_${SWIFTLIB_SINGLE_ARCHITECTURE}_TRIPLE}/include")
target_include_directories("${target}" SYSTEM PRIVATE "${SWIFT_${SWIFTLIB_SINGLE_SDK}_ICU_I18N_INCLUDE}")
endif()
endif()
@@ -1055,6 +1059,7 @@
DEPLOYMENT_VERSION_IOS "${SWIFTLIB_DEPLOYMENT_VERSION_IOS}"
DEPLOYMENT_VERSION_TVOS "${SWIFTLIB_DEPLOYMENT_VERSION_TVOS}"
DEPLOYMENT_VERSION_WATCHOS "${SWIFTLIB_DEPLOYMENT_VERSION_WATCHOS}"
+ "${SWIFTLIB_FORCE_BUILD_OPTIMIZED_keyword}"
RESULT_VAR_NAME c_compile_flags
)
_add_variant_link_flags(
@@ -1328,7 +1333,7 @@
set(SWIFTLIB_options
SHARED STATIC OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE IS_SDK_OVERLAY
TARGET_LIBRARY FORCE_BUILD_FOR_HOST_SDK
- API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE HAS_SWIFT_CONTENT)
+ API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE HAS_SWIFT_CONTENT FORCE_BUILD_OPTIMIZED)
cmake_parse_arguments(SWIFTLIB
"${SWIFTLIB_options}"
"INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS"
@@ -1566,6 +1571,7 @@
${SWIFTLIB_IS_SDK_OVERLAY_keyword}
${SWIFTLIB_TARGET_LIBRARY_keyword}
${SWIFTLIB_FORCE_BUILD_FOR_HOST_SDK_keyword}
+ ${SWIFTLIB_FORCE_BUILD_OPTIMIZED_keyword}
INSTALL_IN_COMPONENT "${SWIFTLIB_INSTALL_IN_COMPONENT}"
DEPLOYMENT_VERSION_OSX "${SWIFTLIB_DEPLOYMENT_VERSION_OSX}"
DEPLOYMENT_VERSION_IOS "${SWIFTLIB_DEPLOYMENT_VERSION_IOS}"
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index 51b030f..7d6a01f 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -548,20 +548,18 @@
///
/// This distinguishes static references to types, like Int, from metatype
/// values, "someTy: Any.Type".
- bool isTypeReference(llvm::function_ref<Type(const Expr &)> getType
- = [](const Expr &E) -> Type {
- return E.getType();
- }) const;
+ bool isTypeReference(llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type {
+ return E->getType();
+ }) const;
/// Determine whether this expression refers to a statically-derived metatype.
///
/// This implies `isTypeReference`, but also requires that the referenced type
/// is not an archetype or dependent type.
bool isStaticallyDerivedMetatype(
- llvm::function_ref<Type(const Expr &)> getType
- = [](const Expr &E) -> Type {
- return E.getType();
- }) const;
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); }) const;
/// isImplicit - Determines whether this expression was implicitly-generated,
/// rather than explicitly written in the AST.
@@ -781,8 +779,10 @@
LiteralExpr(ExprKind Kind, bool Implicit) : Expr(Kind, Implicit) {}
// Make an exact copy of this one AST node.
- LiteralExpr *shallowClone(ASTContext &Ctx) const;
-
+ LiteralExpr *
+ shallowClone(ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) const;
+
static bool classof(const Expr *E) {
return E->getKind() >= ExprKind::First_LiteralExpr &&
E->getKind() <= ExprKind::Last_LiteralExpr;
@@ -1155,8 +1155,9 @@
///
/// Note: prefer to use the second entry point, which separates out
/// arguments/labels/etc.
- static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
- LiteralKind kind, Expr *arg, bool implicit);
+ static ObjectLiteralExpr *
+ create(ASTContext &ctx, SourceLoc poundLoc, LiteralKind kind, Expr *arg,
+ bool implicit, llvm::function_ref<Type(const Expr *)> getType);
/// Create a new object literal expression.
static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
@@ -1340,15 +1341,13 @@
// The type of a TypeExpr is always a metatype type. Return the instance
// type, ErrorType if an error, or null if not set yet.
- Type getInstanceType(llvm::function_ref<bool(const Expr &)> hasType
- = [](const Expr &E) -> bool {
- return !!E.getType();
- },
- llvm::function_ref<Type(const Expr &)> getType
- = [](const Expr &E) -> Type {
- return E.getType();
+ Type getInstanceType(llvm::function_ref<bool(const Expr *)> hasType =
+ [](const Expr *E) -> bool { return !!E->getType(); },
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type {
+ return E->getType();
}) const;
-
+
// Create an implicit TypeExpr, which has no location information.
static TypeExpr *createImplicit(Type Ty, ASTContext &C) {
return new (C) TypeExpr(Ty);
@@ -1714,9 +1713,11 @@
///
/// Note: do not create new callers to this entry point; use the entry point
/// that takes separate index arguments.
- static DynamicSubscriptExpr *create(ASTContext &ctx, Expr *base, Expr *index,
- ConcreteDeclRef decl,
- bool implicit);
+ static DynamicSubscriptExpr *
+ create(ASTContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl,
+ bool implicit,
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); });
/// Create a new dynamic subscript.
static DynamicSubscriptExpr *create(ASTContext &ctx, Expr *base,
@@ -2263,11 +2264,12 @@
///
/// Note: do not create new callers to this entry point; use the entry point
/// that takes separate index arguments.
- static SubscriptExpr *create(ASTContext &ctx, Expr *base, Expr *index,
- ConcreteDeclRef decl = ConcreteDeclRef(),
- bool implicit = false,
- AccessSemantics semantics
- = AccessSemantics::Ordinary);
+ static SubscriptExpr *
+ create(ASTContext &ctx, Expr *base, Expr *index,
+ ConcreteDeclRef decl = ConcreteDeclRef(), bool implicit = false,
+ AccessSemantics semantics = AccessSemantics::Ordinary,
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); });
/// Create a new subscript.
static SubscriptExpr *create(ASTContext &ctx, Expr *base,
@@ -3751,11 +3753,12 @@
/// Create a new call expression.
///
/// Note: prefer to use the entry points that separate out the arguments.
- static CallExpr *create(ASTContext &ctx, Expr *fn, Expr *arg,
- ArrayRef<Identifier> argLabels,
- ArrayRef<SourceLoc> argLabelLocs,
- bool hasTrailingClosure,
- bool implicit, Type type = Type());
+ static CallExpr *
+ create(ASTContext &ctx, Expr *fn, Expr *arg, ArrayRef<Identifier> argLabels,
+ ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure,
+ bool implicit, Type type = Type(),
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); });
/// Create a new implicit call expression without any source-location
/// information.
@@ -3764,11 +3767,13 @@
/// \param args The call arguments, not including a trailing closure (if any).
/// \param argLabels The argument labels, whose size must equal args.size(),
/// or which must be empty.
- static CallExpr *createImplicit(ASTContext &ctx, Expr *fn,
- ArrayRef<Expr *> args,
- ArrayRef<Identifier> argLabels) {
+ static CallExpr *
+ createImplicit(ASTContext &ctx, Expr *fn, ArrayRef<Expr *> args,
+ ArrayRef<Identifier> argLabels,
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); }) {
return create(ctx, fn, SourceLoc(), args, argLabels, { }, SourceLoc(),
- /*trailingClosure=*/nullptr, /*implicit=*/true);
+ /*trailingClosure=*/nullptr, /*implicit=*/true, getType);
}
/// Create a new call expression.
@@ -3780,14 +3785,12 @@
/// \param argLabelLocs The locations of the argument labels, whose size must
/// equal args.size() or which must be empty.
/// \param trailingClosure The trailing closure, if any.
- static CallExpr *create(ASTContext &ctx, Expr *fn,
- SourceLoc lParenLoc,
- ArrayRef<Expr *> args,
- ArrayRef<Identifier> argLabels,
- ArrayRef<SourceLoc> argLabelLocs,
- SourceLoc rParenLoc,
- Expr *trailingClosure,
- bool implicit);
+ static CallExpr *
+ create(ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
+ ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
+ SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); });
SourceLoc getStartLoc() const {
SourceLoc fnLoc = getFn()->getStartLoc();
diff --git a/include/swift/Basic/DiverseStack.h b/include/swift/Basic/DiverseStack.h
index 387515b..0b35138 100644
--- a/include/swift/Basic/DiverseStack.h
+++ b/include/swift/Basic/DiverseStack.h
@@ -116,6 +116,8 @@
return Depth != (std::size_t) -1;
}
+ std::size_t getDepth() const { return Depth; }
+
/// A helper class that wraps a stable_iterator as something that
/// pretends to be a non-null pointer.
///
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 2f9d8df..4b5166c 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -1,3 +1,8 @@
+
+if (SWIFT_FORCE_OPTIMIZED_TYPECHECKER)
+ set(EXTRA_AST_FLAGS "FORCE_BUILD_OPTIMIZED")
+endif()
+
add_swift_library(swiftAST STATIC
ArchetypeBuilder.cpp
ASTContext.cpp
@@ -79,6 +84,8 @@
bitreader bitwriter coroutines coverage irreader debuginfoDWARF
profiledata instrumentation object objcarcopts mc mcparser
bitreader bitwriter lto ipo option core support ${LLVM_TARGETS_TO_BUILD}
+
+ ${EXTRA_AST_FLAGS}
)
# intrinsics_gen is the LLVM tablegen target that generates the include files
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index cd344f0..fd13fad 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -569,10 +569,10 @@
this->walk(ChildWalker(callback));
}
-bool Expr::
-isTypeReference(llvm::function_ref<Type(const Expr &)> getType) const {
+bool Expr::isTypeReference(
+ llvm::function_ref<Type(const Expr *)> getType) const {
// If the result isn't a metatype, there's nothing else to do.
- if (!getType(*this)->is<AnyMetatypeType>())
+ if (!getType(this)->is<AnyMetatypeType>())
return false;
const Expr *expr = this;
@@ -604,14 +604,16 @@
}
bool Expr::isStaticallyDerivedMetatype(
- llvm::function_ref<Type(const Expr &)> getType) const {
+ llvm::function_ref<Type(const Expr *)> getType) const {
// The type must first be a type reference.
if (!isTypeReference(getType))
return false;
// Archetypes are never statically derived.
- return !getType(*this)->getAs<AnyMetatypeType>()->getInstanceType()
- ->is<ArchetypeType>();
+ return !getType(this)
+ ->getAs<AnyMetatypeType>()
+ ->getInstanceType()
+ ->is<ArchetypeType>();
}
bool Expr::isSuperExpr() const {
@@ -858,12 +860,15 @@
// Support methods for Exprs.
//===----------------------------------------------------------------------===//
-static LiteralExpr *shallowCloneImpl(const NilLiteralExpr *E, ASTContext &Ctx) {
+static LiteralExpr *
+shallowCloneImpl(const NilLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
return new (Ctx) NilLiteralExpr(E->getLoc());
}
static LiteralExpr *
-shallowCloneImpl(const IntegerLiteralExpr *E, ASTContext &Ctx) {
+shallowCloneImpl(const IntegerLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
auto res = new (Ctx) IntegerLiteralExpr(E->getDigitsText(),
E->getSourceRange().End);
if (E->isNegative())
@@ -871,7 +876,9 @@
return res;
}
-static LiteralExpr *shallowCloneImpl(const FloatLiteralExpr *E, ASTContext &Ctx) {
+static LiteralExpr *
+shallowCloneImpl(const FloatLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
auto res = new (Ctx) FloatLiteralExpr(E->getDigitsText(),
E->getSourceRange().End);
if (E->isNegative())
@@ -879,26 +886,30 @@
return res;
}
static LiteralExpr *
-shallowCloneImpl(const BooleanLiteralExpr *E, ASTContext &Ctx) {
+shallowCloneImpl(const BooleanLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
return new (Ctx) BooleanLiteralExpr(E->getValue(), E->getLoc());
}
-static LiteralExpr *shallowCloneImpl(const StringLiteralExpr *E, ASTContext &Ctx) {
+static LiteralExpr *
+shallowCloneImpl(const StringLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
auto res = new (Ctx) StringLiteralExpr(E->getValue(), E->getSourceRange());
res->setEncoding(E->getEncoding());
return res;
}
static LiteralExpr *
-shallowCloneImpl(const InterpolatedStringLiteralExpr *E, ASTContext &Ctx) {
+shallowCloneImpl(const InterpolatedStringLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
auto res = new (Ctx) InterpolatedStringLiteralExpr(E->getLoc(),
const_cast<InterpolatedStringLiteralExpr*>(E)->getSegments());
res->setSemanticExpr(E->getSemanticExpr());
return res;
}
-
static LiteralExpr *
-shallowCloneImpl(const MagicIdentifierLiteralExpr *E, ASTContext &Ctx) {
+shallowCloneImpl(const MagicIdentifierLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
auto res = new (Ctx) MagicIdentifierLiteralExpr(E->getKind(),
E->getSourceRange().End);
if (res->isString())
@@ -907,36 +918,38 @@
}
static LiteralExpr *
-shallowCloneImpl(const ObjectLiteralExpr *E, ASTContext &Ctx) {
- auto res = ObjectLiteralExpr::create(Ctx, E->getStartLoc(),
- E->getLiteralKind(),
- E->getArg(), E->isImplicit());
+shallowCloneImpl(const ObjectLiteralExpr *E, ASTContext &Ctx,
+ llvm::function_ref<Type(const Expr *)> getType) {
+ auto res =
+ ObjectLiteralExpr::create(Ctx, E->getStartLoc(), E->getLiteralKind(),
+ E->getArg(), E->isImplicit(), getType);
res->setSemanticExpr(E->getSemanticExpr());
return res;
}
// Make an exact copy of this AST node.
-LiteralExpr *LiteralExpr::shallowClone(ASTContext &Ctx) const {
+LiteralExpr *LiteralExpr::shallowClone(
+ ASTContext &Ctx, llvm::function_ref<Type(const Expr *)> getType) const {
LiteralExpr *Result = nullptr;
switch (getKind()) {
default: llvm_unreachable("Unknown literal type!");
-#define DISPATCH_CLONE(KIND) \
- case ExprKind::KIND: \
- Result = shallowCloneImpl(cast<KIND##Expr>(this), Ctx); \
+#define DISPATCH_CLONE(KIND) \
+ case ExprKind::KIND: \
+ Result = shallowCloneImpl(cast<KIND##Expr>(this), Ctx, getType); \
break;
- DISPATCH_CLONE(NilLiteral)
- DISPATCH_CLONE(IntegerLiteral)
- DISPATCH_CLONE(FloatLiteral)
- DISPATCH_CLONE(BooleanLiteral)
- DISPATCH_CLONE(StringLiteral)
- DISPATCH_CLONE(InterpolatedStringLiteral)
- DISPATCH_CLONE(ObjectLiteral)
- DISPATCH_CLONE(MagicIdentifierLiteral)
+ DISPATCH_CLONE(NilLiteral)
+ DISPATCH_CLONE(IntegerLiteral)
+ DISPATCH_CLONE(FloatLiteral)
+ DISPATCH_CLONE(BooleanLiteral)
+ DISPATCH_CLONE(StringLiteral)
+ DISPATCH_CLONE(InterpolatedStringLiteral)
+ DISPATCH_CLONE(ObjectLiteral)
+ DISPATCH_CLONE(MagicIdentifierLiteral)
#undef DISPATCH_CLONE
}
-
- Result->setType(getType());
+
+ Result->setType(getType(this));
Result->setImplicit(isImplicit());
return Result;
}
@@ -1011,10 +1024,13 @@
unicode::isSingleExtendedGraphemeCluster(Val);
}
-static ArrayRef<Identifier>
-getArgumentLabelsFromArgument(Expr *arg, SmallVectorImpl<Identifier> &scratch,
- SmallVectorImpl<SourceLoc> *sourceLocs = nullptr,
- bool *hasTrailingClosure = nullptr){
+static ArrayRef<Identifier> getArgumentLabelsFromArgument(
+ Expr *arg, SmallVectorImpl<Identifier> &scratch,
+ SmallVectorImpl<SourceLoc> *sourceLocs = nullptr,
+ bool *hasTrailingClosure = nullptr,
+ llvm::function_ref<Type(const Expr *)> getType = [](const Expr *E) -> Type {
+ return E->getType();
+ }) {
if (sourceLocs) sourceLocs->clear();
if (hasTrailingClosure) *hasTrailingClosure = false;
@@ -1045,7 +1061,7 @@
}
// Otherwise, use the type information.
- auto type = arg->getType();
+ auto type = getType(arg);
if (isa<ParenType>(type.getPointer())) {
scratch.clear();
scratch.push_back(Identifier());
@@ -1067,15 +1083,16 @@
}
/// Compute the type of an argument to a call (or call-like) AST
-static void computeSingleArgumentType(ASTContext &ctx, Expr *arg,
- bool implicit) {
+static void
+computeSingleArgumentType(ASTContext &ctx, Expr *arg, bool implicit,
+ llvm::function_ref<Type(const Expr *)> getType) {
// Propagate 'implicit' to the argument.
if (implicit)
arg->setImplicit(true);
// Handle parenthesized expressions.
if (auto paren = dyn_cast<ParenExpr>(arg)) {
- if (auto type = paren->getSubExpr()->getType()) {
+ if (auto type = getType(paren->getSubExpr())) {
arg->setType(ParenType::get(ctx, type));
}
return;
@@ -1085,7 +1102,7 @@
auto tuple = dyn_cast<TupleExpr>(arg);
SmallVector<TupleTypeElt, 4> typeElements;
for (unsigned i = 0, n = tuple->getNumElements(); i != n; ++i) {
- auto type = tuple->getElement(i)->getType();
+ auto type = getType(tuple->getElement(i));
if (!type) return;
typeElements.push_back(TupleTypeElt(type, tuple->getElementName(i)));
@@ -1101,17 +1118,15 @@
///
/// \param argLabelLocs The argument label locations, which might be updated by
/// this function.
-static Expr *packSingleArgument(
- ASTContext &ctx,
- SourceLoc lParenLoc,
- ArrayRef<Expr *> args,
- ArrayRef<Identifier> &argLabels,
- ArrayRef<SourceLoc> &argLabelLocs,
- SourceLoc rParenLoc,
- Expr *trailingClosure,
- bool implicit,
- SmallVectorImpl<Identifier> &argLabelsScratch,
- SmallVectorImpl<SourceLoc> &argLabelLocsScratch) {
+static Expr *
+packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc, ArrayRef<Expr *> args,
+ ArrayRef<Identifier> &argLabels,
+ ArrayRef<SourceLoc> &argLabelLocs, SourceLoc rParenLoc,
+ Expr *trailingClosure, bool implicit,
+ SmallVectorImpl<Identifier> &argLabelsScratch,
+ SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
+ llvm::function_ref<Type(const Expr *)> getType =
+ [](const Expr *E) -> Type { return E->getType(); }) {
// Clear out our scratch space.
argLabelsScratch.clear();
argLabelLocsScratch.clear();
@@ -1122,7 +1137,7 @@
if (args.size() == 1 && (argLabels.empty() || argLabels[0].empty())) {
auto arg = new (ctx) ParenExpr(lParenLoc, args[0], rParenLoc,
/*hasTrailingClosure=*/false);
- computeSingleArgumentType(ctx, arg, implicit);
+ computeSingleArgumentType(ctx, arg, implicit, getType);
argLabelsScratch.push_back(Identifier());
argLabels = argLabelsScratch;
argLabelLocs = { };
@@ -1144,7 +1159,7 @@
auto arg = TupleExpr::create(ctx, lParenLoc, args, argLabels, argLabelLocs,
rParenLoc, /*HasTrailingClosure=*/false,
/*Implicit=*/false);
- computeSingleArgumentType(ctx, arg, implicit);
+ computeSingleArgumentType(ctx, arg, implicit, getType);
return arg;
}
@@ -1153,7 +1168,7 @@
if (args.size() == 0) {
auto arg = new (ctx) ParenExpr(lParenLoc, trailingClosure, rParenLoc,
/*hasTrailingClosure=*/true);
- computeSingleArgumentType(ctx, arg, implicit);
+ computeSingleArgumentType(ctx, arg, implicit, getType);
argLabelsScratch.push_back(Identifier());
argLabels = argLabelsScratch;
argLabelLocs = { };
@@ -1189,7 +1204,7 @@
argLabelLocs, rParenLoc,
/*HasTrailingClosure=*/true,
/*Implicit=*/false);
- computeSingleArgumentType(ctx, arg, implicit);
+ computeSingleArgumentType(ctx, arg, implicit, getType);
return arg;
}
@@ -1210,11 +1225,10 @@
initializeCallArguments(argLabels, argLabelLocs, hasTrailingClosure);
}
-ObjectLiteralExpr *ObjectLiteralExpr::create(ASTContext &ctx,
- SourceLoc poundLoc,
- LiteralKind kind,
- Expr *arg,
- bool implicit) {
+ObjectLiteralExpr *
+ObjectLiteralExpr::create(ASTContext &ctx, SourceLoc poundLoc, LiteralKind kind,
+ Expr *arg, bool implicit,
+ llvm::function_ref<Type(const Expr *)> getType) {
// Inspect the argument to dig out the argument labels, their location, and
// whether there is a trailing closure.
SmallVector<Identifier, 4> argLabelsScratch;
@@ -1222,7 +1236,8 @@
bool hasTrailingClosure = false;
auto argLabels = getArgumentLabelsFromArgument(arg, argLabelsScratch,
&argLabelLocs,
- &hasTrailingClosure);
+ &hasTrailingClosure,
+ getType);
size_t size = totalSizeToAlloc(argLabels, argLabelLocs, hasTrailingClosure);
@@ -1483,9 +1498,11 @@
initializeCallArguments(argLabels, argLabelLocs, hasTrailingClosure);
}
-SubscriptExpr *SubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
- ConcreteDeclRef decl, bool implicit,
- AccessSemantics semantics) {
+SubscriptExpr *
+SubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
+ ConcreteDeclRef decl, bool implicit,
+ AccessSemantics semantics,
+ llvm::function_ref<Type(const Expr *)> getType) {
// Inspect the argument to dig out the argument labels, their location, and
// whether there is a trailing closure.
SmallVector<Identifier, 4> argLabelsScratch;
@@ -1493,7 +1510,8 @@
bool hasTrailingClosure = false;
auto argLabels = getArgumentLabelsFromArgument(index, argLabelsScratch,
&argLabelLocs,
- &hasTrailingClosure);
+ &hasTrailingClosure,
+ getType);
size_t size = totalSizeToAlloc(argLabels, argLabelLocs, hasTrailingClosure);
@@ -1548,7 +1566,8 @@
DynamicSubscriptExpr *
DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
- ConcreteDeclRef decl, bool implicit) {
+ ConcreteDeclRef decl, bool implicit,
+ llvm::function_ref<Type(const Expr *)> getType) {
// Inspect the argument to dig out the argument labels, their location, and
// whether there is a trailing closure.
SmallVector<Identifier, 4> argLabelsScratch;
@@ -1556,7 +1575,8 @@
bool hasTrailingClosure = false;
auto argLabels = getArgumentLabelsFromArgument(index, argLabelsScratch,
&argLabelLocs,
- &hasTrailingClosure);
+ &hasTrailingClosure,
+ getType);
size_t size = totalSizeToAlloc(argLabels, argLabelLocs, hasTrailingClosure);
@@ -1697,8 +1717,8 @@
CallExpr *CallExpr::create(ASTContext &ctx, Expr *fn, Expr *arg,
ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
- bool hasTrailingClosure,
- bool implicit, Type type) {
+ bool hasTrailingClosure, bool implicit, Type type,
+ llvm::function_ref<Type(const Expr *)> getType) {
SmallVector<Identifier, 4> argLabelsScratch;
SmallVector<SourceLoc, 4> argLabelLocsScratch;
if (argLabels.empty()) {
@@ -1706,7 +1726,8 @@
// whether there is a trailing closure.
argLabels = getArgumentLabelsFromArgument(arg, argLabelsScratch,
&argLabelLocsScratch,
- &hasTrailingClosure);
+ &hasTrailingClosure,
+ getType);
argLabelLocs = argLabelLocsScratch;
}
@@ -1717,14 +1738,13 @@
hasTrailingClosure, type);
}
-CallExpr *CallExpr::create(ASTContext &ctx, Expr *fn,
- SourceLoc lParenLoc,
+CallExpr *CallExpr::create(ASTContext &ctx, Expr *fn, SourceLoc lParenLoc,
ArrayRef<Expr *> args,
ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs,
- SourceLoc rParenLoc,
- Expr *trailingClosure,
- bool implicit) {
+ SourceLoc rParenLoc, Expr *trailingClosure,
+ bool implicit,
+ llvm::function_ref<Type(const Expr *)> getType) {
SmallVector<Identifier, 4> argLabelsScratch;
SmallVector<SourceLoc, 4> argLabelLocsScratch;
Expr *arg = packSingleArgument(ctx, lParenLoc, args, argLabels, argLabelLocs,
@@ -1899,15 +1919,15 @@
// The type of a TypeExpr is always a metatype type. Return the instance
// type or null if not set yet.
Type TypeExpr::getInstanceType(
- llvm::function_ref<bool(const Expr &)> hasType,
- llvm::function_ref<Type(const Expr &)> getType) const {
- if (!hasType(*this))
+ llvm::function_ref<bool(const Expr *)> hasType,
+ llvm::function_ref<Type(const Expr *)> getType) const {
+ if (!hasType(this))
return Type();
- if (auto metaType = getType(*this)->getAs<MetatypeType>())
+ if (auto metaType = getType(this)->getAs<MetatypeType>())
return metaType->getInstanceType();
- return ErrorType::get(getType(*this)->getASTContext());
+ return ErrorType::get(getType(this)->getASTContext());
}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index a9cd136..49635fc 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -44,7 +44,9 @@
"${ICU_UC_LIBDIR}"
"${ICU_I18N_LIBDIR}"
OUTPUT
- "${SWIFTSTATICLIB_DIR}/${linkfile}")
+ "${SWIFTSTATICLIB_DIR}/${linkfile}"
+ DEPENDS
+ "${SWIFT_SOURCE_DIR}/utils/gen-static-stdlib-link-args")
list(APPEND static_stdlib_lnk_file_list ${swift_static_stdlib_${sdk}_args})
swift_install_in_component(stdlib
diff --git a/lib/SILGen/Cleanup.cpp b/lib/SILGen/Cleanup.cpp
index 85b05f2..9542537 100644
--- a/lib/SILGen/Cleanup.cpp
+++ b/lib/SILGen/Cleanup.cpp
@@ -232,3 +232,32 @@
cleanup.setState(stateToRestore);
}
}
+
+llvm::raw_ostream &Lowering::operator<<(llvm::raw_ostream &os,
+ CleanupState state) {
+ switch (state) {
+ case CleanupState::Dormant:
+ return os << "Dormant";
+ case CleanupState::Dead:
+ return os << "Dead";
+ case CleanupState::Active:
+ return os << "Active";
+ case CleanupState::PersistentlyActive:
+ return os << "PersistentlyActive";
+ }
+}
+
+void CleanupManager::dump() const {
+#ifndef NDEBUG
+ auto begin = Stack.stable_begin();
+ auto end = Stack.stable_end();
+ while (begin != end) {
+ auto iter = Stack.find(begin);
+ const Cleanup &stackCleanup = *iter;
+ llvm::errs() << "CLEANUP DEPTH: " << begin.getDepth() << "\n";
+ stackCleanup.dump();
+ begin = Stack.stabilize(++iter);
+ Stack.checkIterator(begin);
+ }
+#endif
+}
diff --git a/lib/SILGen/Cleanup.h b/lib/SILGen/Cleanup.h
index 2cd4684..7b79bbf 100644
--- a/lib/SILGen/Cleanup.h
+++ b/lib/SILGen/Cleanup.h
@@ -14,20 +14,25 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLEANUP_H
-#define CLEANUP_H
+#ifndef SWIFT_SILGEN_CLEANUP_H
+#define SWIFT_SILGEN_CLEANUP_H
#include "swift/Basic/DiverseStack.h"
#include "swift/SIL/SILLocation.h"
+#include "llvm/ADT/SmallVector.h"
namespace swift {
- class SILBasicBlock;
- class SILFunction;
- class SILValue;
-
+
+class SILBasicBlock;
+class SILFunction;
+class SILValue;
+
namespace Lowering {
- class JumpDest;
- class SILGenFunction;
+
+class JumpDest;
+class SILGenFunction;
+class ManagedValue;
+class BorrowedManagedValue;
/// The valid states that a cleanup can be in.
enum class CleanupState {
@@ -47,6 +52,8 @@
PersistentlyActive
};
+llvm::raw_ostream &operator<<(raw_ostream &os, CleanupState state);
+
class LLVM_LIBRARY_VISIBILITY Cleanup {
unsigned allocatedSize;
CleanupState state;
@@ -67,6 +74,7 @@
bool isDead() const { return state == CleanupState::Dead; }
virtual void emit(SILGenFunction &Gen, CleanupLocation L) = 0;
+ virtual void dump() const = 0;
};
/// A cleanup depth is generally used to denote the set of cleanups
@@ -112,7 +120,8 @@
void setCleanupState(Cleanup &cleanup, CleanupState state);
friend class CleanupStateRestorationScope;
-
+ friend class BorrowedManagedValue;
+
public:
CleanupManager(SILGenFunction &Gen)
: Gen(Gen), InnermostScope(Stack.stable_end()) {
@@ -192,6 +201,9 @@
/// True if there are any active cleanups in the scope between the specified
/// cleanup handle and the current top of stack.
bool hasAnyActiveCleanups(CleanupsDepth from);
+
+ /// Dump the output of each cleanup on this stack.
+ void dump() const;
};
/// An RAII object that allows the state of a cleanup to be
diff --git a/lib/SILGen/ManagedValue.cpp b/lib/SILGen/ManagedValue.cpp
index 0a7a88e..560b499 100644
--- a/lib/SILGen/ManagedValue.cpp
+++ b/lib/SILGen/ManagedValue.cpp
@@ -104,3 +104,78 @@
gen.emitSemanticStore(loc, getValue(), address, addrTL,
IsNotInitialization);
}
+
+ManagedValue ManagedValue::borrow(SILGenFunction &gen, SILLocation loc) const {
+ assert(getValue() && "cannot borrow an invalid or in-context value");
+ if (isLValue())
+ return *this;
+ if (getType().isAddress())
+ return ManagedValue::forUnmanaged(getValue());
+ return gen.emitManagedBeginBorrow(loc, getValue());
+}
+
+void BorrowedManagedValue::cleanupImpl() {
+ if (!gen.B.hasValidInsertionPoint()) {
+ handle.reset();
+ return;
+ }
+
+ // We had a trivial or an address value so there isn't anything to
+ // cleanup. Still be sure to unset borrowedValue though.
+ if (!handle.hasValue()) {
+ borrowedValue = ManagedValue();
+ return;
+ }
+
+ assert(borrowedValue && "already cleaned up this object!?");
+
+ CleanupHandle handleValue = handle.getValue();
+ CleanupLocation cleanupLoc = CleanupLocation::get(loc);
+
+ auto iter = gen.Cleanups.Stack.find(handleValue);
+ assert(iter != gen.Cleanups.Stack.end() &&
+ "can't change end of cleanups stack");
+
+ Cleanup &cleanup = *iter;
+ assert(cleanup.isActive() && "Cleanup emitted out of order?!");
+
+ CleanupState newState =
+ (cleanup.getState() == CleanupState::Active ? CleanupState::Dead
+ : CleanupState::Dormant);
+ cleanup.emit(gen, cleanupLoc);
+ gen.Cleanups.setCleanupState(cleanup, newState);
+
+ borrowedValue = ManagedValue();
+ handle.reset();
+}
+
+BorrowedManagedValue::BorrowedManagedValue(SILGenFunction &gen,
+ ManagedValue originalValue,
+ SILLocation loc)
+ : gen(gen), borrowedValue(), handle(), loc(loc) {
+ if (!originalValue)
+ return;
+ auto &lowering = gen.F.getTypeLowering(originalValue.getType());
+ assert(lowering.getLoweredType().getObjectType() ==
+ originalValue.getType().getObjectType());
+
+ if (lowering.isTrivial()) {
+ borrowedValue = ManagedValue::forUnmanaged(originalValue.getValue());
+ return;
+ }
+
+ if (originalValue.getOwnershipKind() == ValueOwnershipKind::Guaranteed) {
+ borrowedValue = ManagedValue::forUnmanaged(originalValue.getValue());
+ return;
+ }
+
+ if (originalValue.getType().isAddress()) {
+ borrowedValue = ManagedValue::forUnmanaged(originalValue.getValue());
+ return;
+ }
+
+ SILValue borrowed = gen.B.createBeginBorrow(loc, originalValue.getValue());
+ if (borrowed->getType().isObject())
+ handle = gen.enterEndBorrowCleanup(originalValue.getValue(), borrowed);
+ borrowedValue = ManagedValue(borrowed, CleanupHandle::invalid());
+}
diff --git a/lib/SILGen/ManagedValue.h b/lib/SILGen/ManagedValue.h
index 5af4e05..b383694 100644
--- a/lib/SILGen/ManagedValue.h
+++ b/lib/SILGen/ManagedValue.h
@@ -31,6 +31,8 @@
namespace Lowering {
+class SILGenFunction;
+
/// ManagedValue - represents a singular SIL value and an optional cleanup.
/// Ownership of the ManagedValue can be "forwarded" to disable its cleanup when
/// the rvalue is consumed. A ManagedValue can also represent an LValue used as
@@ -253,9 +255,10 @@
/// An l-value is borrowed as itself. A +1 r-value is borrowed as a
/// +0 r-value, with the assumption that the original ManagedValue
/// will not be forwarded until the borrowed value is fully used.
- ManagedValue borrow() const {
- assert(getValue() && "cannot borrow an invalid or in-context value");
- return (isLValue() ? *this : ManagedValue::forUnmanaged(getValue()));
+ ManagedValue borrow(SILGenFunction &gen, SILLocation loc) const;
+
+ ManagedValue unmanagedBorrow() const {
+ return isLValue() ? *this : ManagedValue::forUnmanaged(getValue());
}
/// Disable the cleanup for this value.
@@ -358,8 +361,41 @@
return { asUnmanagedValue(), CastConsumptionKind::CopyOnSuccess };
}
};
-
-} // end namespace Lowering
+
+/// An RAII object that allows a user to borrow a value without a specific scope
+/// that ensures that the object is cleaned up before other scoped cleanups
+/// occur. The way cleanup is triggered is by calling:
+///
+/// std::move(value).cleanup();
+class BorrowedManagedValue {
+ SILGenFunction &gen;
+ ManagedValue borrowedValue;
+ Optional<CleanupHandle> handle;
+ SILLocation loc;
+
+public:
+ BorrowedManagedValue(SILGenFunction &gen, ManagedValue originalValue,
+ SILLocation loc);
+ ~BorrowedManagedValue() {
+ assert(!borrowedValue &&
+ "Did not manually cleanup borrowed managed value?!");
+ }
+ BorrowedManagedValue(const BorrowedManagedValue &) = delete;
+ BorrowedManagedValue(BorrowedManagedValue &&) = delete;
+ BorrowedManagedValue &operator=(const BorrowedManagedValue &) = delete;
+ BorrowedManagedValue &operator=(BorrowedManagedValue &&) = delete;
+
+ void cleanup() && { cleanupImpl(); }
+ operator ManagedValue() const { return borrowedValue; }
+
+private:
+ void cleanupImpl();
+};
+
+} // namespace Lowering
+} // namespace swift
+
+namespace swift {
template <typename To> inline bool isa(const Lowering::ManagedValue &M) {
return isa<To>(M.getValue());
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 111cbb3..cc406e5 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -3805,6 +3805,14 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.createDeallocBox(l, box);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeallocateUninitializedBox "
+ << "State:" << getState() << " "
+ << "Box: " << box << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -4423,7 +4431,7 @@
uncurriedArgs.end());
uncurriedArgs[foreignSelf.getSelfIndex()] = selfArg;
}
-
+
// Emit the uncurried call.
// Special case for superclass method calls.
@@ -4922,6 +4930,14 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.emitUninitializedArrayDeallocation(l, Array);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeallocateUninitializedArray "
+ << "State:" << getState() << " "
+ << "Array:" << Array << "\n";
+#endif
+ }
};
} // end anonymous namespace
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 5f8a2c2..94668c8 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -111,10 +111,9 @@
// Call the witness.
SILType resultTy = gen.getLoweredType(objcType);
- SILValue bridgedValue = gen.B.createApply(loc, witnessRef, witnessFnTy,
- resultTy, substitutions,
- swiftValue.borrow()
- .getUnmanagedValue());
+ SILValue bridgedValue =
+ gen.B.createApply(loc, witnessRef, witnessFnTy, resultTy, substitutions,
+ swiftValue.borrow(gen, loc).getValue());
return gen.emitManagedRValueWithCleanup(bridgedValue);
}
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index 573ee54..3b9f0a4 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -120,6 +120,13 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.emitDestroyValueOperation(l, closure);
}
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "CleanupClosureConstant\n"
+ << "State:" << getState() << "\n"
+ << "closure:" << closure << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -214,6 +221,15 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.createEndBorrow(l, borrowed, original);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "EndBorrowCleanup "
+ << "State:" << getState() << "\n"
+ << "original:" << original << "\n"
+ << "borrowed:" << borrowed << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -229,6 +245,14 @@
else
gen.B.emitDestroyValueOperation(l, v);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "ReleaseValueCleanup\n"
+ << "State:" << getState() << "\n"
+ << "Value:" << v << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -242,6 +266,14 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.createDeallocStack(l, Addr);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeallocStackCleanup\n"
+ << "State:" << getState() << "\n"
+ << "Addr:" << Addr << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -255,6 +287,15 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.destroyLocalVariable(l, Var);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DestroyLocalVariable\n"
+ << "State:" << getState() << "\n";
+ // TODO: Make sure we dump var.
+ llvm::errs() << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -268,6 +309,15 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.deallocateUninitializedLocalVariable(l, Var);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeallocateUninitializedLocalVariable\n"
+ << "State:" << getState() << "\n";
+ // TODO: Make sure we dump var.
+ llvm::errs() << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -1196,6 +1246,14 @@
break;
}
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeinitExistentialCleanup\n"
+ << "State:" << getState() << "\n"
+ << "Value:" << existentialAddr << "\n";
+#endif
+ }
};
} // end anonymous namespace
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 33dfcdd..b934489 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -93,6 +93,13 @@
void emit(SILGenFunction &gen, CleanupLocation loc) override {
gen.getWritebackStack()[Depth].performWriteback(gen, /*isFinal*/ false);
}
+
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "LValueWritebackCleanup\n"
+ << "State: " << getState() << "Depth: " << Depth << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -230,20 +237,21 @@
// Otherwise, we need to emit a get and set. Borrow the base for
// the getter.
- ManagedValue getterBase = (base ? base.borrow() : ManagedValue());
+ BorrowedManagedValue borrowedBase(gen, base, loc);
// Clone anything else about the component that we might need in the
// writeback.
auto clonedComponent = clone(gen, loc);
- // Emit a 'get' into a temporary.
- ManagedValue temporary = emitGetIntoTemporary(gen, loc, getterBase,
- std::move(*this));
+ // Emit a 'get' into a temporary and then pop the borrow of base.
+ ManagedValue temporary =
+ emitGetIntoTemporary(gen, loc, borrowedBase, std::move(*this));
+ std::move(borrowedBase).cleanup();
// Push a writeback for the temporary.
pushWriteback(gen, loc, std::move(clonedComponent), base,
MaterializedLValue(temporary));
- return temporary.borrow();
+ return temporary.unmanagedBorrow();
}
void LogicalPathComponent::writeback(SILGenFunction &gen, SILLocation loc,
@@ -865,7 +873,7 @@
// If the base is a +1 r-value, just borrow it for materializeForSet.
// prepareAccessorArgs will copy it if necessary.
- ManagedValue borrowedBase = (base ? base.borrow() : ManagedValue());
+ BorrowedManagedValue borrowedBase(gen, base, loc);
// Clone the component without cloning the indices. We don't actually
// consume them in writeback().
@@ -912,6 +920,11 @@
gen.B.createMarkDependence(loc, temporary, base.getValue()));
}
+ // Now that we have emitted the materializeForSet and created a dependence
+ // on the base from the temporary value, we can end the shared borrow of
+ // the base scope if we performed one.
+ std::move(borrowedBase).cleanup();
+
// TODO: maybe needsWriteback should be a thin function pointer
// to which we pass the base? That would let us use direct
// access for stored properties with didSet.
@@ -1714,8 +1727,10 @@
assert(!entry.HasBeenConsumed && "opaque value already consumed");
entry.HasBeenConsumed = true;
+ RegularLocation loc(e);
LValue lv;
- lv.add<ValueComponent>(entry.Value.borrow(), getValueTypeData(gen, e));
+ lv.add<ValueComponent>(entry.Value.borrow(gen, loc),
+ getValueTypeData(gen, e));
return lv;
}
diff --git a/lib/SILGen/SILGenMaterializeForSet.cpp b/lib/SILGen/SILGenMaterializeForSet.cpp
index 6fa6a18..b18277e 100644
--- a/lib/SILGen/SILGenMaterializeForSet.cpp
+++ b/lib/SILGen/SILGenMaterializeForSet.cpp
@@ -746,6 +746,12 @@
void emit(SILGenFunction &gen, CleanupLocation loc) override {
gen.B.createDeallocValueBuffer(loc, ValueType, Buffer);
}
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeallocateValueBuffer\n"
+ << "State: " << getState() << "Buffer: " << Buffer << "\n";
+#endif
+ }
};
} // end anonymous namespace
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index e7ad809..017240d 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -64,6 +64,12 @@
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.emitDestroyValueOperation(l, box);
}
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeallocateValueBuffer\n"
+ << "State: " << getState() << "box: " << box << "\n";
+#endif
+ }
};
} // end anonymous namespace
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index dc215c5..63d762d 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -405,6 +405,12 @@
void emit(SILGenFunction &SGF, CleanupLocation l) override {
assert(false && "Sema didn't catch exit out of a defer?");
}
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeferEscapeCheckerCleanup\n"
+ << "State: " << getState() << "\n";
+#endif
+ }
};
} // end anonymous namespace
@@ -425,6 +431,12 @@
if (SGF.B.hasValidInsertionPoint())
SGF.Cleanups.setCleanupState(TheCleanup, CleanupState::Dead);
}
+ void dump() const override {
+#ifndef NDEBUG
+ llvm::errs() << "DeferCleanup\n"
+ << "State: " << getState() << "\n";
+#endif
+ }
};
} // end anonymous namespace
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 6fe33e5..c34fba9 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -1,3 +1,8 @@
+
+if (SWIFT_FORCE_OPTIMIZED_TYPECHECKER)
+ set(EXTRA_TYPECHECKER_FLAGS "FORCE_BUILD_OPTIMIZED")
+endif()
+
add_swift_library(swiftSema STATIC
CSApply.cpp
CSDiag.cpp
@@ -44,5 +49,7 @@
TypeChecker.cpp
LINK_LIBRARIES
swiftParse
- swiftAST)
+ swiftAST
+ ${EXTRA_TYPECHECKER_FLAGS}
+)
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 8a6a59a..10f4fbf 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -265,17 +265,17 @@
}
bool ConstraintSystem::isTypeReference(Expr *E) {
- return E->isTypeReference([&](const Expr &E) -> Type { return getType(&E); });
+ return E->isTypeReference([&](const Expr *E) -> Type { return getType(E); });
}
bool ConstraintSystem::isStaticallyDerivedMetatype(Expr *E) {
return E->isStaticallyDerivedMetatype(
- [&](const Expr &E) -> Type { return getType(&E); });
+ [&](const Expr *E) -> Type { return getType(E); });
}
Type ConstraintSystem::getInstanceType(TypeExpr *E) {
- return E->getInstanceType([&](const Expr &E) -> bool { return hasType(&E); },
- [&](const Expr &E) -> Type { return getType(&E); });
+ return E->getInstanceType([&](const Expr *E) -> bool { return hasType(E); },
+ [&](const Expr *E) -> Type { return getType(E); });
}
namespace {
@@ -968,6 +968,7 @@
apply->setImplicit();
}
}
+
return finishApply(apply, openedType, locator);
}
@@ -1280,6 +1281,10 @@
if (!index)
return nullptr;
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
// Form the subscript expression.
// Handle dynamic lookup.
@@ -1293,7 +1298,7 @@
// TODO: diagnose if semantics != AccessSemantics::Ordinary?
auto subscriptExpr = DynamicSubscriptExpr::create(tc.Context, base,
index, subscript,
- isImplicit);
+ isImplicit, getType);
cs.setType(subscriptExpr, resultTy);
Expr *result = subscriptExpr;
closeExistential(result, locator);
@@ -1323,12 +1328,10 @@
return nullptr;
// Form the generic subscript expression.
- auto subscriptExpr
- = SubscriptExpr::create(tc.Context, base, index,
- ConcreteDeclRef(tc.Context, subscript,
- substitutions),
- isImplicit,
- semantics);
+ auto subscriptExpr = SubscriptExpr::create(
+ tc.Context, base, index,
+ ConcreteDeclRef(tc.Context, subscript, substitutions), isImplicit,
+ semantics, getType);
cs.setType(subscriptExpr, resultTy);
subscriptExpr->setIsSuper(isSuper);
@@ -1349,9 +1352,8 @@
return nullptr;
// Form a normal subscript.
- auto *subscriptExpr
- = SubscriptExpr::create(tc.Context, base, index, subscript,
- isImplicit, semantics);
+ auto *subscriptExpr = SubscriptExpr::create(
+ tc.Context, base, index, subscript, isImplicit, semantics, getType);
cs.setType(subscriptExpr, resultTy);
subscriptExpr->setIsSuper(isSuper);
Expr *result = subscriptExpr;
@@ -1418,10 +1420,17 @@
ConcreteDeclRef fnDeclRef(fn);
auto fnRef = new (tc.Context) DeclRefExpr(fnDeclRef, DeclNameLoc(loc),
/*Implicit=*/true);
- fnRef->setType(fn->getInterfaceType());
+ cs.setType(fnRef, fn->getInterfaceType());
fnRef->setFunctionRefKind(FunctionRefKind::SingleApply);
- cs.setExprTypes(value);
- Expr *call = CallExpr::createImplicit(tc.Context, fnRef, { value }, { });
+
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
+ Expr *call = CallExpr::createImplicit(tc.Context, fnRef, { value }, { },
+ getType);
+ cs.cacheSubExprTypes(call);
+ cs.setSubExprTypes(call);
if (tc.typeCheckExpressionShallow(call, dc))
return nullptr;
@@ -1506,11 +1515,15 @@
AccessSemantics::Ordinary,
bridgeFnTy);
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
fnRef->setFunctionRefKind(FunctionRefKind::SingleApply);
Expr *call = CallExpr::createImplicit(tc.Context, fnRef, valueParen,
- { Identifier() });
+ { Identifier() }, getType);
cs.setType(call, bridgeTy);
- cs.cacheSubExprTypes(call);
+ cs.cacheExprTypes(call);
return call;
}
@@ -1605,19 +1618,23 @@
// Form the arguments.
Expr *args[2] = {
object,
- cs.cacheType(new (tc.Context) DotSelfExpr(
- cs.cacheType(
+ new (tc.Context) DotSelfExpr(
TypeExpr::createImplicitHack(object->getLoc(),
valueType,
- tc.Context)),
- object->getLoc(), object->getLoc(),
- MetatypeType::get(valueType)))
+ tc.Context),
+ object->getLoc(), object->getLoc(),
+ MetatypeType::get(valueType))
};
args[1]->setImplicit();
// Form the call and type-check it.
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
Expr *call = CallExpr::createImplicit(tc.Context, fnRef, args,
- { Identifier(), Identifier() });
+ { Identifier(), Identifier() },
+ getType);
cs.cacheSubExprTypes(call);
cs.setSubExprTypes(call);
@@ -2064,9 +2081,9 @@
// Build a reference to the init(stringInterpolation:) initializer.
// FIXME: This location info is bogus.
- auto *typeRef =
- cs.cacheType(TypeExpr::createImplicitHack(expr->getStartLoc(),
- type, tc.Context));
+ auto *typeRef = TypeExpr::createImplicitHack(expr->getStartLoc(), type,
+ tc.Context);
+
Expr *memberRef =
new (tc.Context) MemberRefExpr(typeRef,
expr->getStartLoc(),
@@ -2084,17 +2101,23 @@
SmallVector<Expr *, 4> segments;
SmallVector<Identifier, 4> names;
ConstraintLocatorBuilder locatorBuilder(cs.getConstraintLocator(expr));
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
for (auto segment : expr->getSegments()) {
ApplyExpr *apply =
CallExpr::createImplicit(
tc.Context, typeRef,
{ segment },
- { tc.Context.Id_stringInterpolationSegment });
- cs.cacheType(apply->getArg());
+ { tc.Context.Id_stringInterpolationSegment }, getType);
+ cs.cacheSubExprTypes(apply);
Expr *convertedSegment = apply;
+ cs.setSubExprTypes(convertedSegment);
if (tc.typeCheckExpressionShallow(convertedSegment, cs.DC))
continue;
+ cs.cacheExprTypes(convertedSegment);
segments.push_back(convertedSegment);
@@ -2111,8 +2134,8 @@
// Call the init(stringInterpolation:) initializer with the arguments.
ApplyExpr *apply = CallExpr::createImplicit(tc.Context, memberRef,
- segments, names);
- cs.cacheSubExprTypes(apply);
+ segments, names, getType);
+ cs.cacheExprTypes(apply);
expr->setSemanticExpr(finishApply(apply, openedType, locatorBuilder));
return expr;
}
@@ -2164,10 +2187,9 @@
ConformanceCheckFlags::InExpression);
assert(conformance && "object literal type conforms to protocol");
- Expr *base =
- cs.cacheType(TypeExpr::createImplicitHack(expr->getLoc(),
- conformingType,
- ctx));
+ Expr *base = TypeExpr::createImplicitHack(expr->getLoc(), conformingType,
+ ctx);
+ cs.cacheExprTypes(base);
SmallVector<Expr *, 4> args;
if (!isa<TupleExpr>(expr->getArg()))
@@ -2327,9 +2349,9 @@
// The base expression is simply the metatype of the base type.
// FIXME: This location info is bogus.
- auto base =
- cs.cacheType(TypeExpr::createImplicitHack(expr->getDotLoc(),
- baseTy, tc.Context));
+ auto base = TypeExpr::createImplicitHack(expr->getDotLoc(), baseTy,
+ tc.Context);
+ cs.cacheExprTypes(base);
// Build the member reference.
bool isDynamic
@@ -2348,13 +2370,16 @@
if (!result)
return nullptr;
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
// If there was an argument, apply it.
if (auto arg = expr->getArgument()) {
- ApplyExpr *apply = CallExpr::create(tc.Context, result, arg,
- expr->getArgumentLabels(),
- expr->getArgumentLabelLocs(),
- expr->hasTrailingClosure(),
- /*implicit=*/false);
+ ApplyExpr *apply = CallExpr::create(
+ tc.Context, result, arg, expr->getArgumentLabels(),
+ expr->getArgumentLabelLocs(), expr->hasTrailingClosure(),
+ /*implicit=*/false, Type(), getType);
result = finishApply(apply, Type(), cs.getConstraintLocator(expr));
}
@@ -2493,9 +2518,9 @@
baseMetaTy->getInstanceType());
// FIXME: We're dropping side effects in the base here!
- base =
- cs.cacheType(TypeExpr::createImplicitHack(base->getLoc(), classTy,
- tc.Context));
+ base = TypeExpr::createImplicitHack(base->getLoc(), classTy,
+ tc.Context);
+ cs.cacheExprTypes(base);
} else {
// Bridge the base to its corresponding Objective-C object.
base = bridgeToObjectiveC(base);
@@ -2628,9 +2653,10 @@
// be nicer to re-use them.
// FIXME: This location info is bogus.
- Expr *typeRef =
- cs.cacheType(TypeExpr::createImplicitHack(expr->getLoc(),
- arrayTy, tc.Context));
+ Expr *typeRef = TypeExpr::createImplicitHack(expr->getLoc(), arrayTy,
+ tc.Context);
+ cs.cacheExprTypes(typeRef);
+
DeclName name(tc.Context, tc.Context.Id_init,
{ tc.Context.Id_arrayLiteral });
@@ -2706,9 +2732,9 @@
// It would be nicer to re-use them.
// FIXME: Cache the name.
// FIXME: This location info is bogus.
- Expr *typeRef =
- cs.cacheType(TypeExpr::createImplicitHack(expr->getLoc(),
- dictionaryTy, tc.Context));
+ Expr *typeRef = TypeExpr::createImplicitHack(expr->getLoc(), dictionaryTy,
+ tc.Context);
+ cs.cacheExprTypes(typeRef);
DeclName name(tc.Context, tc.Context.Id_init,
{ tc.Context.Id_dictionaryLiteral });
@@ -3276,13 +3302,13 @@
// Warn about NSNumber and NSValue bridging coercions we accepted in
// Swift 3 but which can fail at runtime.
if (tc.Context.LangOpts.isSwiftVersion3()
- && tc.typeCheckCheckedCast(sub->getType(), toInstanceType,
+ && tc.typeCheckCheckedCast(cs.getType(sub), toInstanceType,
CheckedCastContextKind::None,
dc, SourceLoc(), sub, SourceRange())
== CheckedCastKind::Swift3BridgingDowncast) {
tc.diagnose(expr->getLoc(),
diag::missing_forced_downcast_swift3_compat_warning,
- sub->getType(), toInstanceType)
+ cs.getType(sub), toInstanceType)
.fixItReplace(expr->getAsLoc(), "as!");
}
@@ -3547,8 +3573,13 @@
StringRef msg = "attempt to evaluate editor placeholder";
Expr *argExpr = new (ctx) StringLiteralExpr(msg, E->getLoc(),
/*implicit*/true);
+
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
Expr *callExpr = CallExpr::createImplicit(ctx, fnRef, { argExpr },
- { Identifier() });
+ { Identifier() }, getType);
bool invalid = tc.typeCheckExpression(callExpr, cs.DC,
TypeLoc::withoutLoc(valueType),
@@ -3867,6 +3898,9 @@
.fixItInsert(cast->getStartLoc(), "(")
.fixItInsertAfter(cast->getEndLoc(), ")");
}
+
+ // Set the final types on the expression.
+ cs.setExprTypes(result);
}
/// Diagnose an optional injection that is probably not what the
@@ -5927,14 +5961,18 @@
Diag<> brokenBuiltinProtocolDiag) {
auto &tc = cs.getTypeChecker();
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
// If coercing a literal to an unresolved type, we don't try to look up the
// witness members, just do it.
if (type->is<UnresolvedType>()) {
// Instead of updating the literal expr in place, allocate a new node. This
// avoids issues where Builtin types end up on expr nodes and pollute
// diagnostics.
- literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context);
-
+ literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context, getType);
+
// The literal expression has this type.
cs.setType(literal, type);
return literal;
@@ -5968,7 +6006,7 @@
// Instead of updating the literal expr in place, allocate a new node. This
// avoids issues where Builtin types end up on expr nodes and pollute
// diagnostics.
- literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context);
+ literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context, getType);
// The literal expression has this type.
cs.setType(literal, argType);
@@ -6066,14 +6104,18 @@
Diag<> brokenBuiltinProtocolDiag) {
auto &tc = cs.getTypeChecker();
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
// If coercing a literal to an unresolved type, we don't try to look up the
// witness members, just do it.
if (type->is<UnresolvedType>()) {
// Instead of updating the literal expr in place, allocate a new node. This
// avoids issues where Builtin types end up on expr nodes and pollute
// diagnostics.
- literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context);
-
+ literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context, getType);
+
// The literal expression has this type.
cs.setType(literal, type);
return literal;
@@ -6097,9 +6139,9 @@
// Form a reference to the builtin conversion function.
// FIXME: Bogus location info.
- Expr *base =
- cs.cacheType(TypeExpr::createImplicitHack(literal->getLoc(), type,
- tc.Context));
+ Expr *base = TypeExpr::createImplicitHack(literal->getLoc(), type,
+ tc.Context);
+
Expr *unresolvedDot = new (tc.Context) UnresolvedDotExpr(
base, SourceLoc(),
witness->getFullName(),
@@ -6162,9 +6204,9 @@
// Form a reference to the conversion function.
// FIXME: Bogus location info.
- Expr *base =
- cs.cacheType(TypeExpr::createImplicitHack(literal->getLoc(), type,
- tc.Context));
+ Expr *base = TypeExpr::createImplicitHack(literal->getLoc(), type,
+ tc.Context);
+
Expr *unresolvedDot = new (tc.Context) UnresolvedDotExpr(
base, SourceLoc(),
witness->getFullName(),
@@ -6297,11 +6339,14 @@
auto escapable = new (tc.Context)
OpaqueValueExpr(apply->getFn()->getLoc(), Type());
cs.setType(escapable, escapableType);
-
- auto callSubExpr = CallExpr::create(tc.Context, body, escapable,
- {}, {},
+
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
+ auto callSubExpr = CallExpr::create(tc.Context, body, escapable, {}, {},
/*trailing closure*/ false,
- /*implicit*/ true);
+ /*implicit*/ true, Type(), getType);
cs.setType(callSubExpr, resultType);
auto replacement = new (tc.Context)
@@ -7149,6 +7194,10 @@
FunctionRefKind::DoubleApply,
dotLocator);
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
// Form the call argument.
// FIXME: Standardize all callers to always provide all argument names,
// rather than hack around this.
@@ -7157,9 +7206,9 @@
if (arguments.size() == 1 &&
(isVariadicWitness(witness) ||
argumentNamesMatch(arguments[0]->getType(), argLabels))) {
- call = CallExpr::create(Context, unresolvedDot, arguments[0], { },
- { }, /*hasTrailingClosure=*/false,
- /*implicit=*/true);
+ call = CallExpr::create(Context, unresolvedDot, arguments[0], {}, {},
+ /*hasTrailingClosure=*/false,
+ /*implicit=*/true, Type(), getType);
} else {
// The tuple should have the source range enclosing its arguments unless
// they are invalid or there are no arguments.
@@ -7174,12 +7223,10 @@
}
}
- call = CallExpr::create(Context, unresolvedDot,
- TupleStartLoc,
- arguments, argLabels, { },
- TupleEndLoc,
+ call = CallExpr::create(Context, unresolvedDot, TupleStartLoc, arguments,
+ argLabels, {}, TupleEndLoc,
/*trailingClosure=*/nullptr,
- /*implicit=*/true);
+ /*implicit=*/true, getType);
}
// Add the conversion from the argument to the function parameter type.
@@ -7276,7 +7323,11 @@
(void)failed;
// Call the builtin method.
- expr = CallExpr::createImplicit(ctx, memberRef, { }, { });
+ auto getType = [&](const Expr *E) -> Type {
+ return cs.getType(E);
+ };
+
+ expr = CallExpr::createImplicit(ctx, memberRef, { }, { }, getType);
cs.cacheSubExprTypes(expr);
cs.setSubExprTypes(expr);
failed = tc.typeCheckExpressionShallow(expr, cs.DC);
diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt
index e5d530b..a44e642 100644
--- a/stdlib/public/runtime/CMakeLists.txt
+++ b/stdlib/public/runtime/CMakeLists.txt
@@ -102,7 +102,9 @@
"${SWIFT_SOURCE_DIR}/utils/${lowercase}/static-executable-args.lnk"
"${SWIFTSTATICLIB_DIR}/${linkfile}"
OUTPUT
- "${SWIFTSTATICLIB_DIR}/${linkfile}")
+ "${SWIFTSTATICLIB_DIR}/${linkfile}"
+ DEPENDS
+ "${SWIFT_SOURCE_DIR}/utils/${lowercase}/static-executable-args.lnk")
list(APPEND static_binary_lnk_file_list ${swift_static_binary_${sdk}_args})
swift_install_in_component(stdlib
@@ -161,16 +163,10 @@
set(section_magic_begin_obj "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/section_magic_begin-${arch_suffix}.dir/swift_sections.S${CMAKE_C_OUTPUT_EXTENSION}")
set(section_magic_end_obj "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/section_magic_end-${arch_suffix}.dir/swift_sections.S${CMAKE_C_OUTPUT_EXTENSION}")
- if(SWIFT_ENABLE_GOLD_LINKER)
- set(LD_COMMAND "gold")
- else()
- set(LD_COMMAND "ld")
- endif()
-
add_custom_command_target(section_magic_${arch_suffix}_begin_object
COMMAND
# Merge ImageInspectionInit.o + swift_sections.S(BEGIN) => swift_begin.o
- ${LD_COMMAND} -r -o "${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o"
+ ${CMAKE_LINKER} -r -o "${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o"
"${section_magic_begin_obj}" "${section_magic_loader_obj}"
OUTPUT
"${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o"
diff --git a/test/SILGen/accessors.swift b/test/SILGen/accessors.swift
index ea80410..7d4e39a 100644
--- a/test/SILGen/accessors.swift
+++ b/test/SILGen/accessors.swift
@@ -26,7 +26,7 @@
ref.array[index0()] = ref.array[index1()]
}
// CHECK: sil hidden @_T09accessors5test0yAA1ACF : $@convention(thin) (@owned A) -> () {
-// CHECK: bb0(%0 : $A):
+// CHECK: bb0([[ARG:%.*]] : $A):
// CHECK-NEXT: debug_value
// Formal evaluation of LHS.
// CHECK-NEXT: // function_ref accessors.index0 () -> Swift.Int
@@ -38,8 +38,8 @@
// CHECK-NEXT: [[INDEX1:%.*]] = apply [[T0]]()
// Formal access to RHS.
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $OrdinarySub
-// CHECK-NEXT: [[T0:%.*]] = class_method %0 : $A, #A.array!getter.1
-// CHECK-NEXT: [[T1:%.*]] = apply [[T0]](%0)
+// CHECK-NEXT: [[T0:%.*]] = class_method [[ARG]] : $A, #A.array!getter.1
+// CHECK-NEXT: [[T1:%.*]] = apply [[T0]]([[ARG]])
// CHECK-NEXT: store [[T1]] to [init] [[TEMP]]
// CHECK-NEXT: [[T0:%.*]] = load [take] [[TEMP]]
// CHECK-NEXT: // function_ref accessors.OrdinarySub.subscript.getter : (Swift.Int) -> Swift.Int
@@ -49,17 +49,20 @@
// Formal access to LHS.
// CHECK-NEXT: [[STORAGE:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer
// CHECK-NEXT: [[BUFFER:%.*]] = alloc_stack $OrdinarySub
+// CHECK-NEXT: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK-NEXT: [[T0:%.*]] = address_to_pointer [[BUFFER]]
-// CHECK-NEXT: [[T1:%.*]] = class_method %0 : $A, #A.array!materializeForSet.1
-// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]], %0)
+// CHECK-NEXT: [[T1:%.*]] = class_method [[BORROWED_ARG]] : $A, #A.array!materializeForSet.1
+// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]], [[BORROWED_ARG]])
// CHECK-NEXT: [[T3:%.*]] = tuple_extract [[T2]] {{.*}}, 0
// CHECK-NEXT: [[OPT_CALLBACK:%.*]] = tuple_extract [[T2]] {{.*}}, 1
// CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]]
// CHECK-NEXT: [[ADDR:%.*]] = mark_dependence [[T4]] : $*OrdinarySub on %0 : $A
+// CHECK-NEXT: end_borrow [[BORROWED_ARG]] from [[ARG]]
// CHECK-NEXT: // function_ref accessors.OrdinarySub.subscript.setter : (Swift.Int) -> Swift.Int
// CHECK-NEXT: [[T0:%.*]] = function_ref @_T09accessors11OrdinarySubV9subscriptSiSicfs
// CHECK-NEXT: apply [[T0]]([[VALUE]], [[INDEX0]], [[ADDR]])
// CHECK-NEXT: switch_enum [[OPT_CALLBACK]] : $Optional<Builtin.RawPointer>, case #Optional.some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.none!enumelt: [[CONT:bb[0-9]+]]
+
// CHECK: [[WRITEBACK]]([[CALLBACK_ADDR:%.*]] : $Builtin.RawPointer):
// CHECK-NEXT: [[CALLBACK:%.*]] = pointer_to_thin_function [[CALLBACK_ADDR]] : $Builtin.RawPointer to $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout A, @thick A.Type) -> ()
// CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $A
@@ -69,6 +72,7 @@
// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE]], [[TEMP2]], [[T0]])
// CHECK-NEXT: dealloc_stack [[TEMP2]]
// CHECK-NEXT: br [[CONT]]
+
// CHECK: [[CONT]]:
// CHECK-NEXT: dealloc_stack [[BUFFER]]
// CHECK-NEXT: dealloc_stack [[STORAGE]]
@@ -92,7 +96,7 @@
ref.array[index0()] = ref.array[index1()]
}
// CHECK-LABEL: sil hidden @_T09accessors5test1yAA1BCF : $@convention(thin) (@owned B) -> () {
-// CHECK: bb0(%0 : $B):
+// CHECK: bb0([[ARG:%.*]] : $B):
// CHECK-NEXT: debug_value
// Formal evaluation of LHS.
// CHECK-NEXT: // function_ref accessors.index0 () -> Swift.Int
@@ -105,17 +109,20 @@
// Formal access to RHS.
// CHECK-NEXT: [[STORAGE:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer
// CHECK-NEXT: [[BUFFER:%.*]] = alloc_stack $MutatingSub
+// CHECK-NEXT: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK-NEXT: [[T0:%.*]] = address_to_pointer [[BUFFER]]
-// CHECK-NEXT: [[T1:%.*]] = class_method %0 : $B, #B.array!materializeForSet.1
-// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]], %0)
+// CHECK-NEXT: [[T1:%.*]] = class_method [[BORROWED_ARG]] : $B, #B.array!materializeForSet.1
+// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]], [[BORROWED_ARG]])
// CHECK-NEXT: [[T3:%.*]] = tuple_extract [[T2]] {{.*}}, 0
// CHECK-NEXT: [[OPT_CALLBACK:%.*]] = tuple_extract [[T2]] {{.*}}, 1
// CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]]
// CHECK-NEXT: [[ADDR:%.*]] = mark_dependence [[T4]] : $*MutatingSub on %0 : $B
+// CHECK-NEXT: end_borrow [[BORROWED_ARG]] from [[ARG]]
// CHECK-NEXT: // function_ref accessors.MutatingSub.subscript.getter : (Swift.Int) -> Swift.Int
// CHECK-NEXT: [[T0:%.*]] = function_ref @_T09accessors11MutatingSubV9subscriptSiSicfg : $@convention(method) (Int, @inout MutatingSub) -> Int
// CHECK-NEXT: [[VALUE:%.*]] = apply [[T0]]([[INDEX1]], [[ADDR]])
// CHECK-NEXT: switch_enum [[OPT_CALLBACK]] : $Optional<Builtin.RawPointer>, case #Optional.some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.none!enumelt: [[CONT:bb[0-9]+]]
+//
// CHECK: [[WRITEBACK]]([[CALLBACK_ADDR:%.*]] : $Builtin.RawPointer):
// CHECK-NEXT: [[CALLBACK:%.*]] = pointer_to_thin_function [[CALLBACK_ADDR]] : $Builtin.RawPointer to $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout B, @thick B.Type) -> ()
// CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $B
@@ -125,21 +132,25 @@
// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE]], [[TEMP2]], [[T0]])
// CHECK-NEXT: dealloc_stack [[TEMP2]]
// CHECK-NEXT: br [[CONT]]
+//
// CHECK: [[CONT]]:
// Formal access to LHS.
// CHECK-NEXT: [[STORAGE2:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer
// CHECK-NEXT: [[BUFFER2:%.*]] = alloc_stack $MutatingSub
+// CHECK-NEXT: [[BORROWED_ARG_2:%.*]] = begin_borrow [[ARG]]
// CHECK-NEXT: [[T0:%.*]] = address_to_pointer [[BUFFER2]]
-// CHECK-NEXT: [[T1:%.*]] = class_method %0 : $B, #B.array!materializeForSet.1
-// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE2]], %0)
+// CHECK-NEXT: [[T1:%.*]] = class_method [[BORROWED_ARG_2]] : $B, #B.array!materializeForSet.1
+// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE2]], [[BORROWED_ARG_2]])
// CHECK-NEXT: [[T3:%.*]] = tuple_extract [[T2]] {{.*}}, 0
// CHECK-NEXT: [[OPT_CALLBACK:%.*]] = tuple_extract [[T2]] {{.*}}, 1
// CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]]
// CHECK-NEXT: [[ADDR:%.*]] = mark_dependence [[T4]] : $*MutatingSub on %0 : $B
+// CHECK-NEXT: end_borrow [[BORROWED_ARG_2]] from [[ARG]]
// CHECK-NEXT: // function_ref accessors.MutatingSub.subscript.setter : (Swift.Int) -> Swift.Int
// CHECK-NEXT: [[T0:%.*]] = function_ref @_T09accessors11MutatingSubV9subscriptSiSicfs : $@convention(method) (Int, Int, @inout MutatingSub) -> ()
// CHECK-NEXT: apply [[T0]]([[VALUE]], [[INDEX0]], [[ADDR]])
// CHECK-NEXT: switch_enum [[OPT_CALLBACK]] : $Optional<Builtin.RawPointer>, case #Optional.some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.none!enumelt: [[CONT:bb[0-9]+]]
+//
// CHECK: [[WRITEBACK]]([[CALLBACK_ADDR:%.*]] : $Builtin.RawPointer):
// CHECK-NEXT: [[CALLBACK:%.*]] = pointer_to_thin_function [[CALLBACK_ADDR]] : $Builtin.RawPointer to $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout B, @thick B.Type) -> ()
// CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $B
@@ -149,6 +160,7 @@
// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE2]], [[TEMP2]], [[T0]])
// CHECK-NEXT: dealloc_stack [[TEMP2]]
// CHECK-NEXT: br [[CONT]]
+//
// CHECK: [[CONT]]:
// CHECK-NEXT: dealloc_stack [[BUFFER2]]
// CHECK-NEXT: dealloc_stack [[STORAGE2]]
diff --git a/test/SILGen/foreign_errors.swift b/test/SILGen/foreign_errors.swift
index 7dee4f8..2ad9a68 100644
--- a/test/SILGen/foreign_errors.swift
+++ b/test/SILGen/foreign_errors.swift
@@ -91,17 +91,25 @@
@objc func badDescription() throws -> String {
throw NSError(domain: "", code: 1, userInfo: [:])
}
-// CHECK-LABEL: sil hidden [thunk] @_TToFE14foreign_errorsCSo8NSObject14badDescription{{.*}} : $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, NSObject) -> @autoreleased Optional<NSString>
+// CHECK-LABEL: sil hidden [thunk] @_TToFE14foreign_errorsCSo8NSObject14badDescription{{.*}} : $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, NSObject) -> @autoreleased Optional<NSString> {
+// CHECK: bb0([[UNOWNED_ARG0:%.*]] : $Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, [[UNOWNED_ARG1:%.*]] : $NSObject):
+// CHECK: [[ARG1:%.*]] = copy_value [[UNOWNED_ARG1]]
// CHECK: [[T0:%.*]] = function_ref @_TFE14foreign_errorsCSo8NSObject14badDescription{{.*}} : $@convention(method) (@guaranteed NSObject) -> (@owned String, @error Error)
-// CHECK: try_apply [[T0]](
-// CHECK: bb1([[RESULT:%.*]] : $String):
+// CHECK: try_apply [[T0]]([[ARG1]]) : $@convention(method) (@guaranteed NSObject) -> (@owned String, @error Error), normal [[NORMAL_BB:bb[0-9][0-9]*]], error [[ERROR_BB:bb[0-9][0-9]*]]
+//
+// CHECK: [[NORMAL_BB]]([[RESULT:%.*]] : $String):
// CHECK: [[T0:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveCfT_CSo8NSString : $@convention(method) (@guaranteed String) -> @owned NSString
-// CHECK: [[T1:%.*]] = apply [[T0]]([[RESULT]])
+// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
+// CHECK: [[T1:%.*]] = apply [[T0]]([[BORROWED_RESULT]])
// CHECK: [[T2:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt.1, [[T1]] : $NSString
+// CHECK: end_borrow [[BORROWED_RESULT]] from [[RESULT]]
+// CHECK: destroy_value [[RESULT]]
// CHECK: br bb6([[T2]] : $Optional<NSString>)
-// CHECK: bb2([[ERR:%.*]] : $Error):
-// CHECK: switch_enum %0 : $Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, case #Optional.some!enumelt.1: bb3, case #Optional.none!enumelt: bb4
-// CHECK: bb3([[UNWRAPPED_OUT:%.+]] : $AutoreleasingUnsafeMutablePointer<Optional<NSError>>):
+//
+// CHECK: [[ERROR_BB]]([[ERR:%.*]] : $Error):
+// CHECK: switch_enum [[UNOWNED_ARG0]] : $Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9][0-9]*]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9][0-9]*]]
+//
+// CHECK: [[SOME_BB]]([[UNWRAPPED_OUT:%.+]] : $AutoreleasingUnsafeMutablePointer<Optional<NSError>>):
// CHECK: [[T0:%.*]] = function_ref @swift_convertErrorToNSError : $@convention(thin) (@owned Error) -> @owned NSError
// CHECK: [[T1:%.*]] = apply [[T0]]([[ERR]])
// CHECK: [[OBJCERR:%.*]] = enum $Optional<NSError>, #Optional.some!enumelt.1, [[T1]] : $NSError
@@ -111,9 +119,11 @@
// CHECK: apply [[SETTER]]<Optional<NSError>>([[TEMP]], [[UNWRAPPED_OUT]])
// CHECK: dealloc_stack [[TEMP]]
// CHECK: br bb5
-// CHECK: bb4:
+//
+// CHECK: [[NONE_BB]]:
// CHECK: destroy_value [[ERR]] : $Error
// CHECK: br bb5
+//
// CHECK: bb5:
// CHECK: [[T0:%.*]] = enum $Optional<NSString>, #Optional.none!enumelt
// CHECK: br bb6([[T0]] : $Optional<NSString>)
diff --git a/test/SILGen/lifetime.swift b/test/SILGen/lifetime.swift
index 94e7d42..1792014 100644
--- a/test/SILGen/lifetime.swift
+++ b/test/SILGen/lifetime.swift
@@ -362,9 +362,10 @@
// CHECK: [[R2:%[0-9]+]] = load [copy] [[PR]]
// CHECK: [[STORAGE:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer
// CHECK: [[ALEPH_PROP_TEMP:%[0-9]+]] = alloc_stack $Aleph
+ // CHECK: [[BORROWED_R2:%.*]] = begin_borrow [[R2]]
// CHECK: [[T0:%.*]] = address_to_pointer [[ALEPH_PROP_TEMP]]
- // CHECK: [[MATERIALIZE_METHOD:%[0-9]+]] = class_method {{.*}} : $RefWithProp, #RefWithProp.aleph_prop!materializeForSet.1 :
- // CHECK: [[MATERIALIZE:%.*]] = apply [[MATERIALIZE_METHOD]]([[T0]], [[STORAGE]], [[R2]])
+ // CHECK: [[MATERIALIZE_METHOD:%[0-9]+]] = class_method [[BORROWED_R2]] : $RefWithProp, #RefWithProp.aleph_prop!materializeForSet.1 :
+ // CHECK: [[MATERIALIZE:%.*]] = apply [[MATERIALIZE_METHOD]]([[T0]], [[STORAGE]], [[BORROWED_R2]])
// CHECK: [[PTR:%.*]] = tuple_extract [[MATERIALIZE]] : {{.*}}, 0
// CHECK: [[OPTCALLBACK:%.*]] = tuple_extract [[MATERIALIZE]] : {{.*}}, 1
// CHECK: [[ADDR:%.*]] = pointer_to_address [[PTR]]
diff --git a/test/SILGen/objc_bridging.swift b/test/SILGen/objc_bridging.swift
index df2b9c8..79703a5 100644
--- a/test/SILGen/objc_bridging.swift
+++ b/test/SILGen/objc_bridging.swift
@@ -226,7 +226,10 @@
// CHECK: [[PROP_COPY:%.*]] = apply [[PROPIMPL]]([[THIS_COPY]]) : $@convention(method) (@guaranteed Bas) -> @owned String
// CHECK: destroy_value [[THIS_COPY]]
// CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveCfT_CSo8NSString
- // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[PROP_COPY]])
+ // CHECK: [[BORROWED_PROP_COPY:%.*]] = begin_borrow [[PROP_COPY]]
+ // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[BORROWED_PROP_COPY]])
+ // CHECK: end_borrow [[BORROWED_PROP_COPY]] from [[PROP_COPY]]
+ // CHECK: destroy_value [[PROP_COPY]]
// CHECK: return [[NSSTR]]
// CHECK: }
@@ -267,7 +270,9 @@
// CHECK: [[STR:%.*]] = apply [[GETTER]]([[THIS_COPY]])
// CHECK: destroy_value [[THIS_COPY]]
// CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveCfT_CSo8NSString
- // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[STR]])
+ // CHECK: [[BORROWED_STR:%.*]] = begin_borrow [[STR]]
+ // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[BORROWED_STR]])
+ // CHECK: end_borrow [[BORROWED_STR]] from [[STR]]
// CHECK: destroy_value [[STR]]
// CHECK: return [[NSSTR]]
// CHECK: }
@@ -309,7 +314,9 @@
// CHECK: [[STR:%.*]] = apply [[METHOD]]([[THIS_COPY]])
// CHECK: destroy_value [[THIS_COPY]]
// CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveCfT_CSo8NSString
- // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[STR]])
+ // CHECK: [[BORROWED_STR:%.*]] = begin_borrow [[STR]]
+ // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[BORROWED_STR]])
+ // CHECK: end_borrow [[BORROWED_STR]] from [[STR]]
// CHECK: destroy_value [[STR]]
// CHECK: return [[NSSTR]]
// CHECK: }
@@ -364,7 +371,9 @@
// CHECK: [[ARRAY:%[0-9]+]] = apply [[SWIFT_FN]]([[SELF_COPY]]) : $@convention(method) (@guaranteed Bas) -> @owned Array<AnyObject>
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: [[CONV_FN:%[0-9]+]] = function_ref @_TFE10FoundationSa19_bridgeToObjectiveCfT_CSo7NSArray
- // CHECK: [[NSARRAY:%[0-9]+]] = apply [[CONV_FN]]<AnyObject>([[ARRAY]]) : $@convention(method) <τ_0_0> (@guaranteed Array<τ_0_0>) -> @owned NSArray
+ // CHECK: [[BORROWED_ARRAY:%.*]] = begin_borrow [[ARRAY]]
+ // CHECK: [[NSARRAY:%[0-9]+]] = apply [[CONV_FN]]<AnyObject>([[BORROWED_ARRAY]]) : $@convention(method) <τ_0_0> (@guaranteed Array<τ_0_0>) -> @owned NSArray
+ // CHECK: end_borrow [[BORROWED_ARRAY]] from [[ARRAY]]
// CHECK: destroy_value [[ARRAY]]
// CHECK: return [[NSARRAY]]
func arrayResult() -> [AnyObject] { return [] }
@@ -381,12 +390,14 @@
// CHECK: [[BLOCK_COPY_COPY:%.*]] = copy_value [[BLOCK_COPY]]
// CHECK: [[STRING_COPY:%.*]] = copy_value [[STRING]]
// CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveCfT_CSo8NSString
- // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[STRING_COPY]])
+ // CHECK: [[BORROWED_STRING_COPY:%.*]] = begin_borrow [[STRING_COPY]]
+ // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[BORROWED_STRING_COPY]]) : $@convention(method) (@guaranteed String)
// CHECK: [[RESULT_NSSTR:%.*]] = apply [[BLOCK_COPY_COPY]]([[NSSTR]]) : $@convention(block) (NSString) -> @autoreleased NSString
// CHECK: [[FINAL_BRIDGE:%.*]] = function_ref @_TZFE10FoundationSS36_unconditionallyBridgeFromObjectiveCfGSqCSo8NSString_SS
// CHECK: [[OPTIONAL_NSSTR:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt.1, [[RESULT_NSSTR]]
// CHECK: [[RESULT:%.*]] = apply [[FINAL_BRIDGE]]([[OPTIONAL_NSSTR]], {{.*}}) : $@convention(method) (@owned Optional<NSString>, @thin String.Type) -> @owned String
// CHECK: destroy_value [[NSSTR]]
+ // CHECK: end_borrow [[BORROWED_STRING_COPY]] from [[STRING_COPY]]
// CHECK: destroy_value [[STRING_COPY]]
// CHECK: destroy_value [[BLOCK_COPY_COPY]]
// CHECK: destroy_value [[STRING]]
@@ -483,16 +494,22 @@
// +=
// CHECK: [[PLUS_EQ:%[0-9]+]] = function_ref @_TFsoi2peFTRSdSd_T_
+ // Borrowed home
+ // CHECK: [[BORROWED_HOME:%.*]] = begin_borrow [[HOME]]
+
// Temporary fridge
// CHECK: [[TEMP_FRIDGE:%[0-9]+]] = alloc_stack $Refrigerator
// Get operation
- // CHECK: [[GETTER:%[0-9]+]] = class_method [volatile] [[HOME]] : $APPHouse, #APPHouse.fridge!getter.1.foreign
- // CHECK: [[OBJC_FRIDGE:%[0-9]+]] = apply [[GETTER]]([[HOME]])
+ // CHECK: [[GETTER:%[0-9]+]] = class_method [volatile] [[BORROWED_HOME]] : $APPHouse, #APPHouse.fridge!getter.1.foreign
+ // CHECK: [[OBJC_FRIDGE:%[0-9]+]] = apply [[GETTER]]([[BORROWED_HOME]])
// CHECK: [[BRIDGE_FROM_FN:%[0-9]+]] = function_ref @_TZFV10Appliances12Refrigerator36_unconditionallyBridgeFromObjectiveC
// CHECK: [[REFRIGERATOR_META:%[0-9]+]] = metatype $@thin Refrigerator.Type
// CHECK: [[FRIDGE:%[0-9]+]] = apply [[BRIDGE_FROM_FN]]([[OBJC_FRIDGE]], [[REFRIGERATOR_META]])
+ // End the borrow from the get operation.
+ // CHECK: end_borrow [[BORROWED_HOME]] from [[HOME]]
+
// Addition
// CHECK: [[TEMP:%[0-9]+]] = struct_element_addr [[TEMP_FRIDGE]] : $*Refrigerator, #Refrigerator.temperature
// CHECK: apply [[PLUS_EQ]]([[TEMP]], [[DELTA]])
@@ -502,6 +519,8 @@
// CHECK: [[SETTER:%[0-9]+]] = class_method [volatile] [[HOME]] : $APPHouse, #APPHouse.fridge!setter.1.foreign
// CHECK: [[BRIDGE_TO_FN:%[0-9]+]] = function_ref @_TFV10Appliances12Refrigerator19_bridgeToObjectiveCfT_CSo15APPRefrigerator
// CHECK: [[OBJC_ARG:%[0-9]+]] = apply [[BRIDGE_TO_FN]]([[FRIDGE]])
- // CHECK: apply [[SETTER]]([[OBJC_ARG]], [[HOME]])
+ // CHECK: apply [[SETTER]]([[OBJC_ARG]], [[HOME]]) : $@convention(objc_method) (APPRefrigerator, APPHouse) -> ()
+ // CHECK: destroy_value [[OBJC_ARG]]
+ // CHECK: destroy_value [[HOME]]
home.fridge.temperature += delta
}
diff --git a/test/SILGen/objc_bridging_any.swift b/test/SILGen/objc_bridging_any.swift
index 5c9a086..45d80bb 100644
--- a/test/SILGen/objc_bridging_any.swift
+++ b/test/SILGen/objc_bridging_any.swift
@@ -42,10 +42,12 @@
// CHECK: [[METHOD:%.*]] = class_method [volatile] [[SELF]]
// CHECK: [[STRING_COPY:%.*]] = copy_value [[STRING]]
// CHECK: [[BRIDGE_STRING:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveC
- // CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[STRING_COPY]])
+ // CHECK: [[BORROWED_STRING_COPY:%.*]] = begin_borrow [[STRING_COPY]]
+ // CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[BORROWED_STRING_COPY]])
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[BRIDGED]] : $NSString : $NSString, $AnyObject
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
// CHECK: destroy_value [[BRIDGED]]
+ // CHECK: end_borrow [[BORROWED_STRING_COPY]] from [[STRING_COPY]]
// CHECK: destroy_value [[STRING_COPY]]
receiver.takesId(string)
@@ -237,10 +239,14 @@
// CHECK: [[METHOD:%.*]] = class_method [volatile] [[SELF]]
// CHECK: [[STRING_COPY:%.*]] = copy_value [[STRING]]
// CHECK: [[BRIDGE_STRING:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveC
- // CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[STRING_COPY]])
+ // CHECK: [[BORROWED_STRING_COPY:%.*]] = begin_borrow [[STRING_COPY]]
+ // CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[BORROWED_STRING_COPY]])
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[BRIDGED]] : $NSString : $NSString, $AnyObject
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
+ // CHECK: destroy_value [[BRIDGED]]
+ // CHECK: end_borrow [[BORROWED_STRING_COPY]] from [[STRING_COPY]]
+ // CHECK: destroy_value [[STRING_COPY]]
receiver.takesNullableId(string)
// CHECK: [[METHOD:%.*]] = class_method [volatile] [[SELF]] : $NSIdLover,
diff --git a/test/SILGen/objc_dictionary_bridging.swift b/test/SILGen/objc_dictionary_bridging.swift
index c9cd86e..79288f7 100644
--- a/test/SILGen/objc_dictionary_bridging.swift
+++ b/test/SILGen/objc_dictionary_bridging.swift
@@ -37,7 +37,9 @@
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_T0s10DictionaryV10FoundationE19_bridgeToObjectiveCSo12NSDictionaryCyF
- // CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[DICT]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
+ // CHECK: [[BORROWED_DICT:%.*]] = begin_borrow [[DICT]]
+ // CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[BORROWED_DICT]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
+ // CHECK: end_borrow [[BORROWED_DICT]] from [[DICT]]
// CHECK: destroy_value [[DICT]]
// CHECK: return [[NSDICT]] : $NSDictionary
}
@@ -53,7 +55,9 @@
// CHECK: [[DICT:%[0-9]+]] = apply [[GETTER]]([[SELF_COPY]]) : $@convention(method) (@guaranteed Foo) -> @owned Dictionary<Foo, Foo>
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_T0s10DictionaryV10FoundationE19_bridgeToObjectiveCSo12NSDictionaryCyF
- // CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[DICT]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
+ // CHECK: [[BORROWED_DICT:%.*]] = begin_borrow [[DICT]]
+ // CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[BORROWED_DICT]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
+ // CHECK: end_borrow [[BORROWED_DICT]] from [[DICT]]
// CHECK: destroy_value [[DICT]]
// CHECK: return [[NSDICT]] : $NSDictionary
// CHECK: } // end sil function '_T024objc_dictionary_bridging3FooC8propertys10DictionaryVyAcCGfgTo'
diff --git a/test/SILGen/objc_set_bridging.swift b/test/SILGen/objc_set_bridging.swift
index 61dc602..ba3c95a 100644
--- a/test/SILGen/objc_set_bridging.swift
+++ b/test/SILGen/objc_set_bridging.swift
@@ -35,7 +35,9 @@
// CHECK: [[SET:%[0-9]+]] = apply [[SWIFT_FN]]([[SELF_COPY]]) : $@convention(method) (@guaranteed Foo) -> @owned Set<Foo>
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_T0s3SetV10FoundationE19_bridgeToObjectiveCSo5NSSetCyF
- // CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[SET]]) : $@convention(method) <τ_0_0 where τ_0_0 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned NSSet
+ // CHECK: [[BORROWED_SET:%.*]] = begin_borrow [[SET]]
+ // CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[BORROWED_SET]]) : $@convention(method) <τ_0_0 where τ_0_0 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned NSSet
+ // CHECK: end_borrow [[BORROWED_SET]] from [[SET]]
// CHECK: destroy_value [[SET]]
// CHECK: return [[NSSET]] : $NSSet
}
@@ -51,7 +53,9 @@
// CHECK: [[SET:%[0-9]+]] = apply [[GETTER]]([[SELF_COPY]]) : $@convention(method) (@guaranteed Foo) -> @owned Set<Foo>
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_T0s3SetV10FoundationE19_bridgeToObjectiveCSo5NSSetCyF
- // CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[SET]]) : $@convention(method) <τ_0_0 where τ_0_0 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned NSSet
+ // CHECK: [[BORROWED_SET:%.*]] = begin_borrow [[SET]]
+ // CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[BORROWED_SET]]) : $@convention(method) <τ_0_0 where τ_0_0 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned NSSet
+ // CHECK: end_borrow [[BORROWED_SET]] from [[SET]]
// CHECK: destroy_value [[SET]]
// CHECK: return [[NSSET]] : $NSSet
// CHECK: } // end sil function '_T017objc_set_bridging3FooC8property{{[_0-9a-zA-Z]*}}fgTo'
diff --git a/test/SILGen/objc_thunks.swift b/test/SILGen/objc_thunks.swift
index 993afc7..f8377df 100644
--- a/test/SILGen/objc_thunks.swift
+++ b/test/SILGen/objc_thunks.swift
@@ -336,7 +336,9 @@
// CHECK-NEXT: destroy_value [[SELF_COPY]] : $Wotsit<T>
// CHECK-NEXT: // function_ref
// CHECK-NEXT: [[BRIDGE:%.*]] = function_ref @_TFE10FoundationSS19_bridgeToObjectiveCfT_CSo8NSString
- // CHECK-NEXT: [[NSRESULT:%.*]] = apply [[BRIDGE]]([[RESULT]]) : $@convention(method) (@guaranteed String) -> @owned NSString
+ // CHECK-NEXT: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
+ // CHECK-NEXT: [[NSRESULT:%.*]] = apply [[BRIDGE]]([[BORROWED_RESULT]]) : $@convention(method) (@guaranteed String) -> @owned NSString
+ // CHECK-NEXT: end_borrow [[BORROWED_RESULT]] from [[RESULT]]
// CHECK-NEXT: destroy_value [[RESULT]]
// CHECK-NEXT: return [[NSRESULT]] : $NSString
// CHECK-NEXT: }
diff --git a/test/SILGen/properties.swift b/test/SILGen/properties.swift
index 200936c..414f44a 100644
--- a/test/SILGen/properties.swift
+++ b/test/SILGen/properties.swift
@@ -190,13 +190,15 @@
// -- val.ref.val_prop
// CHECK: [[STORAGE:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer
// CHECK: [[VAL_REF_VAL_PROP_TEMP:%.*]] = alloc_stack $Val
+ // CHECK: [[VAL_REF_BORROWED:%.*]] = begin_borrow [[VAL_REF]]
// CHECK: [[T0:%.*]] = address_to_pointer [[VAL_REF_VAL_PROP_TEMP]] : $*Val to $Builtin.RawPointer
// CHECK: [[MAT_VAL_PROP_METHOD:%[0-9]+]] = class_method {{.*}} : $Ref, #Ref.val_prop!materializeForSet.1 : (Ref) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?)
- // CHECK: [[MAT_RESULT:%[0-9]+]] = apply [[MAT_VAL_PROP_METHOD]]([[T0]], [[STORAGE]], [[VAL_REF]])
+ // CHECK: [[MAT_RESULT:%[0-9]+]] = apply [[MAT_VAL_PROP_METHOD]]([[T0]], [[STORAGE]], [[VAL_REF_BORROWED]])
// CHECK: [[T0:%.*]] = tuple_extract [[MAT_RESULT]] : $(Builtin.RawPointer, Optional<Builtin.RawPointer>), 0
// CHECK: [[OPT_CALLBACK:%.*]] = tuple_extract [[MAT_RESULT]] : $(Builtin.RawPointer, Optional<Builtin.RawPointer>), 1
// CHECK: [[T1:%[0-9]+]] = pointer_to_address [[T0]] : $Builtin.RawPointer to [strict] $*Val
// CHECK: [[VAL_REF_VAL_PROP_MAT:%.*]] = mark_dependence [[T1]] : $*Val on [[VAL_REF]]
+ // CHECK: end_borrow [[VAL_REF_BORROWED]] from [[VAL_REF]]
// CHECK: [[V_R_VP_Z_TUPLE_MAT:%[0-9]+]] = alloc_stack $(Int, Int)
// CHECK: [[LD:%[0-9]+]] = load [copy] [[VAL_REF_VAL_PROP_MAT]]
// -- val.ref.val_prop.z_tuple
diff --git a/utils/build-script b/utils/build-script
index 9e9f4d8..9294811 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -2059,6 +2059,11 @@
help="Enable the SIL ownership model",
action='store_true')
+ parser.add_argument("--force-optimized-typechecker",
+ help="Force the type checker to be built with "
+ "optimization",
+ action='store_true')
+
parser.add_argument(
# Explicitly unavailable options here.
"--build-jobs",
diff --git a/utils/swift_build_support/swift_build_support/products/swift.py b/utils/swift_build_support/swift_build_support/products/swift.py
index a1af113..203b113 100644
--- a/utils/swift_build_support/swift_build_support/products/swift.py
+++ b/utils/swift_build_support/swift_build_support/products/swift.py
@@ -36,6 +36,10 @@
# Generate the compile db.
self.cmake_options.extend(self._compile_db_flags)
+ # Add the flag if we are supposed to force the typechecker to compile
+ # with optimization.
+ self.cmake_options.extend(self._force_optimized_typechecker_flags)
+
@property
def _runtime_sanitizer_flags(self):
sanitizer_list = []
@@ -108,3 +112,9 @@
@property
def _compile_db_flags(self):
return ['-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE']
+
+ @property
+ def _force_optimized_typechecker_flags(self):
+ if not self.args.force_optimized_typechecker:
+ return ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE']
+ return ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=TRUE']
diff --git a/utils/swift_build_support/tests/products/test_swift.py b/utils/swift_build_support/tests/products/test_swift.py
index 9378379..0400038 100644
--- a/utils/swift_build_support/tests/products/test_swift.py
+++ b/utils/swift_build_support/tests/products/test_swift.py
@@ -55,7 +55,8 @@
benchmark=False,
benchmark_num_onone_iterations=3,
benchmark_num_o_iterations=3,
- enable_sil_ownership=False)
+ enable_sil_ownership=False,
+ force_optimized_typechecker=False)
# Setup shell
shell.dry_run = True
@@ -84,7 +85,8 @@
build_dir='/path/to/build')
self.assertEqual(set(swift.cmake_options), set([
'-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
- '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE']))
+ '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE',
+ '-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE']))
def test_swift_runtime_tsan(self):
self.args.enable_tsan_runtime = True
@@ -96,7 +98,8 @@
self.assertEqual(set(swift.cmake_options),
set(['-DSWIFT_RUNTIME_USE_SANITIZERS=Thread',
'-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
- '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE']))
+ '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE',
+ '-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE']))
def test_swift_compiler_vendor_flags(self):
self.args.compiler_vendor = "none"
@@ -281,3 +284,15 @@
['-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=TRUE'],
[x for x in swift.cmake_options
if 'SWIFT_STDLIB_ENABLE_SIL_OWNERSHIP' in x])
+
+ def test_force_optimized_typechecker_flags(self):
+ self.args.force_optimized_typechecker = True
+ swift = Swift(
+ args=self.args,
+ toolchain=self.toolchain,
+ source_dir='/path/to/src',
+ build_dir='/path/to/build')
+ self.assertEqual(
+ ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=TRUE'],
+ [x for x in swift.cmake_options
+ if 'SWIFT_FORCE_OPTIMIZED_TYPECHECKER' in x])