Merge pull request #16642 from rjmccall/abi-accessibility-4.2

[4.2] Perform value operations opaquely on ABI-inaccessible types
diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h
index 06b5ef1..25405ef 100644
--- a/include/swift/AST/IRGenOptions.h
+++ b/include/swift/AST/IRGenOptions.h
@@ -106,8 +106,8 @@
   /// \brief Whether we should run LLVM optimizations after IRGen.
   unsigned DisableLLVMOptzns : 1;
 
-  /// \brief Whether we should run LLVM ARC optimizations after IRGen.
-  unsigned DisableLLVMARCOpts : 1;
+  /// Whether we should run swift specific LLVM optimizations after IRGen.
+  unsigned DisableSwiftSpecificLLVMOptzns : 1;
 
   /// \brief Whether we should run LLVM SLP vectorizer.
   unsigned DisableLLVMSLPVectorizer : 1;
@@ -182,7 +182,7 @@
         Verify(true), OptMode(OptimizationMode::NotSet),
         Sanitizers(OptionSet<SanitizerKind>()),
         DebugInfoKind(IRGenDebugInfoKind::None), UseJIT(false),
-        DisableLLVMOptzns(false), DisableLLVMARCOpts(false),
+        DisableLLVMOptzns(false), DisableSwiftSpecificLLVMOptzns(false),
         DisableLLVMSLPVectorizer(false), DisableFPElim(true), Playground(false),
         EmitStackPromotionChecks(false), PrintInlineTree(false),
         EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false),
@@ -197,7 +197,7 @@
   unsigned getLLVMCodeGenOptionsHash() {
     unsigned Hash = (unsigned)OptMode;
     Hash = (Hash << 1) | DisableLLVMOptzns;
-    Hash = (Hash << 1) | DisableLLVMARCOpts;
+    Hash = (Hash << 1) | DisableSwiftSpecificLLVMOptzns;
     return Hash;
   }
 
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 1080b9e..74c02d3 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -214,8 +214,8 @@
 def disable_sil_perf_optzns : Flag<["-"], "disable-sil-perf-optzns">,
   HelpText<"Don't run SIL performance optimization passes">;
 
-def disable_llvm_arc_opts : Flag<["-"], "disable-llvm-arc-opts">,
-  HelpText<"Don't run LLVM ARC optimization passes.">;
+def disable_swift_specific_llvm_optzns : Flag<["-"], "disable-swift-specific-llvm-optzns">,
+  HelpText<"Don't run Swift specific LLVM optimization passes.">;
 
 def disable_llvm_slp_vectorizer : Flag<["-"], "disable-llvm-slp-vectorizer">,
   HelpText<"Don't run LLVM SLP vectorizer">;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index e35f81d..4c90c63 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -807,7 +807,8 @@
   }
 
   Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns);
-  Opts.DisableLLVMARCOpts |= Args.hasArg(OPT_disable_llvm_arc_opts);
+  Opts.DisableSwiftSpecificLLVMOptzns |=
+      Args.hasArg(OPT_disable_swift_specific_llvm_optzns);
   Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer);
   if (Args.hasArg(OPT_disable_llvm_verify))
     Opts.Verify = false;
diff --git a/lib/IRGen/GenHeap.cpp b/lib/IRGen/GenHeap.cpp
index ac58faa..ea22ae1 100644
--- a/lib/IRGen/GenHeap.cpp
+++ b/lib/IRGen/GenHeap.cpp
@@ -1306,7 +1306,8 @@
 /// optimizer not to touch this value.
 void IRGenFunction::emitFixLifetime(llvm::Value *value) {
   // If we aren't running the LLVM ARC optimizer, we don't need to emit this.
-  if (!IGM.IRGen.Opts.shouldOptimize() || IGM.IRGen.Opts.DisableLLVMARCOpts)
+  if (!IGM.IRGen.Opts.shouldOptimize() ||
+      IGM.IRGen.Opts.DisableSwiftSpecificLLVMOptzns)
     return;
   if (doesNotRequireRefCounting(value)) return;
   emitUnaryRefCountCall(*this, IGM.getFixLifetimeFn(), value);
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index f57248b..10daa8d 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -176,9 +176,12 @@
         llvm::createAlwaysInlinerLegacyPass(/*insertlifetime*/false);
   }
 
