Skip to content

Commit 08e8fb0

Browse files
authored
Merge pull request #17238 from rjmccall/full-accessor-lists
Generalize accessor storage to preserve the original accessor list.
2 parents fdbe018 + 69f4dd1 commit 08e8fb0

19 files changed

+571
-764
lines changed

include/swift/AST/Decl.h

Lines changed: 90 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -3962,9 +3962,11 @@ enum class AccessorKind {
39623962
#include "swift/AST/AccessorKinds.def"
39633963
};
39643964

3965+
const unsigned NumAccessorKinds = unsigned(AccessorKind::Last) + 1;
3966+
39653967
static inline IntRange<AccessorKind> allAccessorKinds() {
39663968
return IntRange<AccessorKind>(AccessorKind(0),
3967-
AccessorKind(unsigned(AccessorKind::Last) + 1));
3969+
AccessorKind(NumAccessorKinds));
39683970
}
39693971

39703972
/// The safety semantics of this addressor.
@@ -4121,66 +4123,66 @@ class AbstractStorageDecl : public ValueDecl {
41214123
/// return the address at which the object is stored.
41224124
ComputedWithMutableAddress,
41234125
};
4126+
4127+
static const size_t MaxNumAccessors = 255;
41244128
private:
41254129
AbstractStorageDecl *OverriddenDecl;
41264130

