Skip to content

Commit

Permalink
Mangler: Include the error result of SILFunctionTypes in their mangling.
Browse files Browse the repository at this point in the history
Fixes a mangling collision when e.g. reabstraction thunks for T -> U and T throws -> U are needed in the same module.

Swift SVN r29362
  • Loading branch information
jckarter committed Jun 10, 2015
1 parent 6e9ffc7 commit 7388b56
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/ABI.rst
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ which are juxtaposed and terminated with a trailing underscore.
impl-convention ::= 'l' // indirect, inout
impl-convention ::= 'G' // indirect, guaranteed
impl-convention ::= 'o' // direct, ownership transfer
impl-convention ::= 'z' impl-convention // error result
impl-function-attribute ::= 'Cb' // compatible with C block invocation function
impl-function-attribute ::= 'Cc' // compatible with C global function
impl-function-attribute ::= 'Cm' // compatible with Swift method
Expand Down
1 change: 1 addition & 0 deletions include/swift/Basic/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ NODE(ImplFunctionType)
CONTEXT_NODE(ImplicitClosure)
NODE(ImplParameter)
NODE(ImplResult)
NODE(ImplErrorResult)
NODE(InOut)
NODE(InfixOperator)
CONTEXT_NODE(Initializer)
Expand Down
8 changes: 8 additions & 0 deletions lib/AST/Mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ void Mangler::mangleType(Type type, ResilienceExpansion explosion,
// <impl-convention> ::= 'l' // indirect, inout
// <impl-convention> ::= 'g' // direct, guaranteed
// <impl-convention> ::= 'G' // indirect, guaranteed
// <impl-convention> ::= 'z' <impl-convention> // error result
// <impl-function-attribute> ::= 'Cb' // block invocation function
// <impl-function-attribute> ::= 'Cc' // C global function
// <impl-function-attribute> ::= 'Cm' // Swift method
Expand Down Expand Up @@ -1064,6 +1065,13 @@ void Mangler::mangleType(Type type, ResilienceExpansion explosion,
Buffer << mangleResultConvention(result.getConvention());
mangleType(result.getType(), ResilienceExpansion::Minimal, 0);
}

if (fn->hasErrorResult()) {
auto error = fn->getErrorResult();
Buffer << 'z' << mangleResultConvention(error.getConvention());
mangleType(error.getType(), ResilienceExpansion::Minimal, 0);
}

Buffer << '_';
return;
}
Expand Down
19 changes: 17 additions & 2 deletions lib/Basic/Demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//===---------------------------------------------------------------------===//

#include "swift/Basic/Demangle.h"
#include "swift/Basic/Fallthrough.h"
#include "swift/Strings.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Punycode.h"
Expand Down Expand Up @@ -2113,10 +2114,18 @@ class Demangler {
}

