Skip to content

Commit fee591e

Browse files
authored
Merge pull request swiftlang#12359 from xedin/ast-func-mangling-changes
Changes to AST mangling to always respect parens in function signature
2 parents ba39c7b + affbd5e commit fee591e

File tree

5 files changed

+100
-66
lines changed

5 files changed

+100
-66
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ Types
343343

344344
function-signature ::= params-type params-type throws? // results and parameters
345345

346-
params-type := type // tuple in case of multiple parameters
346+
params-type := type // tuple in case of multiple parameters or a single parameter with a single tuple type
347347
params-type := empty-list // shortcut for no parameters
348348

349349
throws ::= 'K' // 'throws' annotation on function types

include/swift/AST/ASTMangler.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,16 @@ class ASTMangler : public Mangler {
187187

188188
void appendAnyGenericType(const GenericTypeDecl *decl);
189189

190-
void appendFunctionType(AnyFunctionType *fn, bool forceSingleParam);
190+
void appendFunctionType(AnyFunctionType *fn);
191191

192-
void appendFunctionSignature(AnyFunctionType *fn, bool forceSingleParam);
192+
void appendFunctionSignature(AnyFunctionType *fn);
193193

194-
void appendParams(Type ParamsTy, bool forceSingleParam);
194+
void appendFunctionInputType(ArrayRef<AnyFunctionType::Param> params);
195+
void appendFunctionResultType(Type resultType);
195196

196197
void appendTypeList(Type listTy);
198+
void appendTypeListElement(Identifier name, Type elementType,
199+
ParameterTypeFlags flags);
197200

198201
/// Append a generic signature to the mangling.
199202
///

include/swift/AST/Types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2347,7 +2347,8 @@ class AnyFunctionType : public TypeBase {
23472347
/// FIXME(Remove InOutType): This is mostly for copying between param
23482348
/// types and should go away.
23492349
Type getPlainType() const { return Ty; }
2350-
2350+
2351+
bool hasLabel() const { return !Label.empty(); }
23512352
Identifier getLabel() const { return Label; }
23522353

23532354
ParameterTypeFlags getParameterFlags() const { return Flags; }

lib/AST/ASTMangler.cpp

Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ void ASTMangler::appendType(Type type) {
900900

901901
case TypeKind::GenericFunction: {
902902
auto genFunc = cast<GenericFunctionType>(tybase);
903-
appendFunctionType(genFunc, /*forceSingleParam*/ false);
903+
appendFunctionType(genFunc);
904904
appendGenericSignature(genFunc->getGenericSignature());
905905
appendOperator("u");
906906
return;
@@ -943,7 +943,7 @@ void ASTMangler::appendType(Type type) {
943943
}
944944

945945
case TypeKind::Function:
946-
appendFunctionType(cast<FunctionType>(tybase), /*forceSingleParam*/ false);
946+
appendFunctionType(cast<FunctionType>(tybase));
947947
return;
948948

949949
case TypeKind::SILBox: {
@@ -1438,12 +1438,11 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
14381438
addSubstitution(key.getPointer());
14391439
}
14401440

1441-
void ASTMangler::appendFunctionType(AnyFunctionType *fn,
1442-
bool forceSingleParam) {
1441+
void ASTMangler::appendFunctionType(AnyFunctionType *fn) {
14431442
assert((DWARFMangling || fn->isCanonical()) &&
14441443
"expecting canonical types when not mangling for the debugger");
14451444

1446-
appendFunctionSignature(fn, forceSingleParam);
1445+
appendFunctionSignature(fn);
14471446

14481447
// Note that we do not currently use thin representations in the AST
14491448
// for the types of function decls. This may need to change at some
@@ -1470,48 +1469,66 @@ void ASTMangler::appendFunctionType(AnyFunctionType *fn,
14701469
}
14711470
}
14721471

1473-
void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
1474-
bool forceSingleParam) {
1475-
appendParams(fn->getResult(), /*forceSingleParam*/ false);
1476-
appendParams(fn->getInput(), forceSingleParam);
1472+
void ASTMangler::appendFunctionSignature(AnyFunctionType *fn) {
1473+
appendFunctionResultType(fn->getResult());
1474+
appendFunctionInputType(fn->getParams());
14771475
if (fn->throws())
14781476
appendOperator("K");
14791477
}
14801478

1481-
void ASTMangler::appendParams(Type ParamsTy, bool forceSingleParam) {
1482-
if (TupleType *Tuple = ParamsTy->getAs<TupleType>()) {
1483-
if (Tuple->getNumElements() == 0) {
1484-
if (forceSingleParam) {
1485-
// A tuple containing a single empty tuple.
1486-
appendOperator("y");
1487-
appendOperator("t");
1488-
appendListSeparator();
1489-
appendOperator("t");
1490-
} else {
1491-
appendOperator("y");
1492-
}
1493-
return;
1479+
void ASTMangler::appendFunctionInputType(
1480+
ArrayRef<AnyFunctionType::Param> params) {
1481+
auto getParamType = [](const AnyFunctionType::Param &param) -> Type {
1482+
auto type = param.getType();
1483+
1484+
// FIXME: Change mangling for variadic parameters so
1485+
// the enclosing array type is not required.
1486+
if (param.isVariadic()) {
1487+
auto *arrayDecl = type->getASTContext().getArrayDecl();
1488+
assert(arrayDecl);
1489+
return BoundGenericType::get(arrayDecl, Type(), {type});
14941490
}
1495-
if (forceSingleParam && Tuple->getNumElements() > 1) {
1496-
auto flags = ParameterTypeFlags();
1497-
if (ParenType *Paren = dyn_cast<ParenType>(ParamsTy.getPointer())) {
1498-
ParamsTy = Paren->getUnderlyingType();
1499-
flags = Paren->getParameterFlags();
1500-
}
15011491

1502-
appendType(ParamsTy);
1503-
if (flags.isShared())
1504-
appendOperator("h");
1505-
appendListSeparator();
1506-
appendOperator("t");
1507-
return;
1492+
return type;
1493+
};
1494+
1495+
switch (params.size()) {
1496+
case 0:
1497+
appendOperator("y");
1498+
break;
1499+
1500+
case 1: {
1501+
const auto &param = params.front();
1502+
auto type = param.getType();
1503+
1504+
// If this is just a single parenthesized type,
1505+
// to save space in the mangled name, let's encode
1506+
// it as a single type dropping sugar.
1507+
if (!param.hasLabel() && !param.isVariadic() &&
1508+
!isa<TupleType>(type.getPointer())) {
1509+
appendType(type);
1510+
break;
15081511
}
1512+
1513+
// If this is a tuple type with a single labeled element
1514+
// let's handle it as a general case.
1515+
LLVM_FALLTHROUGH;
15091516
}
15101517

1511-
if (ParenType *Paren = dyn_cast<ParenType>(ParamsTy.getPointer()))
1512-
ParamsTy = Paren->getUnderlyingType();
1518+
default:
1519+
bool isFirstParam = true;
1520+
for (auto &param : params) {
1521+
appendTypeListElement(param.getLabel(), getParamType(param),
1522+
param.getParameterFlags());
1523+
appendListSeparator(isFirstParam);
1524+
}
1525+
appendOperator("t");
1526+
break;
1527+
}
1528+
}
15131529

1514-
appendType(ParamsTy);
1530+
void ASTMangler::appendFunctionResultType(Type resultType) {
1531+
return resultType->isVoid() ? appendOperator("y") : appendType(resultType);
15151532
}
15161533

15171534
void ASTMangler::appendTypeList(Type listTy) {
@@ -1520,15 +1537,8 @@ void ASTMangler::appendTypeList(Type listTy) {
15201537
return appendOperator("y");
15211538
bool firstField = true;
15221539
for (auto &field : tuple->getElements()) {
1523-
appendType(field.getType()->getInOutObjectType());
1524-
if (field.isInOut())
1525-
appendOperator("z");
1526-
if (field.getParameterFlags().isShared())
1527-
appendOperator("h");
1528-
if (field.hasName())
1529-
appendIdentifier(field.getName().str());
1530-
if (field.isVararg())
1531-
appendOperator("d");
1540+
appendTypeListElement(field.getName(), field.getType(),
1541+
field.getParameterFlags());
15321542
appendListSeparator(firstField);
15331543
}
15341544
} else {
@@ -1537,6 +1547,19 @@ void ASTMangler::appendTypeList(Type listTy) {
15371547
}
15381548
}
15391549

1550+
void ASTMangler::appendTypeListElement(Identifier name, Type elementType,
1551+
ParameterTypeFlags flags) {
1552+
appendType(elementType->getInOutObjectType());
1553+
if (flags.isInOut())
1554+
appendOperator("z");
1555+
if (flags.isShared())
1556+
appendOperator("h");
1557+
if (!name.empty())
1558+
appendIdentifier(name.str());
1559+
if (flags.isVariadic())
1560+
appendOperator("d");
1561+
}
1562+
15401563
bool ASTMangler::appendGenericSignature(const GenericSignature *sig,
15411564
GenericSignature *contextSig) {
15421565
auto canSig = sig->getCanonicalSignature();
@@ -1828,23 +1851,10 @@ void ASTMangler::appendDeclType(const ValueDecl *decl, bool isFunctionMangling)
18281851
auto type = getDeclTypeForMangling(decl, genericSig, parentGenericSig);
18291852

18301853
if (AnyFunctionType *FuncTy = type->getAs<AnyFunctionType>()) {
1831-
1832-
const ParameterList *Params = nullptr;
1833-
if (const auto *FDecl = dyn_cast<AbstractFunctionDecl>(decl)) {
1834-
unsigned PListIdx = isMethodDecl(decl) ? 1 : 0;
1835-
if (PListIdx < FDecl->getNumParameterLists()) {
1836-
Params = FDecl->getParameterList(PListIdx);
1837-
}
1838-
} else if (const auto *SDecl = dyn_cast<SubscriptDecl>(decl)) {
1839-
Params = SDecl->getIndices();
1840-
}
1841-
bool forceSingleParam = Params && (Params->size() == 1);
1842-
1843-
18441854
if (isFunctionMangling) {
1845-
appendFunctionSignature(FuncTy, forceSingleParam);
1855+
appendFunctionSignature(FuncTy);
18461856
} else {
1847-
appendFunctionType(FuncTy, forceSingleParam);
1857+
appendFunctionType(FuncTy);
18481858
}
18491859
} else {
18501860
appendType(type);

test/SILGen/arguments_as_tuple_overloads.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,30 @@ public func test(_ a: Int, _ b: Int) {
3939
public func test(_ t: (Int, Int)) {
4040
}
4141

42+
// CHECK: sil @_T04test0A7NoLabelySi_Sit_tF :
43+
public func testNoLabel(_: (Int, Int)) {
44+
}
45+
46+
// CHECK: sil @_T04test0A5FnArgyySi_SitcF :
47+
public func testFnArg(_: (Int, Int) -> Void) {
48+
}
49+
50+
// CHECK: sil @_T04test0A5FnArgyySi_Sit_tcF :
51+
public func testFnArg(_: ((Int, Int)) -> Void) {
52+
}
53+
4254
// CHECK: sil @_T04test3fooyyt_tF :
4355
public func foo(_: ()) {
4456
}
4557

4658
// CHECK: sil @_T04test3fooyyF :
4759
public func foo() {
4860
}
61+
62+
public func baz() {
63+
// CHECK: function_ref @_T04test3bazyyFySi_Sit_tcfU_ :
64+
let _: ((Int, Int)) -> Void = { x in }
65+
66+
// CHECK: function_ref @_T04test3bazyyFySi_SitcfU0_ :
67+
let _: (Int, Int) -> Void = { x, y in }
68+
}

0 commit comments

Comments
 (0)