Skip to content

Commit 6633ae0

Browse files
committed
Stop special-casing function types when constructing DebugTypeInfo objects.
Prior to this patch, debug info was storing the original swift type for function objects. This could be very wrong in optimized code. This patch stores the lowered function type in the debug info and adds the necessary type reconstruction code (tested via the LLDB testsuite) to allow reconstructing a Swift type from a mangled lowered type. <rdar://problem/28859432>
1 parent bb55c6d commit 6633ae0

File tree

4 files changed

+89
-37
lines changed

4 files changed

+89
-37
lines changed

lib/IDE/TypeReconstruction.cpp

Lines changed: 85 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,45 @@ static void VisitNodeFunction(
13581358
}
13591359
}
13601360

1361+
static void CreateFunctionType(ASTContext *ast,
1362+
const VisitNodeResult &arg_type_result,
1363+
const VisitNodeResult &return_type_result,
1364+
bool throws,
1365+
VisitNodeResult &result) {
1366+
Type arg_clang_type;
1367+
Type return_clang_type;
1368+
1369+
switch (arg_type_result._types.size()) {
1370+
case 0:
1371+
arg_clang_type = TupleType::getEmpty(*ast);
1372+
break;
1373+
case 1:
1374+
arg_clang_type = arg_type_result._types.front().getPointer();
1375+
break;
1376+
default:
1377+
result._error = "too many argument types for a function type";
1378+
break;
1379+
}
1380+
1381+
switch (return_type_result._types.size()) {
1382+
case 0:
1383+
return_clang_type = TupleType::getEmpty(*ast);
1384+
break;
1385+
case 1:
1386+
return_clang_type = return_type_result._types.front().getPointer();
1387+
break;
1388+
default:
1389+
result._error = "too many return types for a function type";
1390+
break;
1391+
}
1392+
1393+
if (arg_clang_type && return_clang_type) {
1394+
result._types.push_back(
1395+
FunctionType::get(arg_clang_type, return_clang_type,
1396+
FunctionType::ExtInfo().withThrows(throws)));
1397+
}
1398+
}
1399+
13611400
static void VisitNodeFunctionType(
13621401
ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
13631402
Demangle::NodePointer &cur_node, VisitNodeResult &result,
@@ -1395,40 +1434,52 @@ static void VisitNodeFunctionType(
13951434
break;
13961435
}
13971436
}
1398-
Type arg_clang_type;
1399-
Type return_clang_type;
1400-
1401-
switch (arg_type_result._types.size()) {
1402-
case 0:
1403-
arg_clang_type = TupleType::getEmpty(*ast);
1404-
break;
1405-
case 1:
1406-
arg_clang_type = arg_type_result._types.front().getPointer();
1407-
break;
1408-
default:
1409-
result._error = "too many argument types for a function type";
1410-
break;
1411-
}
1412-
1413-
switch (return_type_result._types.size()) {
1414-
case 0:
1415-
return_clang_type = TupleType::getEmpty(*ast);
1416-
break;
1417-
case 1:
1418-
return_clang_type = return_type_result._types.front().getPointer();
1419-
break;
1420-
default:
1421-
result._error = "too many return types for a function type";
1422-
break;
1423-
}
1437+
CreateFunctionType(ast, arg_type_result, return_type_result, throws, result);
1438+
}
14241439