NodePointer demangleImplParameterOrResult(Node::Kind kind) {
if (Mangled.nextIf('z')) {
// Only valid for a result.
if (kind != Node::Kind::ImplResult)
return nullptr;
kind = Node::Kind::ImplErrorResult;
}

auto getContext = [](Node::Kind kind) -> ImplConventionContext {
if (kind == Node::Kind::ImplParameter)
return ImplConventionContext::Parameter;
else if (kind == Node::Kind::ImplResult)
else if (kind == Node::Kind::ImplResult
|| kind == Node::Kind::ImplErrorResult)
return ImplConventionContext::Result;
else
unreachable("unexpected node kind");
Expand All @@ -2131,6 +2140,7 @@ class Demangler {
node->addChild(NodeFactory::create(Node::Kind::ImplConvention,
convention));
node->addChild(type);

return node;
}
};
Expand Down Expand Up @@ -2310,6 +2320,7 @@ class NodePrinter {
case Node::Kind::ImplicitClosure:
case Node::Kind::ImplParameter:
case Node::Kind::ImplResult:
case Node::Kind::ImplErrorResult:
case Node::Kind::InOut:
case Node::Kind::InfixOperator:
case Node::Kind::Initializer:
Expand Down Expand Up @@ -2511,7 +2522,8 @@ class NodePrinter {
if (curState == Inputs) Printer << ", ";
transitionTo(Inputs);
print(child);
} else if (child->getKind() == Node::Kind::ImplResult) {
} else if (child->getKind() == Node::Kind::ImplResult
|| child->getKind() == Node::Kind::ImplErrorResult) {
if (curState == Results) Printer << ", ";
transitionTo(Results);
print(child);
Expand Down Expand Up @@ -3369,6 +3381,9 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
case Node::Kind::ImplFunctionAttribute:
Printer << pointer->getText();
return;
case Node::Kind::ImplErrorResult:
Printer << "@error ";
SWIFT_FALLTHROUGH;
case Node::Kind::ImplParameter:
case Node::Kind::ImplResult:
printChildren(pointer, " ");
Expand Down
6 changes: 6 additions & 0 deletions lib/Basic/Remangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,12 @@ void Remangler::mangleImplParameter(Node *node) {
mangleChildNodes(node); // impl convention, type
}

void Remangler::mangleImplErrorResult(Node *node) {
assert(node->getNumChildren() == 2);
Out << 'z';
mangleChildNodes(node); // impl convention, type
}

void Remangler::mangleImplResult(Node *node) {
assert(node->getNumChildren() == 2);
mangleChildNodes(node); // impl convention, type
Expand Down
1 change: 1 addition & 0 deletions test/Demangle/Inputs/manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,4 @@ _TFC3red11BaseClassEHcfMS0_FzT1aSi_S0_ ---> red.BaseClassEH.init (red.BaseClassE
_TF4red23foofSifT1ySi_FT1zSi_Si ---> red2.foo (Swift.Int)(y : Swift.Int)(z : Swift.Int) -> Swift.Int
_TFeRq_27mangling_generic_extensions8Runcible_S_VS_3Foog1aSi ---> ext.mangling_generic_extensions.mangling_generic_extensions.Foo<A where A: mangling_generic_extensions.Runcible>.a.getter : Swift.Int
_TFeRq_27mangling_generic_extensions8Runcible_S_VS_3Foog1bq_ ---> ext.mangling_generic_extensions.mangling_generic_extensions.Foo<A where A: mangling_generic_extensions.Runcible>.b.getter : A
_TTRXFo_iT__iT_zoPSs9ErrorType__XFo__dT_zoPS___ ---> reabstraction thunk helper from @callee_owned (@in ()) -> (@out (), @error @owned Swift.ErrorType) to @callee_owned () -> (@unowned (), @error @owned Swift.ErrorType)
2 changes: 1 addition & 1 deletion test/SILGen/errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func create<T>(fn: () throws -> T) throws -> T {
func testThunk(fn: () throws -> Int) throws -> Int {
return try create(fn)
}
// CHECK-LABEL: sil shared [transparent] [thunk] @_TTRXFo__dSi_XFo__iSi_ : $@convention(thin) (@out Int, @owned @callee_owned () -> (Int, @error ErrorType)) -> @error ErrorType
// CHECK-LABEL: sil shared [transparent] [thunk] @_TTRXFo__dSizoPSs9ErrorType__XFo__iSizoPS___ : $@convention(thin) (@out Int, @owned @callee_owned () -> (Int, @error ErrorType)) -> @error ErrorType
// CHECK: bb0(%0 : $*Int, %1 : $@callee_owned () -> (Int, @error ErrorType)):
// CHECK: try_apply %1()
// CHECK: bb1([[T0:%.*]] : $Int):
Expand Down
8 changes: 8 additions & 0 deletions test/SILGen/reabstract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ func test0() {
// CHECK-NEXT: store [[T1]] to %0
// CHECK-NEXT: tuple ()
// CHECK-NEXT: return

// CHECK-LABEL: sil hidden @_TF10reabstract10testThrowsFP_T_
// CHECK: function_ref @_TTRXFo_iT__iT__XFo__dT__
// CHECK: function_ref @_TTRXFo_iT__iT_zoPSs9ErrorType__XFo__dT_zoPS___
func testThrows(x: Any) {
_ = x as? () -> ()
_ = x as? () throws -> ()
}

0 comments on commit 7388b56

Please sign in to comment.