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,