Skip to content

Commit d39c7f2

Browse files
committed
Reflection: Eliminate NominalTypeTrait::setParent()
When creating a TypeRef from metadata, we have a parent pointer handy, and construct the TypeRef directly, so there's no need to mutate the TypeRef after the fact. When demangling a TypeRef from a string, the mangling encodes the parent module or type context, so we can set it when constructing the TypeRef there too.
1 parent d998fda commit d39c7f2

File tree

5 files changed

+87
-27
lines changed

5 files changed

+87
-27
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,15 @@ class ReflectionContext {
116116
return BuiltinTypeRef::create(*this, mangledName);
117117
}
118118

119-
NominalTypeRef *createNominalType(const std::string &mangledName) {
120-
return NominalTypeRef::create(*this, mangledName);
119+
NominalTypeRef *createNominalType(const std::string &mangledName,
120+
TypeRef *parent) {
121+
return NominalTypeRef::create(*this, mangledName, parent);
121122
}
122123

123124
BoundGenericTypeRef *createBoundGenericType(const std::string &mangledName,
124-
const std::vector<TypeRef *> &args) {
125-
return BoundGenericTypeRef::create(*this, mangledName, args);
125+
const std::vector<TypeRef *> &args,
126+
TypeRef *parent) {
127+
return BoundGenericTypeRef::create(*this, mangledName, args, parent);
126128
}
127129

128130
TupleTypeRef *createTupleType(const std::vector<TypeRef *> &elements,
@@ -270,6 +272,28 @@ class ReflectionContext {
270272
return *Reader;
271273
}
272274

275+
std::pair<std::string, Type>
276+
decodeNominalType(const Demangle::NodePointer &Node) {
277+
using NodeKind = Demangle::Node::Kind;
278+
if (Node->getKind() == NodeKind::Type)
279+
return decodeNominalType(Node->getChild(0));
280+
281+
assert(Node->getNumChildren() == 2);
282+
auto moduleOrParentType = Node->getChild(0);
283+
284+
// Nested types are handled a bit funny here because a
285+
// nominal typeref always stores its full mangled name,
286+
// in addition to a reference to the parent type. The
287+
// mangled name already includes the module and parent
288+
// types, if any.
289+
TypeRef *parent = nullptr;
290+
if (moduleOrParentType->getKind() != NodeKind::Module)
291+
parent = decodeMangledType(moduleOrParentType);
292+
293+
auto mangledName = Demangle::mangleNode(Node);
294+
return std::make_pair(mangledName, parent);
295+
}
296+
273297
Type decodeMangledType(const Demangle::NodePointer &Node) {
274298
using NodeKind = Demangle::Node::Kind;
275299
switch (Node->getKind()) {
@@ -279,26 +303,38 @@ class ReflectionContext {
279303
return decodeMangledType(Node->getChild(0));
280304
case NodeKind::Type:
281305
return decodeMangledType(Node->getChild(0));
306+
case NodeKind::Class:
307+
case NodeKind::Enum:
308+
case NodeKind::Structure: {
309+
std::string mangledName;
310+
Type parent;
311+
312+
std::tie(mangledName, parent) = decodeNominalType(Node);
313+
return Builder.createNominalType(mangledName, parent);
314+
}
282315
case NodeKind::BoundGenericClass:
283316
case NodeKind::BoundGenericEnum:
284317
case NodeKind::BoundGenericStructure: {
285-
auto mangledName = Demangle::mangleNode(Node->getChild(0));
318+
assert(Node->getNumChildren() == 2);
319+
320+
std::string mangledName;
321+
Type parent;
322+
323+
std::tie(mangledName, parent) = decodeNominalType(Node->getChild(0));
324+
325+
std::vector<Type> args;
326+
286327
auto genericArgs = Node->getChild(1);
287-
std::vector<TypeRef *> args;
328+
assert(genericArgs->getKind() == NodeKind::TypeList);
329+
288330
for (auto genericArg : *genericArgs) {
289-
auto paramTypeRef = decodeMangledType(genericArg);
290-
if (!paramTypeRef)
331+
auto paramType = decodeMangledType(genericArg);
332+
if (!paramType)
291333
return Type();
292-
args.push_back(paramTypeRef);
334+
args.push_back(paramType);
293335
}
294336

295-
return Builder.createBoundGenericType(mangledName, args);
296-
}
297-
case NodeKind::Class:
298-
case NodeKind::Enum:
299-
case NodeKind::Structure: {
300-
auto mangledName = Demangle::mangleNode(Node);
301-
return Builder.createNominalType(mangledName);
337+
return Builder.createBoundGenericType(mangledName, args, parent);
302338
}
303339
case NodeKind::BuiltinTypeName: {
304340
auto mangledName = Demangle::mangleNode(Node);
@@ -724,14 +760,9 @@ class ReflectionContext {
724760
Type Nominal;
725761
if (Descriptor->GenericParams.NumPrimaryParams) {
726762
auto Args = getGenericSubst(MetadataAddress);
727-
auto BG = Builder.createBoundGenericType(MangledName, Args);
728-
BG->setParent(Parent);
729-
Nominal = BG;
763+
Nominal = Builder.createBoundGenericType(MangledName, Args, Parent);
730764
} else {
731-
auto TR = decodeMangledType(DemangleNode);
732-
auto N = cast<NominalTypeRef>(TR);
733-
N->setParent(Parent);
734-
Nominal = TR;
765+
Nominal = decodeMangledType(DemangleNode);
735766
}
736767
TypeCache.insert({MetadataAddress, Nominal});
737768
return Nominal;

include/swift/Reflection/TypeRef.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,6 @@ class NominalTypeTrait {
117117
return Parent;
118118
}
119119

120-
void setParent(TypeRef *P) {
121-
Parent = P;
122-
}
123-
124120
unsigned getDepth() const;
125121
};
126122

test/Reflection/Inputs/ConcreteTypes.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public struct S {
3737
public let aTuple: (C, Box<S>, Box<E>, Int)
3838
public let aMetatype: C.Type
3939
public let aFunction: (C, S, E, Int) -> (Int)
40+
41+
public struct NestedS {
42+
public let aField: Int
43+
}
4044
}
4145

4246
public enum E {
@@ -47,6 +51,7 @@ public enum E {
4751
case Tuple(C, S, Int)
4852
indirect case IndirectTuple(C, S, E, Int)
4953
case Metatype(E.Type)
54+
case NestedStruct(S.NestedS)
5055
}
5156

5257
public struct References {

test/Reflection/typeref_decoding.result.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ aFunctionWithVarArgs: (TypesToReflect.C, Swift.Array<TypesToReflect.S>...) -> ()
4848
(struct TypesToReflect.S))
4949
(tuple))
5050

51+
TypesToReflect.S.NestedS
52+
------------------------
53+
aField: Swift.Int
54+
(struct Swift.Int)
55+
5156
TypesToReflect.S
5257
----------------
5358
aClass: TypesToReflect.C
@@ -151,6 +156,15 @@ Metatype: (TypesToReflect.E.Type) -> (TypesToReflect.E.Type) -> TypesToReflect.E
151156
(enum TypesToReflect.E))
152157
(enum TypesToReflect.E)))
153158

159+
NestedStruct: (TypesToReflect.E.Type) -> (TypesToReflect.S.NestedS) -> TypesToReflect.E
160+
(function
161+
(metatype
162+
(enum TypesToReflect.E))
163+
(function
164+
(struct TypesToReflect.S.NestedS
165+
(struct TypesToReflect.S))
166+
(enum TypesToReflect.E)))
167+
154168
TypesToReflect.References
155169
-------------------------
156170
strongRef: TypesToReflect.C

test/Reflection/typeref_decoding_objc.result.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ aFunctionWithVarArgs: (TypesToReflect.C, Swift.Array<TypesToReflect.S>...) -> ()
4848
(struct TypesToReflect.S))
4949
(tuple))
5050

51+
TypesToReflect.S.NestedS
52+
------------------------
53+
aField: Swift.Int
54+
(struct Swift.Int)
55+
5156
TypesToReflect.S
5257
----------------
5358
aClass: TypesToReflect.C
@@ -151,6 +156,15 @@ Metatype: (TypesToReflect.E.Type) -> (TypesToReflect.E.Type) -> TypesToReflect.E
151156
(enum TypesToReflect.E))
152157
(enum TypesToReflect.E)))
153158

159+
NestedStruct: (TypesToReflect.E.Type) -> (TypesToReflect.S.NestedS) -> TypesToReflect.E
160+
(function
161+
(metatype
162+
(enum TypesToReflect.E))
163+
(function
164+
(struct TypesToReflect.S.NestedS
165+
(struct TypesToReflect.S))
166+
(enum TypesToReflect.E)))
167+
154168
TypesToReflect.References
155169
-------------------------
156170
strongRef: TypesToReflect.C

0 commit comments

Comments
 (0)