Skip to content

Commit d39e7d9

Browse files
committed
Reflection: Add type lowering for class references and functions
Also add slightly inaccurate lowering for the special case of an optional of a reference type. I need to rethink the approach for extra inhabitants and enums, but this suffices for now.
1 parent 0d34bc2 commit d39e7d9

File tree

6 files changed

+335
-44
lines changed

6 files changed

+335
-44
lines changed

include/swift/Reflection/TypeLowering.h

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,42 @@
1919
#define SWIFT_REFLECTION_TYPELOWERING_H
2020

2121
#include "llvm/ADT/DenseMap.h"
22+
#include "llvm/Support/Casting.h"
2223

2324
#include <iostream>
2425
#include <memory>
2526

2627
namespace swift {
2728
namespace reflection {
2829

30+
using llvm::cast;
31+
using llvm::dyn_cast;
32+
2933
class TypeRef;
3034
class TypeRefBuilder;
3135

36+
enum class RecordKind : unsigned {
37+
Tuple,
38+
Struct,
39+
ThickFunction,
40+
};
41+
42+
enum class ReferenceCounting : unsigned {
43+
Native,
44+
Unknown
45+
};
46+
47+
enum class ReferenceKind : unsigned {
48+
Strong,
49+
Unowned,
50+
Weak,
51+
Unmanaged
52+
};
53+
3254
enum class TypeInfoKind : unsigned {
3355
Builtin,
34-
Struct,
35-
Tuple,
56+
Record,
57+
Reference,
3658
};
3759

3860
class TypeInfo {
@@ -65,32 +87,84 @@ struct FieldInfo {
6587

6688
/// Class instances, structs, tuples
6789
class RecordTypeInfo : public TypeInfo {
90+
RecordKind SubKind;
6891
std::vector<FieldInfo> Fields;
6992

7093
public:
71-
RecordTypeInfo(TypeInfoKind Kind,
72-
unsigned Size, unsigned Alignment,
94+
RecordTypeInfo(unsigned Size, unsigned Alignment,
7395
unsigned Stride, unsigned NumExtraInhabitants,
74-
const std::vector<FieldInfo> &Fields)
75-
: TypeInfo(Kind, Size, Alignment, Stride, NumExtraInhabitants),
76-
Fields(Fields) {}
96+
RecordKind SubKind, const std::vector<FieldInfo> &Fields)
97+
: TypeInfo(TypeInfoKind::Record, Size, Alignment, Stride,
98+
NumExtraInhabitants),
99+
SubKind(SubKind), Fields(Fields) {}
77100

101+
RecordKind getRecordKind() const { return SubKind; }
78102
unsigned getNumFields() const { return Fields.size(); }
79103
const std::vector<FieldInfo> &getFields() const { return Fields; }
104+
105+
static bool classof(const TypeInfo *TI) {
106+
return TI->getKind() == TypeInfoKind::Record;
107+
}
108+
};
109+
110+
/// References to classes, closure contexts and anything else with an
111+
/// 'isa' pointer
112+
class ReferenceTypeInfo : public TypeInfo {
113+
ReferenceKind SubKind;
114+
ReferenceCounting Refcounting;
115+
116+
public:
117+
ReferenceTypeInfo(unsigned Size, unsigned Alignment,
118+
unsigned Stride, unsigned NumExtraInhabitants,
119+
ReferenceKind SubKind, ReferenceCounting Refcounting)
120+
: TypeInfo(TypeInfoKind::Reference, Size, Alignment, Stride,
121+
NumExtraInhabitants),
122+
SubKind(SubKind), Refcounting(Refcounting) {}
123+
124+
ReferenceKind getReferenceKind() const {
125+
return SubKind;
126+
}
127+
128+
ReferenceCounting getReferenceCounting() const {
129+
return Refcounting;
130+
}
131+
132+
static bool classof(const TypeInfo *TI) {
133+
return TI->getKind() == TypeInfoKind::Reference;
134+
}
80135
};
81136

82137
/// This class owns the memory for all TypeInfo instances that it vends.
83138
class TypeConverter {
84139
TypeRefBuilder &Builder;
85140
std::vector<std::unique_ptr<const TypeInfo>> Pool;
86141
llvm::DenseMap<const TypeRef *, const TypeInfo *> Cache;
142+
llvm::DenseMap<std::pair<unsigned, unsigned>,
143+
const ReferenceTypeInfo *> ReferenceCache;
144+
const TypeInfo *RawPointerTI = nullptr;
145+
const TypeInfo *ThickFunctionTI = nullptr;
87146

88147
public:
89148
explicit TypeConverter(TypeRefBuilder &Builder) : Builder(Builder) {}
90149

91150
TypeRefBuilder &getBuilder() { return Builder; }
92151

93152
const TypeInfo *getTypeInfo(const TypeRef *TR);
153+
154+
/* Not really public */
155+
const ReferenceTypeInfo *
156+
getReferenceTypeInfo(ReferenceKind Kind,
157+
ReferenceCounting Refcounting);
158+
159+
const TypeInfo *getRawPointerTypeInfo();
160+
const TypeInfo *getThickFunctionTypeInfo();
161+
162+
template <typename TypeInfoTy, typename... Args>
163+
const TypeInfoTy *makeTypeInfo(Args... args) {
164+
auto TI = new TypeInfoTy(::std::forward<Args>(args)...);
165+
Pool.push_back(std::unique_ptr<const TypeInfo>(TI));
166+
return TI;
167+
}
94168
};
95169

96170
}

0 commit comments

Comments
 (0)