4127-
struct GetSetRecord;
4128-
4129-
/// This is stored immediately before the GetSetRecord.
4130-
struct alignas(1 << 3) AddressorRecord {
4131-
AccessorDecl *Address = nullptr; // User-defined address accessor
4132-
AccessorDecl *MutableAddress = nullptr; // User-defined mutableAddress accessor
4133-
4134-
GetSetRecord *getGetSet() {
4135-
// Relies on not-strictly-portable ABI layout assumptions.
4136-
return reinterpret_cast<GetSetRecord*>(this+1);
4137-
}
4138-
};
4139-
void configureAddressorRecord(AddressorRecord *record,
4140-
AccessorDecl *addressor, AccessorDecl *mutableAddressor);
4131+
/// A record of the accessors for the declaration.
4132+
class alignas(1 << 3) AccessorRecord final :
4133+
private llvm::TrailingObjects<AccessorRecord, AccessorDecl*> {
4134+
friend TrailingObjects;
4135+
4136+
using AccessorIndex = uint8_t;
4137+
static const AccessorIndex InvalidIndex = 0;
41414138

4142-
struct alignas(1 << 3) GetSetRecord {
41434139
SourceRange Braces;
4144-
AccessorDecl *Get = nullptr; // User-defined getter
4145-
AccessorDecl *Set = nullptr; // User-defined setter
4146-
AccessorDecl *MaterializeForSet = nullptr; // optional materializeForSet accessor
4140+
AccessorIndex NumAccessors;
4141+
4142+
/// The storage capacity of this record for accessors. Always includes
4143+
/// enough space for adding opaque accessors to the record, which are the
4144+
/// only accessors that should ever be added retroactively; hence this
4145+
/// field is only here for the purposes of safety checks.
4146+
AccessorIndex AccessorsCapacity;
4147+
4148+
/// Either 0, meaning there is no registered accessor of the given kind,
4149+
/// or the index+1 of the accessor in the accessors array.
4150+
AccessorIndex AccessorIndices[NumAccessorKinds];
4151+
4152+
AccessorRecord(SourceRange braces, ArrayRef<AccessorDecl*> accessors,
4153+
AccessorIndex accessorsCapacity);
4154+
public:
4155+
static AccessorRecord *create(ASTContext &ctx, SourceRange braces,
4156+
ArrayRef<AccessorDecl*> accessors);
4157+
4158+
SourceRange getBracesRange() const { return Braces; }
4159+
4160+
inline AccessorDecl *getAccessor(AccessorKind kind) const;
41474161

4148-
AddressorRecord *getAddressors() {
4149-
// Relies on not-strictly-portable ABI layout assumptions.
4150-
return reinterpret_cast<AddressorRecord*>(this) - 1;
4162+
ArrayRef<AccessorDecl *> getAllAccessors() const {
4163+
return { getTrailingObjects<AccessorDecl*>(), NumAccessors };
41514164
}
4165+
4166+
void addOpaqueAccessor(AccessorDecl *accessor);
4167+
4168+
private:
4169+
MutableArrayRef<AccessorDecl *> getAccessorsBuffer() {
4170+
return { getTrailingObjects<AccessorDecl*>(), NumAccessors };
4171+
}
4172+
4173+
bool registerAccessor(AccessorDecl *accessor, AccessorIndex index);
41524174
};
4153-
void configureGetSetRecord(GetSetRecord *getSetRecord,
4154-
AccessorDecl *getter, AccessorDecl *setter,
4155-
AccessorDecl *materializeForSet);
4156-
void configureSetRecord(GetSetRecord *getSetInfo,
4157-
AccessorDecl *setter,
4158-
AccessorDecl *materializeForSet);
4159-
4160-
struct ObservingRecord : GetSetRecord {
4161-
AccessorDecl *WillSet = nullptr; // willSet(value):
4162-
AccessorDecl *DidSet = nullptr; // didSet:
4163-
};
4164-
void configureObservingRecord(ObservingRecord *record,
4165-
AccessorDecl *willSet, AccessorDecl *didSet);
41664175

4167-
llvm::PointerIntPair<GetSetRecord*, 3, OptionalEnum<AccessLevel>> GetSetInfo;
4176+
llvm::PointerIntPair<AccessorRecord*, 3, OptionalEnum<AccessLevel>> Accessors;
41684177
llvm::PointerIntPair<BehaviorRecord*, 3, OptionalEnum<AccessLevel>>
41694178
BehaviorInfo;
41704179

4171-
ObservingRecord &getDidSetInfo() const {
4172-
assert(hasObservers());
4173-
return *static_cast<ObservingRecord*>(GetSetInfo.getPointer());
4174-
}
4175-
AddressorRecord &getAddressorInfo() const {
4176-
assert(hasAddressors());
4177-
return *GetSetInfo.getPointer()->getAddressors();
4178-
}
4179-
41804180
void setStorageKind(StorageKindTy K) {
41814181
Bits.AbstractStorageDecl.StorageKind = unsigned(K);
41824182
}
41834183

4184+
void configureAccessor(AccessorDecl *accessor);
4185+
41844186
protected:
41854187
AbstractStorageDecl(DeclKind Kind, DeclContext *DC, DeclName Name,
41864188
SourceLoc NameLoc)
@@ -4308,55 +4310,26 @@ class AbstractStorageDecl : public ValueDecl {
43084310
Bits.AbstractStorageDecl.IsSetterMutating = isMutating;
43094311
}
43104312

4311-
AccessorDecl *getAccessorFunction(AccessorKind accessor) const;
4312-
4313-
/// \brief Push all of the accessor functions associated with this VarDecl
4314-
/// onto `decls`.
4315-
void getAllAccessorFunctions(SmallVectorImpl<Decl *> &decls) const;
4313+
AccessorDecl *getAccessorFunction(AccessorKind kind) const {
4314+
if (auto info = Accessors.getPointer())
4315+
return info->getAccessor(kind);
4316+
return nullptr;
4317+
}
43164318

4317-
/// \brief Turn this into a computed variable, providing a getter and setter.
4318-
void makeComputed(SourceLoc LBraceLoc, AccessorDecl *Get, AccessorDecl *Set,
4319-
AccessorDecl *MaterializeForSet, SourceLoc RBraceLoc);
4319+
ArrayRef<AccessorDecl*> getAllAccessorFunctions() const {
4320+
if (const auto *info = Accessors.getPointer())
4321+
return info->getAllAccessors();
4322+
return {};
4323+
}
43204324

4321-
/// \brief Turn this into a computed object, providing a getter and a mutable
4322-
/// addressor.
4323-
void makeComputedWithMutableAddress(SourceLoc lbraceLoc,
4324-
AccessorDecl *getter,
4325-
AccessorDecl *setter,
4326-
AccessorDecl *materializeForSet,
4327-
AccessorDecl *mutableAddressor,
4328-
SourceLoc rbraceLoc);
4325+
void setAccessors(StorageKindTy storageKind,
4326+
SourceLoc lbraceLoc, ArrayRef<AccessorDecl*> accessors,
4327+
SourceLoc rbraceLoc);
43294328

43304329
/// \brief Add trivial accessors to this Stored or Addressed object.
43314330
void addTrivialAccessors(AccessorDecl *Get, AccessorDecl *Set,
43324331
AccessorDecl *MaterializeForSet);
43334332

4334-
/// \brief Turn this into a stored-with-observers var, providing the
4335-
/// didSet/willSet specifiers.
4336-
void makeStoredWithObservers(SourceLoc LBraceLoc, AccessorDecl *WillSet,
4337-
AccessorDecl *DidSet, SourceLoc RBraceLoc);
4338-
4339-
/// \brief Turn this into an inherited-with-observers var, providing
4340-
/// the didSet/willSet specifiers.
4341-
void makeInheritedWithObservers(SourceLoc LBraceLoc, AccessorDecl *WillSet,
4342-
AccessorDecl *DidSet, SourceLoc RBraceLoc);
4343-
4344-
/// \brief Turn this into an addressed var.
4345-
void makeAddressed(SourceLoc LBraceLoc, AccessorDecl *Addressor,
4346-
AccessorDecl *MutableAddressor,
4347-
SourceLoc RBraceLoc);
4348-
4349-
/// \brief Turn this into an addressed var with observing accessors.
4350-
void makeAddressedWithObservers(SourceLoc LBraceLoc, AccessorDecl *Addressor,
4351-
AccessorDecl *MutableAddressor,
4352-
AccessorDecl *WillSet, AccessorDecl *DidSet,
4353-
SourceLoc RBraceLoc);
4354-
4355-
/// \brief Specify the synthesized get/set functions for a
4356-
/// StoredWithObservers or AddressedWithObservers var. This is used by Sema.
4357-
void setObservingAccessors(AccessorDecl *Get, AccessorDecl *Set,
4358-
AccessorDecl *MaterializeForSet);
4359-
43604333
/// \brief Add a setter to an existing Computed var.
43614334
///
43624335
/// This should only be used by the ClangImporter.
@@ -4370,39 +4343,30 @@ class AbstractStorageDecl : public ValueDecl {
43704343
/// This should only be used by Sema.
43714344
void setMaterializeForSetFunc(AccessorDecl *materializeForSet);
43724345

4373-
/// \brief Specify the braces range without adding accessors.
4374-
///
4375-
/// This is used to record the braces range if the accessors were rejected.
4376-
void setInvalidBracesRange(SourceRange BracesRange);
4377-
43784346
SourceRange getBracesRange() const {
4379-
if (auto info = GetSetInfo.getPointer())
4380-
return info->Braces;
4347+
if (auto info = Accessors.getPointer())
4348+
return info->getBracesRange();
43814349
return SourceRange();
43824350
}
43834351

43844352
/// \brief Retrieve the getter used to access the value of this variable.
43854353
AccessorDecl *getGetter() const {
4386-
if (auto info = GetSetInfo.getPointer())
4387-
return info->Get;
4388-
return nullptr;
4354+
return getAccessorFunction(AccessorKind::Get);
43894355
}
43904356

43914357
/// \brief Retrieve the setter used to mutate the value of this variable.
43924358
AccessorDecl *getSetter() const {
4393-
if (auto info = GetSetInfo.getPointer())
4394-
return info->Set;
4395-
return nullptr;
4359+
return getAccessorFunction(AccessorKind::Set);
43964360
}
43974361

43984362
AccessLevel getSetterFormalAccess() const {
43994363
assert(hasAccess());
4400-
assert(GetSetInfo.getInt().hasValue());
4401-
return GetSetInfo.getInt().getValue();
4364+
assert(Accessors.getInt().hasValue());
4365+
return Accessors.getInt().getValue();
44024366
}
44034367

44044368
void setSetterAccess(AccessLevel accessLevel) {
4405-
assert(!GetSetInfo.getInt().hasValue());
4369+
assert(!Accessors.getInt().hasValue());
44064370
overwriteSetterAccess(accessLevel);
44074371
}
44084372

@@ -4411,19 +4375,18 @@ class AbstractStorageDecl : public ValueDecl {
44114375
/// \brief Retrieve the materializeForSet function, if this
44124376
/// declaration has one.
44134377
AccessorDecl *getMaterializeForSetFunc() const {
4414-
if (auto info = GetSetInfo.getPointer())
4415-
return info->MaterializeForSet;
4416-
return nullptr;
4378+
return getAccessorFunction(AccessorKind::MaterializeForSet);
44174379
}
44184380

4419-
/// \brief Return the decl for the 'address' accessor if it
4420-
/// exists; this is only valid on a declaration with addressors.
4421-
AccessorDecl *getAddressor() const { return getAddressorInfo().Address; }
4381+
/// \brief Return the decl for the immutable addressor if it exists.
4382+
AccessorDecl *getAddressor() const {
4383+
return getAccessorFunction(AccessorKind::Address);
4384+
}
44224385

44234386
/// \brief Return the decl for the 'mutableAddress' accessors if
44244387
/// it exists; this is only valid on a declaration with addressors.
44254388
AccessorDecl *getMutableAddressor() const {
4426-
return getAddressorInfo().MutableAddress;
4389+
return getAccessorFunction(AccessorKind::MutableAddress);
44274390
}
44284391

44294392
/// \brief Return the appropriate addressor for the given access kind.
@@ -4435,11 +4398,15 @@ class AbstractStorageDecl : public ValueDecl {
44354398

44364399
/// \brief Return the decl for the willSet specifier if it exists, this is
44374400
/// only valid on a declaration with Observing storage.
4438-
AccessorDecl *getWillSetFunc() const { return getDidSetInfo().WillSet; }
4401+
AccessorDecl *getWillSetFunc() const {
4402+
return getAccessorFunction(AccessorKind::WillSet);
4403+
}
44394404

44404405
/// \brief Return the decl for the didSet specifier if it exists, this is
44414406
/// only valid on a declaration with Observing storage.
4442-
AccessorDecl *getDidSetFunc() const { return getDidSetInfo().DidSet; }
4407+
AccessorDecl *getDidSetFunc() const {
4408+
return getAccessorFunction(AccessorKind::DidSet);
4409+
}
44434410

44444411
/// Given that this is an Objective-C property or subscript declaration,
44454412
/// produce its getter selector.
@@ -5777,6 +5744,16 @@ inline ParameterList **FuncDecl::getParameterListBuffer() {
57775744
}
57785745
return reinterpret_cast<ParameterList**>(static_cast<AccessorDecl*>(this)+1);
57795746
}
5747+
5748+
inline AccessorDecl *
5749+
AbstractStorageDecl::AccessorRecord::getAccessor(AccessorKind kind) const {
5750+
if (auto optIndex = AccessorIndices[unsigned(kind)]) {
5751+
auto accessor = getAllAccessors()[optIndex - 1];
5752+
assert(accessor && accessor->getAccessorKind() == kind);
5753+
return accessor;
5754+
}
5755+
return nullptr;
5756+
}
57805757

57815758
/// \brief This represents a 'case' declaration in an 'enum', which may declare
57825759
/// one or more individual comma-separated EnumElementDecls.
@@ -6652,7 +6629,7 @@ ::operator()(Decl *decl) const {
66526629

66536630
inline void
66546631
AbstractStorageDecl::overwriteSetterAccess(AccessLevel accessLevel) {
6655-
GetSetInfo.setInt(accessLevel);
6632+
Accessors.setInt(accessLevel);
66566633
if (auto setter = getSetter())
66576634
setter->overwriteAccess(accessLevel);
66586635
if (auto materializeForSet = getMaterializeForSetFunc())

include/swift/Parse/Parser.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ class Parser {
878878

879879
struct ParsedAccessors {
880880
SourceLoc LBLoc, RBLoc;
881+
SmallVector<AccessorDecl*, 16> Accessors;
881882

882883
#define ACCESSOR(ID) AccessorDecl *ID = nullptr;
883884
#include "swift/AST/AccessorKinds.def"
@@ -887,6 +888,17 @@ class Parser {
887888
const DeclAttributes &attrs,
888889
TypeLoc elementTy, ParameterList *indices,
889890
SmallVectorImpl<Decl *> &decls);
891+
892+
AbstractStorageDecl::StorageKindTy
893+
classify(Parser &P, AbstractStorageDecl *storage, bool invalid,
894+
ParseDeclOptions flags, SourceLoc staticLoc,
895+
const DeclAttributes &attrs,
896+
TypeLoc elementTy, ParameterList *indices);
897+
898+
/// Add an accessor. If there's an existing accessor of this kind,
899+
/// return it. The new accessor is still remembered but will be
900+
/// ignored.
901+
AccessorDecl *add(AccessorDecl *accessor);
890902
};
891903

892904
void parseAccessorAttributes(DeclAttributes &Attributes);
@@ -898,15 +910,14 @@ class Parser {
898910
ParsedAccessors &accessors,
899911
AbstractStorageDecl *storage,
900912
SourceLoc &LastValidLoc,
901-
SourceLoc StaticLoc, SourceLoc VarLBLoc,
902-
SmallVectorImpl<Decl *> &Decls);
913+
SourceLoc StaticLoc, SourceLoc VarLBLoc);
903914
bool parseGetSet(ParseDeclOptions Flags,
904915
GenericParamList *GenericParams,
905916
ParameterList *Indices,
906917
TypeLoc ElementTy,
907918
ParsedAccessors &accessors,
908919
AbstractStorageDecl *storage,
909-
SourceLoc StaticLoc, SmallVectorImpl<Decl *> &Decls);
920+
SourceLoc StaticLoc);
910921
void recordAccessors(AbstractStorageDecl *storage, ParseDeclOptions flags,
911922
TypeLoc elementTy, const DeclAttributes &attrs,
912923
SourceLoc staticLoc, ParsedAccessors &accessors);

0 commit comments

Comments
 (0)