1313#include " swift/AST/Decl.h"
1414#include " swift/AST/Types.h"
1515#include " llvm/ADT/FoldingSet.h"
16+ #include " llvm/ADT/PointerIntPair.h"
1617#include " llvm/Support/raw_ostream.h"
1718#include < algorithm>
1819#include < vector>
@@ -38,50 +39,40 @@ const StringRef Symbol::Kinds[] = {
3839// / the Storage type is the allocated backing storage.
3940struct Symbol ::Storage final
4041 : public llvm::FoldingSetNode,
41- public llvm::TrailingObjects<Storage, const ProtocolDecl * , Term> {
42+ public llvm::TrailingObjects<Storage, unsigned , Term> {
4243 friend class Symbol ;
4344
44- unsigned Kind : 3 ;
45- unsigned NumSubstitutions : 14 ;
45+ llvm::PointerIntPair<const ProtocolDecl *, 3 > ProtoAndKind;
4646
4747 union {
4848 Identifier Name;
4949 CanType ConcreteType;
5050 LayoutConstraint Layout;
51- const ProtocolDecl *Proto;
5251 GenericTypeParamType *GenericParam;
5352 };
5453
5554 explicit Storage (Identifier name) {
56- Kind = unsigned (Symbol::Kind::Name);
57- NumSubstitutions = 0 ;
55+ ProtoAndKind.setInt (unsigned (Symbol::Kind::Name));
5856 Name = name;
5957 }
6058
6159 explicit Storage (LayoutConstraint layout) {
62- Kind = unsigned (Symbol::Kind::Layout);
63- NumSubstitutions = 0 ;
60+ ProtoAndKind.setInt (unsigned (Symbol::Kind::Layout));
6461 Layout = layout;
6562 }
6663
6764 explicit Storage (const ProtocolDecl *proto) {
68- Kind = unsigned (Symbol::Kind::Protocol);
69- NumSubstitutions = 0 ;
70- Proto = proto;
65+ ProtoAndKind.setPointerAndInt (proto, unsigned (Symbol::Kind::Protocol));
7166 }
7267
7368 explicit Storage (GenericTypeParamType *param) {
74- Kind = unsigned (Symbol::Kind::GenericParam);
75- NumSubstitutions = 0 ;
69+ ProtoAndKind.setInt (unsigned (Symbol::Kind::GenericParam));
7670 GenericParam = param;
7771 }
7872
7973 Storage (const ProtocolDecl *proto, Identifier name) {
80- Kind = unsigned (Symbol::Kind::AssociatedType);
81- NumSubstitutions = 0 ;
74+ ProtoAndKind.setPointerAndInt (proto, unsigned (Symbol::Kind::AssociatedType));
8275 Name = name;
83-
84- *getTrailingObjects<const ProtocolDecl *>() = proto;
8576 }
8677
8778 Storage (Symbol::Kind kind, CanType type, ArrayRef<Term> substitutions) {
@@ -90,10 +81,11 @@ struct Symbol::Storage final
9081 assert (!type->hasTypeVariable ());
9182 assert (type->hasTypeParameter () != substitutions.empty ());
9283
93- Kind = unsigned (kind);
94- NumSubstitutions = substitutions.size ();
84+ ProtoAndKind.setInt (unsigned (kind));
9585 ConcreteType = type;
9686
87+ *getTrailingObjects<unsigned >() = substitutions.size ();
88+
9789 for (unsigned i : indices (substitutions))
9890 getSubstitutions ()[i] = substitutions[i];
9991 }
@@ -102,38 +94,44 @@ struct Symbol::Storage final
10294 assert (!type->hasTypeVariable ());
10395 assert (type->hasTypeParameter () != substitutions.empty ());
10496
105- Kind = unsigned (Symbol::Kind::ConcreteConformance);
106- NumSubstitutions = substitutions.size ();
97+ ProtoAndKind.setPointerAndInt (proto, unsigned (Symbol::Kind::ConcreteConformance));
98+
99+ *getTrailingObjects<unsigned >() = substitutions.size ();
107100 ConcreteType = type;
108101
109102 for (unsigned i : indices (substitutions))
110103 getSubstitutions ()[i] = substitutions[i];
111-
112- *getTrailingObjects<const ProtocolDecl *>() = proto;
113104 }
114105
115- size_t numTrailingObjects (OverloadToken<const ProtocolDecl *>) const {
116- return (Kind == unsigned (Symbol::Kind::AssociatedType) ||
117- Kind == unsigned (Symbol::Kind::ConcreteConformance));
106+ size_t numTrailingObjects (OverloadToken<unsigned >) const {
107+ auto kind = Symbol::Kind (ProtoAndKind.getInt ());
108+ return (kind == Symbol::Kind::Superclass ||
109+ kind == Symbol::Kind::ConcreteType ||
110+ kind == Symbol::Kind::ConcreteConformance);
118111 }
119112
120113 size_t numTrailingObjects (OverloadToken<Term>) const {
121- return NumSubstitutions;
114+ return getNumSubstitutions ();
115+ }
116+
117+ unsigned getNumSubstitutions () const {
118+ assert (numTrailingObjects (OverloadToken<unsigned >()) == 1 );
119+ return *getTrailingObjects<unsigned >();
122120 }
123121
124122 MutableArrayRef<Term> getSubstitutions () {
125- return {getTrailingObjects<Term>(), NumSubstitutions };
123+ return {getTrailingObjects<Term>(), getNumSubstitutions () };
126124 }
127125
128126 ArrayRef<Term> getSubstitutions () const {
129- return {getTrailingObjects<Term>(), NumSubstitutions };
127+ return {getTrailingObjects<Term>(), getNumSubstitutions () };
130128 }
131129
132130 void Profile (llvm::FoldingSetNodeID &id) const ;
133131};
134132
135133Symbol::Kind Symbol::getKind () const {
136- return Kind (Ptr->Kind );
134+ return Kind (Ptr->ProtoAndKind . getInt () );
137135}
138136
139137// / Get the identifier associated with an unbound name symbol or an
@@ -147,12 +145,10 @@ Identifier Symbol::getName() const {
147145// / Get the protocol declaration associated with a protocol or associated type
148146// / symbol.
149147const ProtocolDecl *Symbol::getProtocol () const {
150- if (getKind () == Kind::Protocol)
151- return Ptr->Proto ;
152-
153- assert (getKind () == Kind::AssociatedType ||
148+ assert (getKind () == Kind::Protocol ||
149+ getKind () == Kind::AssociatedType ||
154150 getKind () == Kind::ConcreteConformance);
155- return * Ptr->getTrailingObjects < const ProtocolDecl *> ();
151+ return Ptr->ProtoAndKind . getPointer ();
156152}
157153
158154// / Get the generic parameter associated with a generic parameter symbol.
@@ -179,9 +175,6 @@ CanType Symbol::getConcreteType() const {
179175// / Get the list of substitution terms associated with a superclass,
180176// / concrete type or concrete conformance symbol.
181177ArrayRef<Term> Symbol::getSubstitutions () const {
182- assert (getKind () == Kind::Superclass ||
183- getKind () == Kind::ConcreteType ||
184- getKind () == Kind::ConcreteConformance);
185178 return Ptr->getSubstitutions ();
186179}
187180
@@ -196,7 +189,7 @@ Symbol Symbol::forName(Identifier name,
196189 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
197190 return symbol;
198191
199- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(0 , 0 );
192+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(0 , 0 );
200193 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
201194 auto *symbol = new (mem) Storage (name);
202195
@@ -225,7 +218,7 @@ Symbol Symbol::forProtocol(const ProtocolDecl *proto,
225218 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
226219 return symbol;
227220
228- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(0 , 0 );
221+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(0 , 0 );
229222 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
230223 auto *symbol = new (mem) Storage (proto);
231224
@@ -254,8 +247,7 @@ Symbol Symbol::forAssociatedType(const ProtocolDecl *proto,
254247 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
255248 return symbol;
256249
257- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl *, Term>(
258- 1 , 0 );
250+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(0 , 0 );
259251 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
260252 auto *symbol = new (mem) Storage (proto, name);
261253
@@ -286,7 +278,7 @@ Symbol Symbol::forGenericParam(GenericTypeParamType *param,
286278 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
287279 return symbol;
288280
289- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(0 , 0 );
281+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(0 , 0 );
290282 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
291283 auto *symbol = new (mem) Storage (param);
292284
@@ -313,7 +305,7 @@ Symbol Symbol::forLayout(LayoutConstraint layout,
313305 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
314306 return symbol;
315307
316- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(0 , 0 );
308+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(0 , 0 );
317309 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
318310 auto *symbol = new (mem) Storage (layout);
319311
@@ -344,8 +336,8 @@ Symbol Symbol::forSuperclass(CanType type, ArrayRef<Term> substitutions,
344336 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
345337 return symbol;
346338
347- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(
348- 0 , substitutions.size ());
339+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(
340+ 1 , substitutions.size ());
349341 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
350342 auto *symbol = new (mem) Storage (Kind::Superclass, type, substitutions);
351343
@@ -375,8 +367,8 @@ Symbol Symbol::forConcreteType(CanType type, ArrayRef<Term> substitutions,
375367 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
376368 return symbol;
377369
378- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(
379- 0 , substitutions.size ());
370+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(
371+ 1 , substitutions.size ());
380372 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
381373 auto *symbol = new (mem) Storage (Kind::ConcreteType, type, substitutions);
382374
@@ -399,18 +391,18 @@ Symbol Symbol::forConcreteConformance(CanType type,
399391 RewriteContext &ctx) {
400392 llvm::FoldingSetNodeID id;
401393 id.AddInteger (unsigned (Kind::ConcreteConformance));
394+ id.AddPointer (proto);
402395 id.AddPointer (type.getPointer ());
403396 id.AddInteger (unsigned (substitutions.size ()));
404397 for (auto substitution : substitutions)
405398 id.AddPointer (substitution.getOpaquePointer ());
406- id.AddPointer (proto);
407399
408400 void *insertPos = nullptr ;
409401 if (auto *symbol = ctx.Symbols .FindNodeOrInsertPos (id, insertPos))
410402 return symbol;
411403
412- unsigned size = Storage::totalSizeToAlloc<const ProtocolDecl * , Term>(
413- /* protos= */ 1 , substitutions.size ());
404+ unsigned size = Storage::totalSizeToAlloc<unsigned , Term>(
405+ 1 , substitutions.size ());
414406 void *mem = ctx.Allocator .Allocate (size, alignof (Storage));
415407 auto *symbol = new (mem) Storage (type, substitutions, proto);
416408
@@ -712,9 +704,9 @@ void Symbol::dump(llvm::raw_ostream &out) const {
712704}
713705
714706void Symbol::Storage::Profile (llvm::FoldingSetNodeID &id) const {
715- id.AddInteger (Kind );
707+ id.AddInteger (ProtoAndKind. getInt () );
716708
717- switch (Symbol::Kind (Kind )) {
709+ switch (Symbol::Kind (ProtoAndKind. getInt () )) {
718710 case Symbol::Kind::Name:
719711 id.AddPointer (Name.get ());
720712 return ;
@@ -724,38 +716,37 @@ void Symbol::Storage::Profile(llvm::FoldingSetNodeID &id) const {
724716 return ;
725717
726718 case Symbol::Kind::Protocol:
727- id.AddPointer (Proto );
719+ id.AddPointer (ProtoAndKind. getPointer () );
728720 return ;
729721
730722 case Symbol::Kind::GenericParam:
731723 id.AddPointer (GenericParam);
732724 return ;
733725
734726 case Symbol::Kind::AssociatedType: {
735- id.AddPointer (*getTrailingObjects< const ProtocolDecl *> ());
727+ id.AddPointer (ProtoAndKind. getPointer ());
736728 id.AddPointer (Name.get ());
737729 return ;
738730 }
739731
740732 case Symbol::Kind::Superclass:
741733 case Symbol::Kind::ConcreteType: {
742734 id.AddPointer (ConcreteType.getPointer ());
743-
744- id.AddInteger (NumSubstitutions);
735+ id.AddInteger (getNumSubstitutions ());
745736 for (auto term : getSubstitutions ())
746737 id.AddPointer (term.getOpaquePointer ());
747738
748739 return ;
749740 }
750741
751742 case Symbol::Kind::ConcreteConformance: {
743+ id.AddPointer (ProtoAndKind.getPointer ());
752744 id.AddPointer (ConcreteType.getPointer ());
753745
754- id.AddInteger (NumSubstitutions );
746+ id.AddInteger (getNumSubstitutions () );
755747 for (auto term : getSubstitutions ())
756748 id.AddPointer (term.getOpaquePointer ());
757749
758- id.AddPointer (*getTrailingObjects<const ProtocolDecl *>());
759750 return ;
760751 }
761752 }
0 commit comments