Merge pull request #16701 from adrian-prantl/40258813

diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 9104761..8b0561a 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -3332,7 +3332,8 @@
   FunctionPointer witnessFnPtr(witness, sig);
 
   // Call the accessor.
-  assert((!IGF.IGM.DebugInfo || IGF.Builder.getCurrentDebugLocation()) &&
+  assert((!IGF.IGM.DebugInfo || IGF.Builder.getCurrentDebugLocation() ||
+          !IGF.CurFn->getSubprogram()) &&
          "creating a function call without a debug location");
   auto call = IGF.Builder.CreateCall(witnessFnPtr,
                                      { request.get(IGF),
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index 5dbb981..f413d1c 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -286,6 +286,9 @@
 
     auto L = decodeDebugLoc(CS->Loc);
     auto Scope = getOrCreateScope(CS->Parent.dyn_cast<const SILDebugScope *>());
+    // Pretend transparent functions don't exist.
+    if (!Scope)
+      return createInlinedAt(CS);
     auto InlinedAt =
         llvm::DebugLoc::get(L.Line, L.Column, Scope, createInlinedAt(CS));
     InlinedAtCache.insert(
@@ -1563,7 +1566,7 @@
 
   SILLocation::DebugLoc L;
   SILFunction *Fn = DS->getInlinedFunction();
-  if (Fn && Fn->isThunk()) {
+  if (Fn && (Fn->isThunk() || Fn->isTransparent())) {
     L = SILLocation::getCompilerGeneratedDebugLoc();
   } else if (DS == LastScope && Loc.isAutoGenerated()) {
     // Reuse the last source location if we are still in the same
@@ -1735,6 +1738,7 @@
   // Some IRGen-generated helper functions don't have a corresponding
   // SIL function, hence the dyn_cast.
   auto *SILFn = DS ? DS->Parent.dyn_cast<SILFunction *>() : nullptr;
+
   StringRef LinkageName;
   if (Fn)
     LinkageName = Fn->getName();
@@ -1754,17 +1758,18 @@
   /// The source line used for the function prologue.
   unsigned ScopeLine = 0;
   SILLocation::DebugLoc L;
-  if (DS && (!SILFn || (!SILFn->isBare() && !SILFn->isThunk()))) {
+  if (!DS || (SILFn && (SILFn->isBare() || SILFn->isThunk() ||
+                        SILFn->isTransparent()))) {
     // Bare functions and thunks should not have any line numbers. This
     // is especially important for shared functions like reabstraction
     // thunk helpers, where DS->Loc is an arbitrary location of whichever use
     // was emitted first.
+    L = SILLocation::getCompilerGeneratedDebugLoc();
+  } else {
     L = decodeDebugLoc(DS->Loc);
     ScopeLine = L.Line;
     if (!DS->Loc.isDebugInfoLoc())
       L = decodeSourceLoc(DS->Loc.getSourceLoc());
-  } else {
-    L = SILLocation::getCompilerGeneratedDebugLoc();
   }
 
   auto Line = L.Line;
@@ -1882,7 +1887,7 @@
   if (!DbgTy.size)
     DbgTy.size = getStorageSize(IGM.DataLayout, Storage);
 
-  auto *Scope = dyn_cast<llvm::DILocalScope>(getOrCreateScope(DS));
+  auto *Scope = dyn_cast_or_null<llvm::DILocalScope>(getOrCreateScope(DS));
   assert(Scope && "variable has no local scope");
   auto Loc = getDebugLoc(*this, VarDecl);
 
@@ -2028,13 +2033,17 @@
   if (Opts.DebugInfoKind <= IRGenDebugInfoKind::LineTables)
     return;
 
+  // Don't emit debug info in transparent functions.
+  auto *DS = IGF.getDebugScope();
+  if (!DS || DS->getInlinedFunction()->isTransparent())
+    return;
+
   auto TName = BumpAllocatedString(("$swift.type." + Name).str());
   auto DbgTy = DebugTypeInfo::getMetadata(
       getMetadataType()->getDeclaredInterfaceType().getPointer(),
       Metadata->getType(), Size(CI.getTargetInfo().getPointerWidth(0)),
       Alignment(CI.getTargetInfo().getPointerAlign(0)));
-  emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(),
-                          nullptr, TName, 0,
+  emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, DS, nullptr, TName, 0,
                           // swift.type is already a pointer type,
                           // having a shadow copy doesn't add another
                           // layer of indirection.
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index e89c624..9cbb9c1 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -1771,8 +1771,8 @@
   for (auto &I : *BB) {
     if (IGM.DebugInfo) {
       // Set the debug info location for I, if applicable.
-      SILLocation ILoc = I.getLoc();
       auto DS = I.getDebugScope();
+      SILLocation ILoc = I.getLoc();
       // Handle cleanup locations.
       if (ILoc.is<CleanupLocation>()) {
         // Cleanup locations point to the decl of the value that is
@@ -1830,9 +1830,8 @@
         emitDebugVariableRangeExtension(BB);
     }
     visit(&I);
-
   }
-  
+
   assert(Builder.hasPostTerminatorIP() && "SIL bb did not terminate block?!");
 }
 
@@ -3647,6 +3646,9 @@
   if (!IGM.DebugInfo)
     return;
 
+  if (i->getDebugScope()->getInlinedFunction()->isTransparent())
+    return;
+  
   auto VarInfo = i->getVarInfo();
   assert(VarInfo && "debug_value without debug info");
   auto SILVal = i->getOperand();
@@ -3689,6 +3691,10 @@
 void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
   if (!IGM.DebugInfo)
     return;
+
+  if (i->getDebugScope()->getInlinedFunction()->isTransparent())
+    return;
+
   VarDecl *Decl = i->getDecl();
   if (!Decl)
     return;
@@ -3968,6 +3974,9 @@
   if (!DS)
     return;
 
+  if (i->getDebugScope()->getInlinedFunction()->isTransparent())
+    return;
+  
   bool IsAnonymous = false;
   StringRef Name = getVarName(i, IsAnonymous);
 
@@ -4171,6 +4180,9 @@
                                              DbgName);
   setLoweredBox(i, boxWithAddr);
 
+  if (i->getDebugScope()->getInlinedFunction()->isTransparent())
+    return;
+  
   if (IGM.DebugInfo && Decl) {
     // FIXME: This is a workaround to not produce local variables for
     // capture list arguments like "[weak self]". The better solution
diff --git a/test/DebugInfo/autoclosure.swift b/test/DebugInfo/autoclosure.swift
index de1dfb5..e99462f 100644
--- a/test/DebugInfo/autoclosure.swift
+++ b/test/DebugInfo/autoclosure.swift
@@ -21,7 +21,7 @@
 func call_me(_ input: Int64) -> Void {
 // rdar://problem/14627460
 // An autoclosure should have a line number in the debug info and a scope line of 0.
-// CHECK-DAG: !DISubprogram({{.*}}linkageName: "$S11autoclosure7call_meyys5Int64VFSbyXKfu_",{{.*}} line: [[@LINE+3]],{{.*}} isLocal: true, isDefinition: true
+// CHECK-DAG: !DISubprogram({{.*}}linkageName: "$S11autoclosure7call_meyys5Int64VFSbyXKfu_",{{.*}} isLocal: true, isDefinition: true
 // But not in the line table.
 // CHECK-DAG: ![[DBG]] = !DILocation(line: [[@LINE+1]],
   if input != 0 &&&&& ( get_truth (input * 2 + 1) > 0 ) {
diff --git a/test/DebugInfo/generic_enum_closure.swift b/test/DebugInfo/generic_enum_closure.swift
index ffa6b19..16164a4 100644
--- a/test/DebugInfo/generic_enum_closure.swift
+++ b/test/DebugInfo/generic_enum_closure.swift
@@ -15,9 +15,8 @@
     // CHECK-SAME: !DIExpression(DW_OP_deref))
     // CHECK-DAG: store i8* %[[DYN:.*]], i8** %[[SHADOW]]
     // CHECK-DAG: %[[DYN]] = alloca i8, i{{32|64}} %
-    // CHECK: ![[T1:.*]] = !DICompositeType({{.*}}, identifier: "$S20generic_enum_closure8CErrorOrVyACQq_GD")
-    // CHECK: ![[SELF]] = !DILocalVariable(name: "self", scope:
-    // CHECK-SAME:                         type: ![[T1]])
+    // CHECK-DAG: ![[T1:.*]] = !DICompositeType({{.*}}, identifier: "$S20generic_enum_closure8CErrorOrVyACQq_GD")
+    // CHECK-DAG: ![[SELF]] = !DILocalVariable(name: "self", scope:{{.*}}, type: ![[T1]])
     value = .none
   }
 }
diff --git a/test/DebugInfo/transparent.swift b/test/DebugInfo/transparent.swift
new file mode 100644
index 0000000..3b8c7e9
--- /dev/null
+++ b/test/DebugInfo/transparent.swift
@@ -0,0 +1,29 @@
+// RUN: %target-swift-frontend %s -O -I %t -emit-ir -g -o - | %FileCheck %s
+
+func use<T>(_ t: T) {}
+
+@inline(never)
+public func noinline(_ x: Int64) -> Int64 { return x }
+
+@_transparent
+public func transparent(_ y: Int64) -> Int64 {
+  var local = y
+  return noinline(local)
+}
+
+let z = transparent(0)
+use(z)
+
+// Check that a transparent function has no debug information.
+// CHECK: define {{.*}}$S11transparentAA
+// CHECK-SAME: !dbg ![[SP:[0-9]+]]
+// CHECK-NEXT: entry:
+// CHECK-NEXT: !dbg ![[ZERO:[0-9]+]]
+// CHECK-NEXT: !dbg ![[ZERO]]
+// CHECK-NEXT: }
+
+// CHECK: ![[SP]] = {{.*}}name: "transparent"
+// CHECK-SAME: file: ![[FILE:[0-9]+]]
+// CHECK-NOT: line:
+// CHECK: ![[FILE]] = {{.*}}"<compiler-generated>"
+// CHECK: ![[ZERO]] = !DILocation(line: 0,