1425-
if (arg_clang_type && return_clang_type) {
1426-
result._types.push_back(
1427-
FunctionType::get(arg_clang_type, return_clang_type,
1428-
FunctionType::ExtInfo().withThrows(throws)));
1440+
static void VisitNodeImplFunctionType(
1441+
ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
1442+
Demangle::NodePointer &cur_node, VisitNodeResult &result,
1443+
const VisitNodeResult &generic_context) { // set by GenericType case
1444+
VisitNodeResult arg_type_result;
1445+
VisitNodeResult return_type_result;
1446+
Demangle::Node::iterator end = cur_node->end();
1447+
bool throws = false;
1448+
for (Demangle::Node::iterator pos = cur_node->begin(); pos != end; ++pos) {
1449+
const Demangle::Node::Kind child_node_kind = (*pos)->getKind();
1450+
switch (child_node_kind) {
1451+
case Demangle::Node::Kind::Class: {
1452+
VisitNodeResult class_type_result;
1453+
nodes.push_back(*pos);
1454+
VisitNode(ast, nodes, class_type_result, generic_context);
1455+
} break;
1456+
case Demangle::Node::Kind::Structure: {
1457+
VisitNodeResult class_type_result;
1458+
nodes.push_back(*pos);
1459+
VisitNode(ast, nodes, class_type_result, generic_context);
1460+
} break;
1461+
case Demangle::Node::Kind::ImplConvention:
1462+
// Ignore the ImplConvention it is only a hint for the SIL ARC optimizer.
1463+
break;
1464+
case Demangle::Node::Kind::ImplParameter:
1465+
nodes.push_back(*pos);
1466+
VisitNode(ast, nodes, arg_type_result, generic_context);
1467+
break;
1468+
case Demangle::Node::Kind::ThrowsAnnotation:
1469+
throws = true;
1470+
break;
1471+
case Demangle::Node::Kind::ImplResult:
1472+
nodes.push_back(*pos);
1473+
VisitNode(ast, nodes, return_type_result, generic_context);
1474+
break;
1475+
default:
1476+
break;
1477+
}
14291478
}
1479+
CreateFunctionType(ast, arg_type_result, return_type_result, throws, result);
14301480
}
14311481

1482+
14321483
static void VisitNodeSetterGetter(
14331484
ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
14341485
Demangle::NodePointer &cur_node, VisitNodeResult &result,
@@ -2072,6 +2123,10 @@ static void visitNodeImpl(
20722123
VisitNodeFunctionType(ast, nodes, node, result, genericContext);
20732124
break;
20742125

2126+
case Demangle::Node::Kind::ImplFunctionType:
2127+
VisitNodeImplFunctionType(ast, nodes, node, result, genericContext);
2128+
break;
2129+
20752130
case Demangle::Node::Kind::DidSet:
20762131
case Demangle::Node::Kind::Getter:
20772132
case Demangle::Node::Kind::Setter:

lib/IRGen/DebugTypeInfo.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ DebugTypeInfo DebugTypeInfo::getLocalVariable(DeclContext *DeclCtx,
7575
// the type hasn't been mucked with by an optimization pass.
7676
auto *Type = DeclSelfType->isEqual(RealType) ? DeclType.getPointer()
7777
: RealType.getPointer();
78-
// FIXME: LLDB cannot deal with manglings that contain @owning annotations.
79-
if (DeclType->getAs<FunctionType>())
80-
Type = DeclType.getPointer();
8178
return getFromTypeInfo(DeclCtx, Type, Info);
8279
}
8380

test/DebugInfo/fnptr.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func barz(_ i: Float, _ j: Float) -> Int64 { return 0; }
1212
func main() -> Int64 {
1313
// CHECK-DAG: !DILocalVariable(name: "bar_fnptr",{{.*}} line: [[@LINE+3]],{{.*}} type: ![[BARPT:[0-9]+]]
1414
// AST-DAG: !DILocalVariable(name: "bar_fnptr",{{.*}} line: [[@LINE+2]],{{.*}} type: ![[BAR_T:[0-9]+]]
15-
// AST-DAG: ![[BAR_T]] = !DICompositeType({{.*}}, identifier: "_TtFT_T_")
15+
// AST-DAG: ![[BAR_T]] = !DICompositeType({{.*}}, identifier: "_TtXFo___")
1616
var bar_fnptr = bar
1717
// CHECK-DAG: ![[BARPT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}} elements: ![[BARMEMBERS:[0-9]+]]
1818
// CHECK-DAG: ![[BARMEMBERS]] = !{![[BARMEMBER:.*]], {{.*}}}
@@ -25,7 +25,7 @@ func main() -> Int64 {
2525

2626
// CHECK-DAG: !DILocalVariable(name: "baz_fnptr",{{.*}} type: ![[BAZPT:[0-9]+]]
2727
// AST-DAG: !DILocalVariable(name: "baz_fnptr",{{.*}} type: ![[BAZ_T:[0-9]+]]
28-
// AST-DAG: ![[BAZ_T]] = !DICompositeType({{.*}}, identifier: "_TtFSfVs5Int64")
28+
// AST-DAG: ![[BAZ_T]] = !DICompositeType({{.*}}, identifier: "_TtXFo_dSf_dVs5Int64_")
2929
// CHECK-DAG: ![[BAZPT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}} elements: ![[BAZMEMBERS:[0-9]+]]
3030
// CHECK-DAG: ![[BAZMEMBERS]] = !{![[BAZMEMBER:.*]], {{.*}}}
3131
// CHECK-DAG: ![[BAZMEMBER]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[BAZPTR:[0-9]+]]
@@ -39,7 +39,7 @@ func main() -> Int64 {
3939

4040
// CHECK-DAG: !DILocalVariable(name: "barz_fnptr",{{.*}} type: ![[BARZPT:[0-9]+]]
4141
// AST_DAG: !DILocalVariable(name: "barz_fnptr",{{.*}} type: ![[BARZ_T:[0-9]+]]
42-
// AST-DAG: ![[BARZ_T:[0-9]+]] = !DICompositeType({{.*}}, identifier: "_TtFTSfSf_Vs5Int64")
42+
// AST-DAG: ![[BARZ_T:[0-9]+]] = !DICompositeType({{.*}}, identifier: "_TtXFo_dSfdSf_dVs5Int64_")
4343
// CHECK-DAG: ![[BARZPT]] = !DICompositeType(tag: DW_TAG_structure_type,{{.*}} elements: ![[BARZMEMBERS:[0-9]+]]
4444
// CHECK-DAG: ![[BARZMEMBERS]] = !{![[BARZMEMBER:.*]], {{.*}}}
4545
// CHECK-DAG: ![[BARZMEMBER]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[BARZPTR:[0-9]+]]

test/DebugInfo/generic_args.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct Wrapper<T: AProtocol> {
4545
}
4646
}
4747

48-
// CHECK-DAG: ![[FNTY:.*]] = !DICompositeType({{.*}}identifier: "_TtFQq_F12generic_args5applyu0_rFTx1fFxq__q_Qq0_F12generic_args5applyu0_rFTx1fFxq__q_"
48+
// CHECK-DAG: ![[FNTY:.*]] = !DICompositeType({{.*}}identifier: "_TtXFo_iQq_F12generic_args5applyu0_rFTx1fFxq__q__iQq0_F12generic_args5applyu0_rFTx1fFxq__q__"
4949
// CHECK-DAG: !DILocalVariable(name: "f", {{.*}}, line: [[@LINE+1]], type: ![[FNTY]])
5050
func apply<T, U> (_ x: T, f: (T) -> (U)) -> U {
5151
return f(x)

0 commit comments

Comments
 (0)