+  bool RunSwiftSpecificLLVMOptzns =
+      !Opts.DisableSwiftSpecificLLVMOptzns && !Opts.DisableLLVMOptzns;
+
   // If the optimizer is enabled, we run the ARCOpt pass in the scalar optimizer
   // and the Contract pass as late as possible.
-  if (!Opts.DisableLLVMARCOpts && !Opts.DisableLLVMOptzns) {
+  if (RunSwiftSpecificLLVMOptzns) {
     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                            addSwiftARCOptPass);
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
@@ -208,11 +211,12 @@
                            addSanitizerCoveragePass);
   }
 
-  if (!Opts.DisableLLVMOptzns)
+  if (RunSwiftSpecificLLVMOptzns)
     addCoroutinePassesToExtensionPoints(PMBuilder);
 
-  PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
-                         addSwiftMergeFunctionsPass);
+  if (RunSwiftSpecificLLVMOptzns)
+    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
+                           addSwiftMergeFunctionsPass);
 
   // Configure the function passes.
   legacy::FunctionPassManager FunctionPasses(Module);
@@ -224,7 +228,7 @@
 
   // The PMBuilder only knows about LLVM AA passes.  We should explicitly add
   // the swift AA pass after the other ones.
-  if (!Opts.DisableLLVMARCOpts && !Opts.DisableLLVMOptzns) {
+  if (RunSwiftSpecificLLVMOptzns) {
     FunctionPasses.add(createSwiftAAWrapperPass());
     FunctionPasses.add(createExternalAAWrapperPass([](Pass &P, Function &,
                                                       AAResults &AAR) {
@@ -253,7 +257,7 @@
 
   // The PMBuilder only knows about LLVM AA passes.  We should explicitly add
   // the swift AA pass after the other ones.
-  if (!Opts.DisableLLVMARCOpts && !Opts.DisableLLVMOptzns) {
+  if (RunSwiftSpecificLLVMOptzns) {
     ModulePasses.add(createSwiftAAWrapperPass());
     ModulePasses.add(createExternalAAWrapperPass([](Pass &P, Function &,
                                                     AAResults &AAR) {
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index c562573..34c5b78 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -48,13 +48,14 @@
 class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
   ArrayRef<uint8_t> ChildIndices;
   bool ParentIsOptional;
+  bool IsFunctionTypeArgument;
 
 public:
-  ChildIndexFinder(ArrayRef<uint8_t> ChildIndices) :
-    ChildIndices(ChildIndices) {}
+  ChildIndexFinder(ArrayRef<uint8_t> ChildIndices)
+      : ChildIndices(ChildIndices), ParentIsOptional(false),
+        IsFunctionTypeArgument(false) {}
 
   FoundResult findChild(AbstractFunctionDecl *Parent) {
-    ParentIsOptional = false;
     auto NextIndex = consumeNext();
     if (!NextIndex) {
       if (auto Func = dyn_cast<FuncDecl>(Parent))
@@ -119,12 +120,16 @@
         Parent->getSourceRange(),
         Optional, Suffixable, /*Suffixed=*/ParentIsOptional
       };
+
     auto NextIndex = consumeNext();
     if (isUserTypeAlias(Parent))
       return {SourceRange(), false, false, false};
+
     assert(NextIndex < Children.size());
     TypeRepr *Child = Children[NextIndex];
     ParentIsOptional = Optional;
+    IsFunctionTypeArgument = NextIndex == 1 && isa<FunctionTypeRepr>(Parent);
+
     return visit(Child);
   }
 
@@ -174,12 +179,14 @@
   }
 
   FoundResult visitTupleTypeRepr(TupleTypeRepr *T) {
-    // Single element TupleTypeReprs may be arbitrarily nested so don't count
-    // as their own index level
-    if (T->getNumElements() == 1) {
+    // Paren TupleTypeReprs may be arbitrarily nested so don't count as their
+    // own index level except in the case of function type argument parens
+    if (T->isParenType() && !IsFunctionTypeArgument) {
       ParentIsOptional = false;
       return visit(T->getElementType(0));
     }
+
+    IsFunctionTypeArgument = false;
     llvm::SmallVector<TypeRepr *, 8> Children;
     T->getElementTypes(Children);
     return handleParent(T, ArrayRef<TypeRepr *>(Children));
diff --git a/test/Migrator/Inputs/API.json b/test/Migrator/Inputs/API.json
index ced8682..0e9d6ee 100644
--- a/test/Migrator/Inputs/API.json
+++ b/test/Migrator/Inputs/API.json
@@ -518,4 +518,15 @@
     "NewPrintedName": "newName(is:at:for:)",
     "NewTypeName": "AwesomeWrapper"
   },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:1:0:0:0",
+    "LeftUsr": "s:6Cities12ToplevelTypeC6memberyyySayypGSgcF",
+    "LeftComment": "Any",
+    "RightUsr": "",
+    "RightComment": "Int",
+    "ModuleName": "Cities"
+  }
 ]
diff --git a/test/Migrator/Inputs/Cities.swift b/test/Migrator/Inputs/Cities.swift
index 78734b0..99ef562 100644
--- a/test/Migrator/Inputs/Cities.swift
+++ b/test/Migrator/Inputs/Cities.swift
@@ -55,9 +55,10 @@
   public func getOptionalSingleAttr() -> String? { return nil }
 }
 
-public class ToplevelType {
+open class ToplevelType {
   public init() {}
   public init(recordName: String) {}
+  open func member(_ x: @escaping ([Any]?) -> Void) {}
 }
 
 public var GlobalAttribute: String = ""
diff --git a/test/Migrator/rename-func-decl.swift b/test/Migrator/rename-func-decl.swift
index 137e55f..3d4c943 100644
--- a/test/Migrator/rename-func-decl.swift
+++ b/test/Migrator/rename-func-decl.swift
@@ -10,3 +10,11 @@
   func setZooLocation(x ix: Int, y iy: Int, z iz: Int) {}
   func addZooAt(_ x: Int, y: Int, z: Int) {}
 }
+
+class MySubTopLevelType: ToplevelType {
+  override func member(_ x: @escaping ([Any]?) -> Void) {}
+}
+
+class MySubTopLevelType2: ToplevelType {
+  override func member(_ x: @escaping (((([(Any)])?))) -> Void) {}
+}
diff --git a/test/Migrator/rename-func-decl.swift.expected b/test/Migrator/rename-func-decl.swift.expected
index 38022e7..5c7e94a 100644
--- a/test/Migrator/rename-func-decl.swift.expected
+++ b/test/Migrator/rename-func-decl.swift.expected
@@ -10,3 +10,11 @@
   func setZooLocationNew(newX ix: Int, newY iy: Int, newZ iz: Int) {}
   func addNewZooAt(_ x: Int, newY y: Int, newZ z: Int) {}
 }
+
+class MySubTopLevelType: ToplevelType {
+  override func member(_ x: @escaping ([Int]?) -> Void) {}
+}
+
+class MySubTopLevelType2: ToplevelType {
+  override func member(_ x: @escaping (((([(Int)])?))) -> Void) {}
+}
diff --git a/utils/swift-autocomplete.bash b/utils/swift-autocomplete.bash
index d422e33..7e48fd7 100644
--- a/utils/swift-autocomplete.bash
+++ b/utils/swift-autocomplete.bash
@@ -20,7 +20,7 @@
     # Don't know how to get the help for llvm options automatically.
     # So we use a grep'ed static list.
     COMPREPLY=( $(compgen -W "\
-      -disable-llvm-arc-opts \
+      -disable-swift-specific-llvm-optzns \
       -stack-promotion-limit \
       -view-cfg-max-columns \
       -view-cfg-long-line-behavior \