Merge pull request #9996 from rudkx/fix-keypath-subscript-score-kind
Update SK_LastScoreKind to SK_KeyPathSubscript.
diff --git a/README.md b/README.md
index a29b10e..36ecd79 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@
For Ubuntu, you'll need the following development dependencies:
- sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-dev
+ sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-dev tzdata
**Note:** LLDB currently requires at least `swig-1.3.40` but will successfully build
with version 2 shipped with Ubuntu.
diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
index 68dd2f6..969994d 100644
--- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
+++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
@@ -48,7 +48,6 @@
"-target" "${target}"
"-F" "${sdk}/../../../Developer/Library/Frameworks"
"-${BENCH_COMPILE_ARCHOPTS_OPT}"
- "-D" "INTERNAL_CHECKS_ENABLED"
"-no-link-objc-runtime"
"-I" "${srcdir}/utils/ObjectiveCTests")
@@ -63,7 +62,6 @@
"-target" "${target}"
"-F" "${sdk}/../../../Developer/Library/Frameworks"
"-${driver_opt}"
- "-D" "INTERNAL_CHECKS_ENABLED"
"-no-link-objc-runtime")
set(bench_library_objects)
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 292c69f..75fc706 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -11,7 +11,7 @@
SET(SPHINX_ARGS
-W
- -D latex_paper_size=${SWIFT_SPHINX_PAPER_SIZE}
+ -D latex_elements.papersize=${SWIFT_SPHINX_PAPER_SIZE}
-d ${CMAKE_BINARY_DIR}/doctrees)
if(SPHINX_EXECUTABLE)
diff --git a/docs/Makefile b/docs/Makefile
index 8998fb1..a3100e6 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -8,8 +8,8 @@
BUILDDIR = _build
# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
+PAPEROPT_a4 = -D latex_elements.papersize=a4
+PAPEROPT_letter = -D latex_elements.papersize=letter
ALLSPHINXOPTS = -W -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
diff --git a/include/swift/AST/DebuggerClient.h b/include/swift/AST/DebuggerClient.h
index e5bcf39..2341102 100644
--- a/include/swift/AST/DebuggerClient.h
+++ b/include/swift/AST/DebuggerClient.h
@@ -48,16 +48,16 @@
/// be consulted first. Return true if results have been added
/// to RV.
/// FIXME: I don't think this ever does anything useful.
- virtual bool lookupOverrides(Identifier Name, DeclContext *DC,
+ virtual bool lookupOverrides(DeclBaseName Name, DeclContext *DC,
SourceLoc Loc, bool IsTypeLookup,
ResultVector &RV) = 0;
-
+
/// This is the second time DebuggerClient is consulted:
/// after all names in external Modules are checked, the client
/// gets a chance to add names to the list of candidates that
- /// have been found in the external module lookup.
+ /// have been found in the external module lookup.
- virtual bool lookupAdditions(Identifier Name, DeclContext *DC,
+ virtual bool lookupAdditions(DeclBaseName Name, DeclContext *DC,
SourceLoc Loc, bool IsTypeLookup,
ResultVector &RV) = 0;
diff --git a/include/swift/IDE/APIDigesterData.h b/include/swift/IDE/APIDigesterData.h
index ead967c..cd96487 100644
--- a/include/swift/IDE/APIDigesterData.h
+++ b/include/swift/IDE/APIDigesterData.h
@@ -231,6 +231,7 @@
StringRef newPrintedName;
Optional<uint8_t> selfIndex;
Optional<uint8_t> removedIndex;
+ StringRef oldTypeName;
StringRef oldPrintedName;
private:
@@ -243,10 +244,10 @@
public:
TypeMemberDiffItem(StringRef usr, StringRef newTypeName,
StringRef newPrintedName, Optional<uint8_t> selfIndex,
- Optional<uint8_t> removedIndex,
+ Optional<uint8_t> removedIndex, StringRef oldTypeName,
StringRef oldPrintedName) : usr(usr),
newTypeName(newTypeName), newPrintedName(newPrintedName),
- selfIndex(selfIndex), removedIndex(removedIndex),
+ selfIndex(selfIndex), removedIndex(removedIndex), oldTypeName(oldTypeName),
oldPrintedName(oldPrintedName), OldNameViewer(oldPrintedName),
NewNameViewer(newPrintedName), Subkind(getSubKind()) {}
static StringRef head();
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 66965a6..064b24f 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -120,6 +120,7 @@
DIFF_ITEM_KEY_KIND_STRING(ModuleName)
DIFF_ITEM_KEY_KIND_STRING(NewTypeName)
DIFF_ITEM_KEY_KIND_STRING(NewPrintedName)
+DIFF_ITEM_KEY_KIND_STRING(OldTypeName)
DIFF_ITEM_KEY_KIND_STRING(OldPrintedName)
DIFF_ITEM_KEY_KIND_STRING(SpecialCaseId)
diff --git a/lib/IDE/APIDigesterData.cpp b/lib/IDE/APIDigesterData.cpp
index 09e998d..0a1dc9c 100644
--- a/lib/IDE/APIDigesterData.cpp
+++ b/lib/IDE/APIDigesterData.cpp
@@ -325,7 +325,7 @@
RemovedIndexShort = RemovedIndex.getValue();
return new (Alloc.Allocate<TypeMemberDiffItem>())
TypeMemberDiffItem(Usr, NewTypeName, NewPrintedName, SelfIndexShort,
- RemovedIndexShort, OldPrintedName);
+ RemovedIndexShort, OldTypeName, OldPrintedName);
}
case APIDiffItemKind::ADK_NoEscapeFuncParam: {
return new (Alloc.Allocate<NoEscapeFuncParam>())
@@ -393,6 +393,8 @@
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Usr), Item->usr);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldPrintedName),
Item->oldPrintedName);
+ out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldTypeName),
+ Item->oldTypeName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewPrintedName),
Item->newPrintedName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewTypeName),
diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp
index bf5ff05..792d2bb 100644
--- a/lib/IDE/Utils.cpp
+++ b/lib/IDE/Utils.cpp
@@ -798,6 +798,10 @@
return;
assert(Labels.back().empty());
Labels.pop_back();
+ std::transform(Labels.begin(), Labels.end(), Labels.begin(),
+ [](StringRef Label) {
+ return Label == "_" ? StringRef() : Label;
+ });
}
unsigned DeclNameViewer::commonPartsCount(DeclNameViewer &Other) const {
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index d620895..677c30b 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -334,7 +334,7 @@
if (Idx < NewName.argSize()) {
auto Label = NewName.args()[Idx++];
- if (Label != "_") {
+ if (!Label.empty()) {
if (LR.getByteLength())
Editor.replace(LR, Label);
else
diff --git a/lib/SIL/SILOpenedArchetypesTracker.cpp b/lib/SIL/SILOpenedArchetypesTracker.cpp
index d94795b..1046efd 100644
--- a/lib/SIL/SILOpenedArchetypesTracker.cpp
+++ b/lib/SIL/SILOpenedArchetypesTracker.cpp
@@ -159,7 +159,8 @@
// First perform a quick check.
for (auto &Op : OpenedArchetypeOperands) {
auto Def = Op.get();
- if (getOpenedArchetypeOf(cast<SILInstruction>(Def)) == archetypeTy)
+ if (isa<SILInstruction>(Def) &&
+ getOpenedArchetypeOf(cast<SILInstruction>(Def)) == archetypeTy)
return Def;
}
// Then use a regular lookup.
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 9ccab94..d8283c1 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -49,9 +49,9 @@
/// that the release occurs in the epilog after any retains associated with
/// @owned return values.
///
-/// 3. Handling addresses. We currently do not handle address types. We can in
-/// the future by introducing alloc_stacks.
-///
+/// 3. We do not support specialization of closures with arguments passed using
+/// any indirect calling conventions besides @inout and @inout_aliasable.
+/// This is a temporary limitation.
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "closure-specialization"
@@ -247,7 +247,8 @@
}
/// Extend the lifetime of 'Arg' to the lifetime of the closure.
- void extendArgumentLifetime(SILValue Arg) const;
+ void extendArgumentLifetime(SILValue Arg,
+ SILArgumentConvention ArgConvention) const;
};
} // end anonymous namespace
@@ -268,6 +269,13 @@
return CInfo->Closure;
}
+static bool isNonInoutIndirectSILArgument(SILValue Arg,
+ SILArgumentConvention ArgConvention) {
+ return !Arg->getType().isObject() && ArgConvention.isIndirectConvention() &&
+ ArgConvention != SILArgumentConvention::Indirect_Inout &&
+ ArgConvention != SILArgumentConvention::Indirect_InoutAliasable;
+}
+
/// Update the callsite to pass in the correct arguments.
static void rewriteApplyInst(const CallSiteDescriptor &CSDesc,
SILFunction *NewF) {
@@ -290,14 +298,33 @@
// implicit release of all captured arguments that occurs when the partial
// apply is destroyed.
SILModule &M = NewF->getModule();
+ unsigned ClosureArgIdx = 0;
+ auto ClosureCalleeConv = CSDesc.getClosureCallee()->getConventions();
for (auto Arg : CSDesc.getArguments()) {
- NewArgs.push_back(Arg);
-
SILType ArgTy = Arg->getType();
// If our argument is of trivial type, continue...
- if (ArgTy.isTrivial(M))
+ if (ArgTy.isTrivial(M)) {
+ NewArgs.push_back(Arg);
+ ++ClosureArgIdx;
continue;
+ }
+
+ auto ArgConvention =
+ ClosureCalleeConv.getSILArgumentConvention(ClosureArgIdx);
+
+ // Non-inout indirect arguments are not supported yet.
+ assert(ArgTy.isObject() ||
+ !isNonInoutIndirectSILArgument(Arg, ArgConvention));
+
+ // If argument is not an object and it is an inout parameter,
+ // continue...
+ if (!ArgTy.isObject() &&
+ !isNonInoutIndirectSILArgument(Arg, ArgConvention)) {
+ NewArgs.push_back(Arg);
+ ++ClosureArgIdx;
+ continue;
+ }
// TODO: When we support address types, this code path will need to be
// updated.
@@ -340,15 +367,21 @@
if (AI.getParent() != Closure->getParent()) {
// Emit the retain and release that keeps the argument life across the
// callee using the closure.
- CSDesc.extendArgumentLifetime(Arg);
+ CSDesc.extendArgumentLifetime(Arg, ArgConvention);
- // Emit the retain that matches the captured argument by the partial_apply
+ // Emit the retain that matches the captured argument by the
+ // partial_apply
// in the callee that is consumed by the partial_apply.
Builder.setInsertionPoint(AI.getInstruction());
- Builder.createRetainValue(Closure->getLoc(), Arg, Builder.getDefaultAtomicity());
+ Builder.createRetainValue(Closure->getLoc(), Arg,
+ Builder.getDefaultAtomicity());
} else {
- Builder.createRetainValue(Closure->getLoc(), Arg, Builder.getDefaultAtomicity());
+ Builder.createRetainValue(Closure->getLoc(), Arg,
+ Builder.getDefaultAtomicity());
}
+
+ NewArgs.push_back(Arg);
+ ++ClosureArgIdx;
}
Builder.setInsertionPoint(AI.getInstruction());
@@ -409,16 +442,27 @@
return Mangler.mangle();
}
-void CallSiteDescriptor::extendArgumentLifetime(SILValue Arg) const {
+void CallSiteDescriptor::extendArgumentLifetime(
+ SILValue Arg, SILArgumentConvention ArgConvention) const {
assert(!CInfo->LifetimeFrontier.empty() &&
"Need a post-dominating release(s)");
+ auto ArgTy = Arg->getType();
+
// Extend the lifetime of a captured argument to cover the callee.
SILBuilderWithScope Builder(getClosure());
- Builder.createRetainValue(getClosure()->getLoc(), Arg, Builder.getDefaultAtomicity());
- for (auto *I : CInfo->LifetimeFrontier) {
- Builder.setInsertionPoint(I);
- Builder.createReleaseValue(getClosure()->getLoc(), Arg, Builder.getDefaultAtomicity());
+
+ // Indirect non-inout arguments are not supported yet.
+ assert(!isNonInoutIndirectSILArgument(Arg, ArgConvention));
+
+ if (ArgTy.isObject()) {
+ Builder.createRetainValue(getClosure()->getLoc(), Arg,
+ Builder.getDefaultAtomicity());
+ for (auto *I : CInfo->LifetimeFrontier) {
+ Builder.setInsertionPoint(I);
+ Builder.createReleaseValue(getClosure()->getLoc(), Arg,
+ Builder.getDefaultAtomicity());
+ }
}
}
@@ -437,12 +481,6 @@
if (PAI->hasSubstitutions())
return false;
- // If any arguments are not objects, return false. This is a temporary
- // limitation.
- for (SILValue Arg : PAI->getArguments())
- if (!Arg->getType().isObject())
- return false;
-
// Ok, it is a closure we support, set Callee.
Callee = PAI->getCallee();
@@ -459,6 +497,30 @@
if (!FRI)
return false;
+ if (auto *PAI = dyn_cast<PartialApplyInst>(Closure)) {
+ // Bail if any of the arguments are passed by address and
+ // are not @inout.
+ // This is a temporary limitation.
+ auto ClosureCallee = FRI->getReferencedFunction();
+ assert(ClosureCallee);
+ auto ClosureCalleeConv = ClosureCallee->getConventions();
+ unsigned ClosureArgIdx = 0;
+ for (auto Arg : PAI->getArguments()) {
+ SILType ArgTy = Arg->getType();
+ // If our argument is an object, continue...
+ if (ArgTy.isObject()) {
+ ++ClosureArgIdx;
+ continue;
+ }
+ auto ArgConvention =
+ ClosureCalleeConv.getSILArgumentConvention(ClosureArgIdx);
+ if (ArgConvention != SILArgumentConvention::Indirect_Inout &&
+ ArgConvention != SILArgumentConvention::Indirect_InoutAliasable)
+ return false;
+ ++ClosureArgIdx;
+ }
+ }
+
// Otherwise, we do support specializing this closure.
return true;
}
@@ -503,23 +565,29 @@
SILModule &M = ClosureUser->getModule();
// Captured parameters are always appended to the function signature. If the
- // type of the captured argument is trivial, pass the argument as
- // Direct_Unowned. Otherwise pass it as Direct_Owned.
+ // type of the captured argument is:
+ // - direct and trivial, pass the argument as Direct_Unowned.
+ // - direct and non-trivial, pass the argument as Direct_Owned.
+ // - indirect, pass the argument using the same parameter convention as in the
+ // original closure.
//
// We use the type of the closure here since we allow for the closure to be an
// external declaration.
unsigned NumTotalParams = ClosedOverFunConv.getNumParameters();
unsigned NumNotCaptured = NumTotalParams - CallSiteDesc.getNumArguments();
for (auto &PInfo : ClosedOverFunConv.getParameters().slice(NumNotCaptured)) {
- if (ClosedOverFunConv.getSILType(PInfo).isTrivial(M)) {
- SILParameterInfo NewPInfo(PInfo.getType(),
- ParameterConvention::Direct_Unowned);
- NewParameterInfoList.push_back(NewPInfo);
- continue;
+ ParameterConvention ParamConv;
+ if (PInfo.isFormalIndirect()) {
+ ParamConv = PInfo.getConvention();
+ assert(ParamConv == ParameterConvention::Indirect_Inout ||
+ ParamConv == ParameterConvention::Indirect_InoutAliasable);
+ } else {
+ ParamConv = ClosedOverFunConv.getSILType(PInfo).isTrivial(M)
+ ? ParameterConvention::Direct_Unowned
+ : ParameterConvention::Direct_Owned;
}
- SILParameterInfo NewPInfo(PInfo.getType(),
- ParameterConvention::Direct_Owned);
+ SILParameterInfo NewPInfo(PInfo.getType(), ParamConv);
NewParameterInfoList.push_back(NewPInfo);
}
diff --git a/test/SILGen/collection_cast_crash.swift b/test/SILGen/collection_cast_crash.swift
index 1eb55ed..08ddd49 100644
--- a/test/SILGen/collection_cast_crash.swift
+++ b/test/SILGen/collection_cast_crash.swift
@@ -10,28 +10,28 @@
}
func ==(lhs: KeyClass, rhs: KeyClass) -> Bool { return true }
-// CHECK-LABEL: sil shared @{{.*}}arrayUpCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}arrayUpCast{{.*}} <Ct where Ct : MyClass>
func arrayUpCast<Ct: MyClass>(_ arr: [Ct]) -> [MyClass] {
- // CHECK: apply %{{[0-9]*}}<Ct, MyClass>(%{{[0-9]*}})
+ // CHECK: apply %{{[0-9]*}}<Ct{{.*}}>(%{{[0-9]*}})
return arr
// CHECK: return
}
-// CHECK-LABEL: sil shared @{{.*}}arrayDownCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}arrayDownCast{{.*}} <Ct where Ct : MyClass>
func arrayDownCast<Ct: MyClass>(_ arr: [MyClass]) -> [Ct] {
- // CHECK: apply %{{[0-9]*}}<MyClass, Ct>(%{{[0-9]*}})
+ // CHECK: apply %{{[0-9]*}}<{{.*}}Ct>(%{{[0-9]*}})
return arr as! [Ct]
// CHECK: return
}
-// CHECK-LABEL: sil shared @{{.*}}dictUpCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}dictUpCast{{.*}} <Ct where Ct : MyClass>
func dictUpCast<Ct: MyClass>(_ dict: [KeyClass:Ct]) -> [KeyClass:MyClass] {
- // CHECK: apply %{{[0-9]*}}<KeyClass, Ct, KeyClass, MyClass>(%{{[0-9]*}})
+ // CHECK: apply %{{[0-9]*}}<{{.*}}Ct{{.*}}>(%{{[0-9]*}})
return dict as [KeyClass:MyClass]
// CHECK: return
}
-// CHECK-LABEL: sil shared @{{.*}}dictDownCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}dictDownCast{{.*}} <Ct where Ct : MyClass>
func dictDownCast<Ct: MyClass>(_ dict: [KeyClass:MyClass]) -> [KeyClass:Ct] {
// CHECK: apply %{{[0-9]*}}<KeyClass, MyClass, KeyClass, Ct>(%{{[0-9]*}})
return dict as! [KeyClass:Ct]
diff --git a/test/SILOptimizer/closure_specialize.sil b/test/SILOptimizer/closure_specialize.sil
index d8609ac..35aa8b1 100644
--- a/test/SILOptimizer/closure_specialize.sil
+++ b/test/SILOptimizer/closure_specialize.sil
@@ -127,7 +127,9 @@
}
// We don't handle closures that close over address types (*NOTE* this includes
-// address and non-address only types). This is a temporary limitation.
+// address and non-address only types) taken as @in or @in_guaranteed.
+
+// This is a temporary limitation.
// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int) -> () {
sil @address_closure : $@convention(thin) (@in Int) -> () {
bb0(%0 : $*Int):
diff --git a/test/SILOptimizer/closure_specialize_consolidated.sil b/test/SILOptimizer/closure_specialize_consolidated.sil
index 775616e..a35705d 100644
--- a/test/SILOptimizer/closure_specialize_consolidated.sil
+++ b/test/SILOptimizer/closure_specialize_consolidated.sil
@@ -12,6 +12,17 @@
func foo(f: (Int32)->Int32, _ j: Int32) -> Int32
}
+public class C {
+ @sil_stored var c: C? { get set }
+ init()
+}
+
+public struct S {
+ @sil_stored var c: C? { get set }
+ init(c: C?)
+ init()
+}
+
// = Test Summary =
// We test the following things here:
//
@@ -28,19 +39,73 @@
// Address Argument Tests //
////////////////////////////
//
-// Make sure that we do not specialize if we have address arguments. We do not
-// handle them correctly so there is a special check to not perform any action.
+// Make sure that we can specialize even if we have address arguments.
//
-
-// We don't handle closures that close over address types (*NOTE* this includes
-// address and non-address only types). This is a temporary limitation.
-// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int) -> () {
-sil @address_closure : $@convention(thin) (@in Int) -> () {
-bb0(%0 : $*Int):
+// But we don't handle closures that close over address types passed as @in or
+// @in_guaranteed.
+// (*NOTE* this includes address and non-address only types).
+// This is a temporary limitation.
+// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int32) -> () {
+sil @address_closure : $@convention(thin) (@in Int32) -> () {
+bb0(%0 : $*Int32):
%6 = tuple()
return %6 : $()
}
+sil @address_closure_struct_complex : $@convention(thin) (@in S) -> () {
+bb0(%0 : $*S):
+ %6 = tuple()
+ return %6 : $()
+}
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: function_ref @address_closure_trivial : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: function_ref @address_closure_trivial_mutating : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: function_ref @address_closure_existential : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: function_ref @address_closure_struct1 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: function_ref @address_closure_struct2 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: function_ref @address_closure_class1 : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: apply
+// CHECK: return
+
// CHECK-LABEL: sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () {
sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () {
bb0(%0 : $@callee_owned () -> ()):
@@ -49,18 +114,282 @@
return %9999 : $()
}
-// CHECK-LABEL: sil @address_caller : $@convention(thin) (@in Int) -> () {
+// CHECK-LABEL: sil @address_caller : $@convention(thin) (@in Int32) -> () {
// CHECK-NOT: _TTSf1cl15address_closureSi__address_closure_user
-sil @address_caller : $@convention(thin) (@in Int) -> () {
-bb0(%0 : $*Int):
- %1 = function_ref @address_closure : $@convention(thin) (@in Int) -> ()
- %2 = partial_apply %1(%0) : $@convention(thin) (@in Int) -> ()
+sil @address_caller : $@convention(thin) (@in Int32) -> () {
+bb0(%0 : $*Int32):
+ %1 = function_ref @address_closure : $@convention(thin) (@in Int32) -> ()
+ %2 = partial_apply %1(%0) : $@convention(thin) (@in Int32) -> ()
%3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
%4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
%9999 = tuple()
return %9999 : $()
}
+// We don't handle closures that close over address types passed as @in or
+// @in_guaranteed.
+// (*NOTE* this includes address and non-address only types).
+// This is a temporary limitation.
+//
+// CHECK-LABEL: sil @address_caller_complex : $@convention(thin) (@in Int32) -> ()
+// CHECK-NOT: function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in Int32) -> ()
+// CHECK: partial_apply
+// CHECK-NOT: function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in Int32) -> ()
+// CHECK: return
+sil @address_caller_complex : $@convention(thin) (@in Int32) -> () {
+bb0(%0 : $*Int32):
+ %00 = alloc_stack $Int32
+ %01 = load %0 : $*Int32
+ store %01 to %00 : $*Int32
+ %1 = function_ref @address_closure : $@convention(thin) (@in Int32) -> ()
+ %2 = partial_apply %1(%00) : $@convention(thin) (@in Int32) -> ()
+ %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ dealloc_stack %00 : $*Int32
+ br bb1
+
+bb1:
+ %6 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// We don't handle closures that close over address types passed as @in or
+// @in_guaranteed.
+// (*NOTE* this includes address and non-address only types).
+// This is a temporary limitation.
+//
+// CHECK-LABEL: sil @address_caller_struct_complex : $@convention(thin) (@in S) -> ()
+// CHECK-NOT: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in S) -> ()
+// CHECK: partial_apply
+// CHECK-NOT: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in S) -> ()
+// CHECK: return
+sil @address_caller_struct_complex : $@convention(thin) (@in S) -> () {
+bb0(%0 : $*S):
+ %00 = alloc_stack $S
+ %01 = load %0 : $*S
+ retain_value %01 : $S
+ store %01 to %00 : $*S
+ %1 = function_ref @address_closure_struct_complex : $@convention(thin) (@in S) -> ()
+ %2 = partial_apply %1(%00) : $@convention(thin) (@in S) -> ()
+ %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %5 = load %00 : $*S
+ release_value %5 : $S
+ dealloc_stack %00 : $*S
+ br bb1
+
+bb1:
+ %6 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %9999 = tuple()
+ return %9999 : $()
+}
+
+// More complex tests involving address arguments.
+
+sil @address_closure_trivial : $@convention(thin) (Int32, @inout_aliasable Int32) -> () {
+bb0(%0 : $Int32, %1 : $*Int32):
+ %9 = integer_literal $Builtin.Int32, 42
+ %10 = struct $Int32 (%9 : $Builtin.Int32)
+ store %10 to %1 : $*Int32
+ %12 = tuple ()
+ return %12 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_trivial
+// CHECK-NOT: partial_apply
+// CHECK: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_trivial: $@convention(thin) (Int32) -> Int32 {
+bb0(%0 : $Int32):
+ %2 = alloc_stack $Int32, var, name "xx"
+ store %0 to %2 : $*Int32
+ // function_ref address_closure_user(f:)
+ %4 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ // function_ref address_closure_trivial(x:)
+ %5 = function_ref @address_closure_trivial : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+ %6 = partial_apply %5(%0, %2) : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+ %7 = apply %4(%6) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %8 = load %2 : $*Int32
+ dealloc_stack %2 : $*Int32
+ return %8 : $Int32
+}
+
+sil @address_closure_trivial_mutating : $@convention(thin) (@inout_aliasable Int32) -> () {
+bb0(%0 : $*Int32):
+ %2 = struct_element_addr %0 : $*Int32, #Int32._value
+ %3 = load %2 : $*Builtin.Int32
+ %4 = integer_literal $Builtin.Int32, 1
+ %5 = integer_literal $Builtin.Int1, -1
+ %6 = builtin "sadd_with_overflow_Int32"(%3 : $Builtin.Int32, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
+ %7 = tuple_extract %6 : $(Builtin.Int32, Builtin.Int1), 0
+ %8 = tuple_extract %6 : $(Builtin.Int32, Builtin.Int1), 1
+ cond_fail %8 : $Builtin.Int1
+ %10 = struct $Int32 (%7 : $Builtin.Int32)
+ store %10 to %0 : $*Int32
+ %12 = tuple ()
+ return %12 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_trivial_mutating
+// CHECK-NOT: partial_apply
+// CHECK: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_trivial_mutating: $@convention(thin) (Int32) -> Int32 {
+bb0(%0 : $Int32):
+ %2 = alloc_stack $Int32, var, name "xx"
+ store %0 to %2 : $*Int32
+ %4 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %5 = function_ref @address_closure_trivial_mutating : $@convention(thin) (@inout_aliasable Int32) -> () // user: %6
+ %6 = partial_apply %5(%2) : $@convention(thin) (@inout_aliasable Int32) -> () // user: %7
+ %7 = apply %4(%6) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %8 = load %2 : $*Int32
+ dealloc_stack %2 : $*Int32
+ return %8 : $Int32
+}
+
+// CHECK-LABEL: sil @address_caller_existential
+// CHECK-NOT: partial_apply
+// CHECK: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: [[SPECIALIZED_FN2:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: apply [[SPECIALIZED_FN2]]{{.*}}
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_existential : $@convention(thin) (@in P, @in P, Int32) -> @out P {
+bb0(%0 : $*P, %1 : $*P, %2 : $*P, %3 : $Int32):
+ %7 = alloc_stack $P
+ copy_addr %1 to [initialization] %7 : $*P
+ %9 = function_ref @address_closure_existential : $@convention(thin) (@inout_aliasable P) -> ()
+ %10 = partial_apply %9(%7) : $@convention(thin) (@inout_aliasable P) -> ()
+ %12 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ strong_retain %10 : $@callee_owned () -> ()
+ %14 = apply %12(%10) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ strong_retain %10 : $@callee_owned () -> ()
+ %16 = apply %12(%10) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %17 = integer_literal $Builtin.Int32, 10
+ %18 = struct_extract %3 : $Int32, #Int32._value
+ %19 = builtin "cmp_slt_Int32"(%17 : $Builtin.Int32, %18 : $Builtin.Int32) : $Builtin.Int1
+ cond_br %19, bb1, bb2
+
+bb1:
+ destroy_addr %2 : $*P
+ copy_addr %1 to [initialization] %0 : $*P
+ destroy_addr %1 : $*P
+ strong_release %10 : $@callee_owned () -> ()
+ br bb3
+
+bb2:
+ destroy_addr %1 : $*P
+ copy_addr %2 to [initialization] %0 : $*P
+ destroy_addr %2 : $*P
+ strong_release %10 : $@callee_owned () -> ()
+ br bb3
+
+bb3:
+ destroy_addr %7 : $*P
+ dealloc_stack %7 : $*P
+ %33 = tuple ()
+ return %33 : $()
+}
+
+sil shared @address_closure_existential : $@convention(thin) (@inout_aliasable P) -> () {
+bb0(%0 : $*P):
+ %7 = tuple () // user: %8
+ return %7 : $() // id: %8
+}
+
+sil @address_closure_struct1 : $@convention(thin) (@inout_aliasable S, @owned S) -> () {
+bb0(%0 : $*S, %1 : $S):
+ %4 = struct_element_addr %0 : $*S, #S.c
+ %5 = load %4 : $*Optional<C>
+ store %1 to %0 : $*S
+ release_value %5 : $Optional<C>
+ %8 = tuple ()
+ return %8 : $()
+}
+
+sil @address_closure_struct2 : $@convention(thin) (@inout_aliasable S, @owned S) -> () {
+bb0(%0 : $*S, %1 : $S):
+ %4 = struct_element_addr %0 : $*S, #S.c
+ %5 = load %4 : $*Optional<C>
+ store %1 to %0 : $*S
+ release_value %5 : $Optional<C>
+ %8 = tuple ()
+ return %8 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_struct
+// CHECK-NOT: partial_apply
+// CHECK: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: apply [[SPECIALIZED_FN1]]
+// CHECK: [[SPECIALIZED_FN2:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: apply [[SPECIALIZED_FN2]]
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_struct : $@convention(thin) (@guaranteed S, @guaranteed S) -> @owned S {
+bb0(%0 : $S, %1 : $S):
+ %4 = alloc_stack $S, var, name "xx"
+ %5 = struct_extract %0 : $S, #S.c
+ store %0 to %4 : $*S
+ %7 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %8 = function_ref @address_closure_struct1 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+ %9 = partial_apply %8(%4, %1) : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+ retain_value %0 : $S
+ retain_value %1 : $S
+ %12 = apply %7(%9) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %13 = function_ref @address_closure_struct2 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+ %14 = partial_apply %13(%4, %0) : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+ retain_value %5 : $Optional<C>
+ %16 = apply %7(%14) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %17 = load %4 : $*S
+ dealloc_stack %4 : $*S
+ return %17 : $S
+}
+
+sil shared @address_closure_class1 : $@convention(thin) (@inout_aliasable C, @owned C) -> () {
+bb0(%0 : $*C, %1 : $C):
+ %4 = load %0 : $*C
+ store %1 to %0 : $*C
+ strong_release %4 : $C
+ %7 = tuple ()
+ return %7 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_class1
+// CHECK-NOT: partial_apply
+// CHECK: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: [[SPECIALIZED_FN2:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: apply [[SPECIALIZED_FN2]]{{.*}}
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_class1 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C {
+bb0(%0 : $C, %1 : $C):
+ %4 = alloc_stack $C, var, name "xx"
+ store %0 to %4 : $*C
+ %7 = function_ref @address_closure_class1 : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+ %8 = partial_apply %7(%4, %1) : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+ %10 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ strong_retain %0 : $C
+ strong_retain %1 : $C
+ strong_retain %8 : $@callee_owned () -> ()
+ %14 = apply %10(%8) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ strong_retain %8 : $@callee_owned () -> ()
+ %16 = apply %10(%8) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+ %17 = load %4 : $*C
+ strong_retain %17 : $C
+ strong_release %8 : $@callee_owned () -> ()
+ %20 = load %4 : $*C
+ strong_release %20 : $C
+ dealloc_stack %4 : $*C
+ return %17 : $C
+}
+
/////////////////////////////////////
// Thin To Thick and Partial Apply //
/////////////////////////////////////
diff --git a/test/SILOptimizer/closure_specialize_simple.sil b/test/SILOptimizer/closure_specialize_simple.sil
index f231a86..5dce016 100644
--- a/test/SILOptimizer/closure_specialize_simple.sil
+++ b/test/SILOptimizer/closure_specialize_simple.sil
@@ -190,7 +190,7 @@
// CHECK: [[INLINEDCLOSURE_CALLER1:%.*]] = function_ref @_T040indirect_parameter_partial_apply_caller10a1_b1_c1_D4_funTf1c_n
// CHECK-NOT: partial_apply [[CLOSUREFUN]]()
-// We don't handle captured indirect parameters yet.
+// We don't handle captured indirect @in and @in_guaranteed parameters yet.
// CHECK: [[CLOSURE2:%.*]] = partial_apply [[CLOSUREFUN]](%{{.*}})
// CHECK: [[CLOSURE3:%.*]] = partial_apply [[CLOSUREFUN]](%{{.*}})
// CHECK: [[CLOSURE4:%.*]] = partial_apply [[CLOSUREFUN]](%{{.*}})
diff --git a/test/SILOptimizer/inline_self.swift b/test/SILOptimizer/inline_self.swift
index 31a1e82..79e657b 100644
--- a/test/SILOptimizer/inline_self.swift
+++ b/test/SILOptimizer/inline_self.swift
@@ -33,6 +33,12 @@
fn()
}
+protocol Use {
+ func use<T>(_ t: T)
+}
+
+var user: Use? = nil
+
class BaseZ {
final func baseCapturesSelf() -> Self {
let fn = { [weak self] in _ = self }
@@ -41,11 +47,14 @@
}
}
-// Do not inline C.capturesSelf() into main either.
+// Do not inline C.capturesSelf() into main either. Doing so would lose the ability
+// to materialize local Self metadata.
class Z : BaseZ {
+ @inline(__always)
final func capturesSelf() -> Self {
let fn = { [weak self] in _ = self }
callIt(fn: fn)
+ user?.use(self)
return self
}
diff --git a/test/api-digester/Inputs/APINotesLeft/APINotesTest.apinotes b/test/api-digester/Inputs/APINotesLeft/APINotesTest.apinotes
new file mode 100644
index 0000000..3256892
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesLeft/APINotesTest.apinotes
@@ -0,0 +1,4 @@
+Name: APINotesTest
+Globals:
+ - Name: ANTGlobalValue
+ SwiftName: OldType.oldMember
diff --git a/test/api-digester/Inputs/APINotesLeft/APINotesTest.h b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
new file mode 100644
index 0000000..20d1c60
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
@@ -0,0 +1,6 @@
+extern int ANTGlobalValue;
+
+@interface NewType
+@end
+@interface OldType
+@end
diff --git a/test/api-digester/Inputs/APINotesLeft/module.modulemap b/test/api-digester/Inputs/APINotesLeft/module.modulemap
new file mode 100644
index 0000000..afd875a
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesLeft/module.modulemap
@@ -0,0 +1,3 @@
+module APINotesTest {
+ header "APINotesTest.h"
+}
diff --git a/test/api-digester/Inputs/APINotesRight/APINotesTest.apinotes b/test/api-digester/Inputs/APINotesRight/APINotesTest.apinotes
new file mode 100644
index 0000000..0a50e5e
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesRight/APINotesTest.apinotes
@@ -0,0 +1,4 @@
+Name: APINotesTest
+Globals:
+ - Name: ANTGlobalValue
+ SwiftName: NewType.newMember
diff --git a/test/api-digester/Inputs/APINotesRight/APINotesTest.h b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
new file mode 100644
index 0000000..5dc6d9e
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
@@ -0,0 +1,6 @@
+extern int ANTGlobalValue;
+
+@interface NewType
+@end
+@interface OldType
+@end
\ No newline at end of file
diff --git a/test/api-digester/Inputs/APINotesRight/module.modulemap b/test/api-digester/Inputs/APINotesRight/module.modulemap
new file mode 100644
index 0000000..afd875a
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesRight/module.modulemap
@@ -0,0 +1,3 @@
+module APINotesTest {
+ header "APINotesTest.h"
+}
diff --git a/test/api-digester/Outputs/apinotes-migrator-gen.json b/test/api-digester/Outputs/apinotes-migrator-gen.json
new file mode 100644
index 0000000..09d2570
--- /dev/null
+++ b/test/api-digester/Outputs/apinotes-migrator-gen.json
@@ -0,0 +1,10 @@
+[
+ {
+ "DiffItemKind": "TypeMemberDiffItem",
+ "Usr": "c:@ANTGlobalValue",
+ "OldPrintedName": "oldMember",
+ "OldTypeName": "OldType",
+ "NewPrintedName": "newMember",
+ "NewTypeName": "NewType"
+ }
+]
\ No newline at end of file
diff --git a/test/api-digester/apinotes-migrator-gen.swift b/test/api-digester/apinotes-migrator-gen.swift
new file mode 100644
index 0000000..7210b91
--- /dev/null
+++ b/test/api-digester/apinotes-migrator-gen.swift
@@ -0,0 +1,8 @@
+// REQUIRES: OS=macosx
+// RUN: rm -rf %t.mod && mkdir -p %t.mod
+// RUN: rm -rf %t.sdk && mkdir -p %t.sdk
+// RUN: rm -rf %t.module-cache && mkdir -p %t.module-cache
+// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesLeft
+// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesRight
+// RUN: %api-digester -compare-sdk --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result -json
+// RUN: diff -u %S/Outputs/apinotes-migrator-gen.json %t.result
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index e21d589..64a53fc 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -2159,9 +2159,15 @@
auto diffParent = diffNode->getParent();
assert(nodeParent && diffParent && "trying to check Root?");
+ // Move from global variable to a member variable.
if (nodeParent->getKind() == SDKNodeKind::TypeDecl &&
diffParent->getKind() == SDKNodeKind::Root)
TypeMemberDiffs.push_back({diffNode, node});
+ // Move from a member variable to another member variable
+ if (nodeParent->getKind() == SDKNodeKind::TypeDecl &&
+ diffParent->getKind() == SDKNodeKind::TypeDecl)
+ TypeMemberDiffs.push_back({diffNode, node});
+ // Move from a getter/setter function to a property
else if (node->getKind() == SDKNodeKind::Getter &&
diffNode->getKind() == SDKNodeKind::Function &&
node->isNameValid()) {
@@ -2998,6 +3004,7 @@
RenameDetectorForMemberDiff Detector;
for (auto pair : diffFinder.getDiffs()) {
auto left = pair.first;
+ auto leftParent = left->getParent();
auto right = pair.second;
auto rightParent = right->getParent();
@@ -3006,6 +3013,8 @@
TypeMemberDiffItem item = {
right->getAs<SDKNodeDecl>()->getUsr(), constructFullTypeName(rightParent),
right->getPrintedName(), findSelfIndex(right), None,
+ leftParent->getKind() == SDKNodeKind::Root ?
+ StringRef() : constructFullTypeName(leftParent),
left->getPrintedName()};
out.emplace_back(item);
Detector.workOn(left, right);
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 5280119..07bde7a 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -108,13 +108,13 @@
return false;
}
void didGlobalize(Decl *D) override {}
- bool lookupOverrides(Identifier Name, DeclContext *DC,
+ bool lookupOverrides(DeclBaseName Name, DeclContext *DC,
SourceLoc Loc, bool IsTypeLookup,
ResultVector &RV) override {
return false;
}
- bool lookupAdditions(Identifier Name, DeclContext *DC,
+ bool lookupAdditions(DeclBaseName Name, DeclContext *DC,
SourceLoc Loc, bool IsTypeLookup,
ResultVector &RV) override {
return false;