Skip to content

Commit 13a50c2

Browse files
committed
ASTDemangler: Add support for lowered metatypes
1 parent fce9339 commit 13a50c2

File tree

9 files changed

+83
-30
lines changed

9 files changed

+83
-30
lines changed

include/swift/AST/ASTDemangler.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ class ASTBuilder {
8686
Type superclass,
8787
bool isClassBound);
8888

89-
Type createExistentialMetatypeType(Type instance);
89+
Type createExistentialMetatypeType(Type instance,
90+
Optional<Demangle::ImplMetatypeRepresentation> repr=None);
9091

91-
Type createMetatypeType(Type instance, bool wasAbstract=false);
92+
Type createMetatypeType(Type instance,
93+
Optional<Demangle::ImplMetatypeRepresentation> repr=None);
9294

9395
Type createGenericTypeParameterType(unsigned depth, unsigned index);
9496

include/swift/Demangling/TypeDecoder.h

+18-10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
namespace swift {
2929
namespace Demangle {
3030

31+
enum class ImplMetatypeRepresentation {
32+
Thin,
33+
Thick,
34+
ObjC,
35+
};
36+
3137
/// Describe a function parameter, parameterized on the type
3238
/// representation.
3339
template <typename BuiltType>
@@ -243,18 +249,22 @@ class TypeDecoder {
243249
case NodeKind::Metatype:
244250
case NodeKind::ExistentialMetatype: {
245251
unsigned i = 0;
246-
bool wasAbstract = false;
252+
Optional<ImplMetatypeRepresentation> repr;
247253

248254
// Handle lowered metatypes in a hackish way. If the representation
249255
// was not thin, force the resulting typeref to have a non-empty
250256
// representation.
251257
if (Node->getNumChildren() >= 2) {
252-
auto repr = Node->getChild(i++);
253-
if (repr->getKind() != NodeKind::MetatypeRepresentation ||
254-
!repr->hasText())
258+
auto reprNode = Node->getChild(i++);
259+
if (reprNode->getKind() != NodeKind::MetatypeRepresentation ||
260+
!reprNode->hasText())
255261
return BuiltType();
256-
if (repr->getText() != "@thin")
257-
wasAbstract = true;
262+
if (reprNode->getText() == "@thin")
263+
repr = ImplMetatypeRepresentation::Thin;
264+
else if (reprNode->getText() == "@thick")
265+
repr = ImplMetatypeRepresentation::Thick;
266+
else if (reprNode->getText() == "@objc_metatype")
267+
repr = ImplMetatypeRepresentation::ObjC;
258268
} else if (Node->getNumChildren() < 1) {
259269
return BuiltType();
260270
}
@@ -263,11 +273,9 @@ class TypeDecoder {
263273
if (!instance)
264274
return BuiltType();
265275
if (Node->getKind() == NodeKind::Metatype) {
266-
return Builder.createMetatypeType(instance, wasAbstract);
276+
return Builder.createMetatypeType(instance, repr);
267277
} else if (Node->getKind() == NodeKind::ExistentialMetatype) {
268-
// FIXME: Ignore representation of existential metatype
269-
// completely for now
270-
return Builder.createExistentialMetatypeType(instance);
278+
return Builder.createExistentialMetatypeType(instance, repr);
271279
} else {
272280
assert(false);
273281
return nullptr;

include/swift/Reflection/TypeRefBuilder.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,14 @@ class TypeRefBuilder {
295295
}
296296

297297
const ExistentialMetatypeTypeRef *
298-
createExistentialMetatypeType(const TypeRef *instance) {
298+
createExistentialMetatypeType(const TypeRef *instance,
299+
Optional<Demangle::ImplMetatypeRepresentation> repr=None) {
299300
return ExistentialMetatypeTypeRef::create(*this, instance);
300301
}
301302

302303
const MetatypeTypeRef *createMetatypeType(const TypeRef *instance,
303-
bool WasAbstract = false) {
304+
Optional<Demangle::ImplMetatypeRepresentation> repr=None) {
305+
bool WasAbstract = (repr && *repr != ImplMetatypeRepresentation::Thin);
304306
return MetatypeTypeRef::create(*this, instance, WasAbstract);
305307
}
306308

lib/AST/ASTDemangler.cpp

+24-6
Original file line numberDiff line numberDiff line change
@@ -325,17 +325,35 @@ Type ASTBuilder::createProtocolCompositionType(
325325
return ProtocolCompositionType::get(Ctx, members, isClassBound);
326326
}
327327

328-
Type ASTBuilder::createExistentialMetatypeType(Type instance) {
328+
static MetatypeRepresentation
329+
getMetatypeRepresentation(ImplMetatypeRepresentation repr) {
330+
switch (repr) {
331+
case Demangle::ImplMetatypeRepresentation::Thin:
332+
return MetatypeRepresentation::Thin;
333+
case Demangle::ImplMetatypeRepresentation::Thick:
334+
return MetatypeRepresentation::Thick;
335+
case Demangle::ImplMetatypeRepresentation::ObjC:
336+
return MetatypeRepresentation::ObjC;
337+
}
338+
}
339+
340+
Type ASTBuilder::createExistentialMetatypeType(Type instance,
341+
Optional<Demangle::ImplMetatypeRepresentation> repr) {
329342
if (!instance->isAnyExistentialType())
330343
return Type();
331-
return ExistentialMetatypeType::get(instance);
344+
if (!repr)
345+
return ExistentialMetatypeType::get(instance);
346+
347+
return ExistentialMetatypeType::get(instance,
348+
getMetatypeRepresentation(*repr));
332349
}
333350

334351
Type ASTBuilder::createMetatypeType(Type instance,
335-
bool wasAbstract) {
336-
// FIXME: Plumb through metatype representation and generalize silly
337-
// 'wasAbstract' flag
338-
return MetatypeType::get(instance);
352+
Optional<Demangle::ImplMetatypeRepresentation> repr) {
353+
if (!repr)
354+
return MetatypeType::get(instance);
355+
356+
return MetatypeType::get(instance, getMetatypeRepresentation(*repr));
339357
}
340358

341359
Type ASTBuilder::createGenericTypeParameterType(unsigned depth,

stdlib/public/runtime/MetadataLookup.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1100,11 +1100,13 @@ class DecodedMetadataBuilder {
11001100
return BuiltType();
11011101
}
11021102

1103-
BuiltType createMetatypeType(BuiltType instance, bool wasAbstract) const {
1103+
BuiltType createMetatypeType(BuiltType instance,
1104+
Optional<Demangle::ImplMetatypeRepresentation> repr=None) const {
11041105
return swift_getMetatypeMetadata(instance);
11051106
}
11061107

1107-
BuiltType createExistentialMetatypeType(BuiltType instance) const {
1108+
BuiltType createExistentialMetatypeType(BuiltType instance,
1109+
Optional<Demangle::ImplMetatypeRepresentation> repr=None) const {
11081110
return swift_getExistentialMetatypeMetadata(instance);
11091111
}
11101112

test/TypeDecoder/dynamic_self.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ class Me {
1414
}
1515

1616
// DEMANGLE: $s12dynamic_self2MeCXDXMTD
17-
// CHECK: Self.Type
17+
// CHECK: @thick Self.Type
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-build-swift -emit-executable %s -g -o %t/lowered_metatypes -emit-module
4+
// RUN: sed -ne '/\/\/ *DEMANGLE: /s/\/\/ *DEMANGLE: *//p' < %s > %t/input
5+
// RUN: %lldb-moduleimport-test %t/lowered_metatypes -type-from-mangled=%t/input | %FileCheck %s
6+
7+
struct Struct {}
8+
class Class {}
9+
protocol Proto {}
10+
11+
// DEMANGLE: $s17lowered_metatypes6StructVXMt
12+
// DEMANGLE: $s17lowered_metatypes6StructVXMT
13+
// DEMANGLE: $s17lowered_metatypes5ClassCXMo
14+
15+
// CHECK: @thin Struct.Type
16+
// CHECK: @thick Struct.Type
17+
// CHECK: @objc_metatype Class.Type
18+
19+
// DEMANGLE: $s17lowered_metatypes5ProtoPXmT
20+
// DEMANGLE: $s17lowered_metatypes5ProtoPXmo
21+
22+
// CHECK: @thick Proto.Type
23+
// CHECK: @objc_metatype Proto.Type

test/TypeDecoder/objc_classes.swift

+1-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ do {
5050
// DEMANGLE: $s12objc_classes15OurObjCProtocol_pXpD
5151

5252
// CHECK: NSSet.Type
53-
54-
// FIXME: we drop the metatype representation here
55-
// CHECK: NSSet.Type
53+
// CHECK: @thick NSSet.Type
5654

5755
// CHECK: NSFastEnumeration.Type
5856
// CHECK: OurObjCProtocol.Type

unittests/Reflection/TypeRef.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ TEST(TypeRefTest, UniqueMetatypeTypeRef) {
240240
TypeRefBuilder Builder;
241241

242242
auto N1 = Builder.createNominalType(ABC, nullptr);
243-
auto M1 = Builder.createMetatypeType(N1, false);
244-
auto M2 = Builder.createMetatypeType(N1, false);
245-
auto MM3 = Builder.createMetatypeType(M1, false);
246-
auto M4 = Builder.createMetatypeType(N1, true);
243+
auto M1 = Builder.createMetatypeType(N1, None);
244+
auto M2 = Builder.createMetatypeType(N1, None);
245+
auto MM3 = Builder.createMetatypeType(M1, None);
246+
auto M4 = Builder.createMetatypeType(N1, Demangle::ImplMetatypeRepresentation::Thick);
247247

248248
EXPECT_EQ(M1, M2);
249249
EXPECT_NE(M2, MM3);

0 commit comments

Comments
 (0)