Skip to content

Commit

Permalink
Mangle the generic signature of a constrained extension after the con…
Browse files Browse the repository at this point in the history
…taining module.

A microoptimization; since the module is likely to come up often in the subsequent mangling, we want to make it more likely to get the coveted S_ substitution.

Swift SVN r32784
  • Loading branch information
jckarter committed Oct 20, 2015
1 parent 270e700 commit b77ea5e
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 24 deletions.
4 changes: 3 additions & 1 deletion docs/ABI.rst
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ Declaration Contexts
module ::= identifier // module name
module ::= known-module // abbreviation
extension ::= 'E' module entity
extension ::= 'e' module generic-signature entity

These manglings identify the enclosing context in which an entity was declared,
such as its enclosing module, function, or nominal type.
Expand All @@ -872,7 +873,8 @@ An ``extension`` mangling is used whenever an entity's declaration context is
an extension *and* the entity being extended is in a different module. In this
case the extension's module is mangled first, followed by the entity being
extended. If the extension and the extended entity are in the same module, the
plain ``entity`` mangling is preferred.
plain ``entity`` mangling is preferred. If the extension is constrained, the
constraints on the extension are mangled in its generic signature.

When mangling the context of a local entity within a constructor or
destructor, the non-allocating or non-deallocating variant is used.
Expand Down
9 changes: 4 additions & 5 deletions lib/AST/Mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,13 @@ void Mangler::mangleContext(const DeclContext *ctx, BindGenerics shouldBind) {
auto sig = ExtD->getGenericSignature();
// If the extension is constrained, mangle the generic signature that
// constrains it.
if (sig && ExtD->isConstrainedExtension()) {
Buffer << 'e';
bool mangleSignature = sig && ExtD->isConstrainedExtension();
Buffer << (mangleSignature ? 'e' : 'E');
mangleModule(ExtD->getParentModule());
if (mangleSignature) {
Mod = ExtD->getModuleContext();
mangleGenericSignature(sig, ResilienceExpansion::Minimal);
} else {
Buffer << 'E';
}
mangleModule(ExtD->getParentModule());
}
mangleNominalType(decl, ResilienceExpansion::Minimal, shouldBind,
ExtD->getGenericParams());
Expand Down
8 changes: 4 additions & 4 deletions lib/Basic/Demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ class Demangler {
// context ::= module
// context ::= entity
// context ::= 'E' module context (extension defined in a different module)
// context ::= 'e' generic-signature module context (generic extension)
// context ::= 'e' module context generic-signature (constrained extension)
if (!Mangled) return nullptr;
if (Mangled.nextIf('E')) {
NodePointer ext = NodeFactory::create(Node::Kind::Extension);
Expand All @@ -1158,17 +1158,17 @@ class Demangler {
}
if (Mangled.nextIf('e')) {
NodePointer ext = NodeFactory::create(Node::Kind::Extension);
NodePointer def_module = demangleModule();
if (!def_module) return nullptr;
NodePointer sig = demangleGenericSignature();
// The generic context is currently re-specified by the type mangling.
// If we ever remove 'self' from manglings, we should stop resetting the
// context here.
resetGenericContext();
if (!sig) return nullptr;
NodePointer def_module = demangleModule();
if (!def_module) return nullptr;
NodePointer type = demangleContext();
if (!type) return nullptr;

ext->addChild(def_module);
ext->addChild(type);
ext->addChild(sig);
Expand Down
4 changes: 3 additions & 1 deletion lib/Basic/Remangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1402,11 +1402,13 @@ void Remangler::mangleExtension(Node *node, EntityContext &ctx) {
assert(node->getNumChildren() == 2 || node->getNumChildren() == 3);
if (node->getNumChildren() == 3) {
Out << 'e';
mangleDependentGenericSignature(node->begin()[2].get()); // generic sig
} else {
Out << 'E';
}
mangleEntityContext(node->begin()[0].get(), ctx); // module
if (node->getNumChildren() == 3) {
mangleDependentGenericSignature(node->begin()[2].get()); // generic sig
}
mangleEntityContext(node->begin()[1].get(), ctx); // context
}

Expand Down
4 changes: 2 additions & 2 deletions test/Demangle/Inputs/manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ _TTWurGV23interface_type_mangling18GenericTypeContextq__S_18GenericWitnessTestS_
_TTWurGV23interface_type_mangling18GenericTypeContextq__S_18GenericWitnessTestS_FS1_16twoParamsAtDepthu_0_Rq_S1__fq_FTqd__1yqd_0__T_ ---> protocol witness for interface_type_mangling.GenericWitnessTest.twoParamsAtDepth <A><B, C where A: interface_type_mangling.GenericWitnessTest> (A)(B, y : C) -> () in conformance <A> interface_type_mangling.GenericTypeContext<A> : interface_type_mangling.GenericWitnessTest in interface_type_mangling
_TFC3red11BaseClassEHcfMS0_FzT1aSi_S0_ ---> red.BaseClassEH.init (red.BaseClassEH.Type)(a : Swift.Int) throws -> red.BaseClassEH
_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
_TFe27mangling_generic_extensionsRq_S_8Runcible_VS_3Foog1aSi ---> ext.mangling_generic_extensions.mangling_generic_extensions.Foo<A where A: mangling_generic_extensions.Runcible>.a.getter : Swift.Int
_TFe27mangling_generic_extensionsRq_S_8Runcible_VS_3Foog1bq_ ---> ext.mangling_generic_extensions.mangling_generic_extensions.Foo<A where A: mangling_generic_extensions.Runcible>.b.getter : A
_TTRXFo_iT__iT_zoPs9ErrorType__XFo__dT_zoPS___ ---> reabstraction thunk helper from @callee_owned (@in ()) -> (@out (), @error @owned Swift.ErrorType) to @callee_owned () -> (@unowned (), @error @owned Swift.ErrorType)
_TFE1a ---> _TFE1a
_TF21$__lldb_module_for_E0au3$E0Ps9ErrorType_ ---> $__lldb_module_for_E0.$E0.unsafeMutableAddressor : Swift.ErrorType
4 changes: 2 additions & 2 deletions test/Demangle/Inputs/simplified-manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ _TTWurGV23interface_type_mangling18GenericTypeContextq__S_18GenericWitnessTestS_
_TTWurGV23interface_type_mangling18GenericTypeContextq__S_18GenericWitnessTestS_FS1_16twoParamsAtDepthu_0_Rq_S1__fq_FTqd__1yqd_0__T_ ---> protocol witness for GenericWitnessTest.twoParamsAtDepth<A><B, C where ...>(B, y : C) -> () in conformance <A> GenericTypeContext<A>
_TFC3red11BaseClassEHcfMS0_FzT1aSi_S0_ ---> BaseClassEH.init(a : Int) throws -> BaseClassEH
_TF4red23foofSifT1ySi_FT1zSi_Si ---> foo(Int)(y : Int)(z : Int) -> Int
_TFeRq_27mangling_generic_extensions8Runcible_S_VS_3Foog1aSi ---> Foo<A where ...>.a.getter
_TFeRq_27mangling_generic_extensions8Runcible_S_VS_3Foog1bq_ ---> Foo<A where ...>.b.getter
_TFe27mangling_generic_extensionsRq_S_8Runcible_VS_3Foog1aSi ---> Foo<A where ...>.a.getter
_TFe27mangling_generic_extensionsRq_S_8Runcible_VS_3Foog1bq_ ---> Foo<A where ...>.b.getter
_TTRXFo_iT__iT_zoPs9ErrorType__XFo__dT_zoPS___ ---> thunk
_TFE1a ---> _TFE1a
2 changes: 1 addition & 1 deletion test/IRGen/same_type_constraints.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ public extension P where Foo == DefaultFoo<Self> {
}
}

// CHECK: define void @_TFeRq_21same_type_constraints1Pzqq_S0_3FooGVS_10DefaultFooq___S_S0_3foouRq_S0_zqq_S0_3FooGS1_q___fq_FT_GS1_q__
// CHECK: define void @_TFe21same_type_constraintsRq_S_1Pzqq_S0_3FooGVS_10DefaultFooq___S0_3foouRq_S0_zqq_S0_3FooGS1_q___fq_FT_GS1_q__
12 changes: 6 additions & 6 deletions test/SILGen/mangling_generic_extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ extension Foo {

extension Foo where T: Runcible {
// A constrained extension always uses the extension mangling.
// CHECK-LABEL: sil hidden @_TFeRq_27mangling_generic_extensions8Runcible_S_VS_3Foog1aSi
// CHECK-LABEL: sil hidden @_TFe27mangling_generic_extensionsRq_S_8Runcible_VS_3Foog1aSi
var a: Int { return 0 }

// CHECK-LABEL: sil hidden @_TFeRq_27mangling_generic_extensions8Runcible_S_VS_3Foog1bq_
// CHECK-LABEL: sil hidden @_TFe27mangling_generic_extensionsRq_S_8Runcible_VS_3Foog1bq_
var b: T { get { } }
}

extension Foo where T: Runcible, T.Spoon: Runcible {
// CHECK-LABEL: sil hidden @_TFeRq_27mangling_generic_extensions8Runcibleqq_S0_5SpoonS0__S_VS_3Foog1aSi
// CHECK-LABEL: sil hidden @_TFe27mangling_generic_extensionsRq_S_8Runcibleqq_S0_5SpoonS0__VS_3Foog1aSi
var a: Int { return 0 }

// CHECK-LABEL: sil hidden @_TFeRq_27mangling_generic_extensions8Runcibleqq_S0_5SpoonS0__S_VS_3Foog1bq_
// CHECK-LABEL: sil hidden @_TFe27mangling_generic_extensionsRq_S_8Runcibleqq_S0_5SpoonS0__VS_3Foog1bq_
var b: T { get { } }
}

Expand All @@ -55,7 +55,7 @@ extension Runcible {
}

extension Runcible where Self.Spoon == Self.Hat {
// CHECK-LABEL: sil hidden @_TFeRq_27mangling_generic_extensions8Runciblezqq_S0_3Hatqq_S0_5Spoon_S_S0_5runceuRq_S0_zqq_S0_3Hatqq_S0_5Spoon_fq_FT_T_
// NO-SELF-LABEL: sil hidden @_TFeRq_27mangling_generic_extensions8Runciblezqq_S0_3Hatqq_S0_5Spoon_S_S0_5runcefT_T_
// CHECK-LABEL: sil hidden @_TFe27mangling_generic_extensionsRq_S_8Runciblezqq_S0_3Hatqq_S0_5Spoon_S0_5runceuRq_S0_zqq_S0_3Hatqq_S0_5Spoon_fq_FT_T_
// NO-SELF-LABEL: sil hidden @_TFe27mangling_generic_extensionsRq_S_8Runciblezqq_S0_3Hatqq_S0_5Spoon_S0_5runcefT_T_
func runce() {}
}
4 changes: 2 additions & 2 deletions test/SILGen/protocol_extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ class ObjCInitClass {
protocol ProtoDelegatesToObjC { }

extension ProtoDelegatesToObjC where Self : ObjCInitClass {
// CHECK-LABEL: sil hidden @_TFeRdq_C19protocol_extensions13ObjCInitClassq_S_20ProtoDelegatesToObjC_S_S1_CuRdq_S0_q_S1__fMq_FT6stringSS_q_
// CHECK-LABEL: sil hidden @_TFe19protocol_extensionsRdq_CS_13ObjCInitClassq_S_20ProtoDelegatesToObjC_S1_CuRdq_S0_q_S1__fMq_FT6stringSS_q_
// CHECK: bb0([[STR:%[0-9]+]] : $String, [[SELF_META:%[0-9]+]] : $@thick Self.Type):
init(string: String) {
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box $Self
Expand All @@ -770,7 +770,7 @@ class RequiredInitClass {
protocol ProtoDelegatesToRequired { }

extension ProtoDelegatesToRequired where Self : RequiredInitClass {
// CHECK-LABEL: sil hidden @_TFeRdq_C19protocol_extensions17RequiredInitClassq_S_24ProtoDelegatesToRequired_S_S1_CuRdq_S0_q_S1__fMq_FT6stringSS_q_
// CHECK-LABEL: sil hidden @_TFe19protocol_extensionsRdq_CS_17RequiredInitClassq_S_24ProtoDelegatesToRequired_S1_CuRdq_S0_q_S1__fMq_FT6stringSS_q_
// CHECK: bb0([[STR:%[0-9]+]] : $String, [[SELF_META:%[0-9]+]] : $@thick Self.Type):
init(string: String) {
// CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box $Self
Expand Down

0 comments on commit b77ea5e

Please sign in to comment.