1616
1717#ifndef SWIFT_ATTR_H
1818#define SWIFT_ATTR_H
19-
2019#include " swift/AST/ASTAllocated.h"
2120#include " swift/AST/AttrKind.h"
2221#include " swift/AST/AutoDiff.h"
@@ -203,7 +202,7 @@ class DeclAttribute : public AttributeBase {
203202 ownership : NumReferenceOwnershipBits
204203 );
205204
206- SWIFT_INLINE_BITFIELD (SpecializeAttr , DeclAttribute, 1 +1 ,
205+ SWIFT_INLINE_BITFIELD (AbstractSpecializeAttr , DeclAttribute, 1 +1 ,
207206 exported : 1 ,
208207 kind : 1
209208 );
@@ -1730,15 +1729,17 @@ class SynthesizedProtocolAttr : public DeclAttribute {
17301729 }
17311730};
17321731
1733- // / The @_specialize attribute, which forces specialization on the specified
1734- // / type list.
1735- class SpecializeAttr final
1732+ // / The @_specialize/@specialize attribute, which forces specialization on the
1733+ // / specified type list.
1734+ template <typename Base, typename ...AdditionalTrailingObjects>
1735+ using SpecializeAttrTrailingObjects = llvm::TrailingObjects<Base,
1736+ Identifier, AvailableAttr *, Type , AdditionalTrailingObjects...>;
1737+
1738+ class AbstractSpecializeAttr
17361739 : public DeclAttribute,
1737- private llvm::TrailingObjects<SpecializeAttr, Identifier,
1738- AvailableAttr *, Type> {
1740+ private llvm::trailing_objects_internal::TrailingObjectsBase {
17391741 friend class SpecializeAttrTargetDeclRequest ;
17401742 friend class SerializeAttrGenericSignatureRequest ;
1741- friend TrailingObjects;
17421743
17431744public:
17441745 // NOTE: When adding new kinds, you must update the inline bitfield macro.
@@ -1759,82 +1760,81 @@ class SpecializeAttr final
17591760 size_t numTypeErasedParams;
17601761 bool typeErasedParamsInitialized;
17611762
1762- SpecializeAttr (SourceLoc atLoc, SourceRange Range,
1763- TrailingWhereClause *clause, bool exported,
1763+ protected:
1764+ AbstractSpecializeAttr (DeclAttrKind DK, SourceLoc atLoc, SourceRange Range,
1765+ TrailingWhereClause *clause,
1766+ bool exported,
17641767 SpecializationKind kind, GenericSignature specializedSignature,
17651768 DeclNameRef targetFunctionName, ArrayRef<Identifier> spiGroups,
17661769 ArrayRef<AvailableAttr *> availabilityAttrs,
17671770 size_t typeErasedParamsCount);
17681771
17691772public:
1770- static SpecializeAttr *
1771- create (ASTContext &Ctx, SourceLoc atLoc, SourceRange Range,
1772- TrailingWhereClause *clause, bool exported, SpecializationKind kind,
1773- DeclNameRef targetFunctionName, ArrayRef<Identifier> spiGroups,
1774- ArrayRef<AvailableAttr *> availabilityAttrs,
1775- GenericSignature specializedSignature = nullptr );
1776-
1777- static SpecializeAttr *create (ASTContext &ctx, bool exported,
1778- SpecializationKind kind,
1779- ArrayRef<Identifier> spiGroups,
1780- ArrayRef<AvailableAttr *> availabilityAttrs,
1781- GenericSignature specializedSignature,
1782- DeclNameRef replacedFunction);
1783-
1784- static SpecializeAttr *create (ASTContext &ctx, bool exported,
1785- SpecializationKind kind,
1786- ArrayRef<Identifier> spiGroups,
1787- ArrayRef<AvailableAttr *> availabilityAttrs,
1788- ArrayRef<Type> typeErasedParams,
1789- GenericSignature specializedSignature,
1790- DeclNameRef replacedFunction,
1791- LazyMemberLoader *resolver, uint64_t data);
1792-
17931773 size_t numTrailingObjects (OverloadToken<Identifier>) const {
17941774 return numSPIGroups;
17951775 }
17961776
17971777 size_t numTrailingObjects (OverloadToken<AvailableAttr *>) const {
17981778 return numAvailableAttrs;
17991779 }
1780+ // Helper to get the trailing objects of one of the subclasses.
1781+ template <typename Type>
1782+ const Type *getSubclassTrailingObjects () const ;
1783+
1784+ template <typename Type>
1785+ Type *getSubclassTrailingObjects () {
1786+ const auto *constThis = this ;
1787+ return const_cast <Type*>(constThis->getSubclassTrailingObjects <Type>());
1788+ }
1789+
18001790 // / Name of SPIs declared by the attribute.
18011791 // /
18021792 // / Note: A single SPI name per attribute is currently supported but this
18031793 // / may change with the syntax change.
18041794 ArrayRef<Identifier> getSPIGroups () const {
1805- return { this -> template getTrailingObjects <Identifier>(),
1795+ return { getSubclassTrailingObjects <Identifier>(),
18061796 numSPIGroups };
18071797 }
18081798
18091799 ArrayRef<AvailableAttr *> getAvailableAttrs () const {
1810- return {this -> template getTrailingObjects <AvailableAttr *>(),
1800+ return {getSubclassTrailingObjects <AvailableAttr *>(),
18111801 numAvailableAttrs};
18121802 }
18131803
18141804 ArrayRef<Type> getTypeErasedParams () const {
18151805 if (!typeErasedParamsInitialized)
18161806 return {};
18171807
1818- return {this -> template getTrailingObjects <Type>(),
1808+ return {getSubclassTrailingObjects <Type>(),
18191809 numTypeErasedParams};
18201810 }
18211811
18221812 void setTypeErasedParams (const ArrayRef<Type> typeErasedParams) {
18231813 assert (typeErasedParams.size () == numTypeErasedParams);
18241814 if (!typeErasedParamsInitialized) {
1825- std::uninitialized_copy (typeErasedParams.begin (), typeErasedParams.end (), getTrailingObjects<Type>());
1815+ std::uninitialized_copy (typeErasedParams.begin (), typeErasedParams.end (),
1816+ getSubclassTrailingObjects<Type>());
18261817 typeErasedParamsInitialized = true ;
18271818 }
18281819 }
18291820
1821+ void setResolver (LazyMemberLoader *resolver, uint64_t resolverContextData) {
1822+ this ->resolver = resolver;
1823+ this ->resolverContextData = resolverContextData;
1824+ }
1825+
18301826 TrailingWhereClause *getTrailingWhereClause () const ;
18311827
1828+ bool isPublic () const {
1829+ return getKind () == DeclAttrKind::Specialized;
1830+ }
1831+
18321832 bool isExported () const {
1833- return Bits.SpecializeAttr .exported ;
1833+ return Bits.AbstractSpecializeAttr .exported ;
18341834 }
18351835
18361836 SpecializationKind getSpecializationKind () const {
1837- return SpecializationKind (Bits.SpecializeAttr .kind );
1837+ return SpecializationKind (Bits.AbstractSpecializeAttr .kind );
18381838 }
18391839
18401840 bool isFullSpecialization () const {
@@ -1856,15 +1856,140 @@ class SpecializeAttr final
18561856 GenericSignature
18571857 getSpecializedSignature (const AbstractFunctionDecl *forDecl) const ;
18581858
1859+ static bool classof (const DeclAttribute *DA) {
1860+ return DA->getKind () == DeclAttrKind::Specialize ||
1861+ DA->getKind () == DeclAttrKind::Specialized;
1862+ }
1863+
1864+ UNIMPLEMENTED_CLONE (AbstractSpecializeAttr)
1865+
1866+ bool isEquivalent (const AbstractSpecializeAttr *other, Decl *attachedTo) const ;
1867+ };
1868+
1869+ // / The @_specialize attribute.
1870+ class SpecializeAttr final : public AbstractSpecializeAttr,
1871+ private SpecializeAttrTrailingObjects<SpecializeAttr> {
1872+ friend TrailingObjects;
1873+ friend AbstractSpecializeAttr;
1874+
1875+ // WARNING: Do not add storage here. The base class uses TrailingObjects.
1876+ private:
1877+ SpecializeAttr (SourceLoc atLoc, SourceRange Range,
1878+ TrailingWhereClause *clause,
1879+ bool exported,
1880+ SpecializationKind kind, GenericSignature specializedSignature,
1881+ DeclNameRef targetFunctionName, ArrayRef<Identifier> spiGroups,
1882+ ArrayRef<AvailableAttr *> availabilityAttrs,
1883+ size_t typeErasedParamsCount) :
1884+ AbstractSpecializeAttr (DeclAttrKind::Specialize, atLoc, Range, clause,
1885+ exported, kind, specializedSignature, targetFunctionName,
1886+ spiGroups, availabilityAttrs, typeErasedParamsCount) {}
1887+
1888+ public:
1889+ static SpecializeAttr *
1890+ create (ASTContext &Ctx, SourceLoc atLoc, SourceRange Range,
1891+ TrailingWhereClause *clause, bool exported,
1892+ SpecializationKind kind,
1893+ DeclNameRef targetFunctionName, ArrayRef<Identifier> spiGroups,
1894+ ArrayRef<AvailableAttr *> availabilityAttrs,
1895+ GenericSignature specializedSignature = nullptr );
1896+
1897+ static SpecializeAttr *create (ASTContext &ctx, bool exported,
1898+ SpecializationKind kind,
1899+ ArrayRef<Identifier> spiGroups,
1900+ ArrayRef<AvailableAttr *> availabilityAttrs,
1901+ GenericSignature specializedSignature,
1902+ DeclNameRef replacedFunction);
1903+
1904+ static SpecializeAttr *create (ASTContext &ctx, bool exported,
1905+ SpecializationKind kind,
1906+ ArrayRef<Identifier> spiGroups,
1907+ ArrayRef<AvailableAttr *> availabilityAttrs,
1908+ ArrayRef<Type> typeErasedParams,
1909+ GenericSignature specializedSignature,
1910+ DeclNameRef replacedFunction,
1911+ LazyMemberLoader *resolver, uint64_t data);
1912+
18591913 static bool classof (const DeclAttribute *DA) {
18601914 return DA->getKind () == DeclAttrKind::Specialize;
18611915 }
18621916
18631917 UNIMPLEMENTED_CLONE (SpecializeAttr)
18641918
1865- bool isEquivalent (const SpecializeAttr *other, Decl *attachedTo) const ;
1919+ bool isEquivalent (const SpecializeAttr *other, Decl *attachedTo) const {
1920+ return AbstractSpecializeAttr::isEquivalent (other, attachedTo);
1921+ }
18661922};
18671923
1924+ // / The @specialized attribute.
1925+ class SpecializedAttr final : public AbstractSpecializeAttr ,
1926+ private SpecializeAttrTrailingObjects<SpecializeAttr> {
1927+ friend TrailingObjects;
1928+ friend AbstractSpecializeAttr;
1929+
1930+ // WARNING: Do not add storage here. The base class uses TrailingObjects.
1931+ private:
1932+
1933+ SpecializedAttr (SourceLoc atLoc, SourceRange Range,
1934+ TrailingWhereClause *clause,
1935+ bool exported,
1936+ SpecializationKind kind, GenericSignature specializedSignature,
1937+ DeclNameRef targetFunctionName, ArrayRef<Identifier> spiGroups,
1938+ ArrayRef<AvailableAttr *> availabilityAttrs,
1939+ size_t typeErasedParamsCount) :
1940+ AbstractSpecializeAttr (DeclAttrKind::Specialized, atLoc, Range, clause,
1941+ exported, kind, specializedSignature, targetFunctionName,
1942+ spiGroups, availabilityAttrs, typeErasedParamsCount) {}
1943+
1944+ public:
1945+ static SpecializedAttr *
1946+ create (ASTContext &Ctx, SourceLoc atLoc, SourceRange Range,
1947+ TrailingWhereClause *clause, bool exported,
1948+ SpecializationKind kind,
1949+ DeclNameRef targetFunctionName, ArrayRef<Identifier> spiGroups,
1950+ ArrayRef<AvailableAttr *> availabilityAttrs,
1951+ GenericSignature specializedSignature = nullptr );
1952+
1953+ static SpecializedAttr *create (ASTContext &ctx, bool exported,
1954+ SpecializationKind kind,
1955+ ArrayRef<Identifier> spiGroups,
1956+ ArrayRef<AvailableAttr *> availabilityAttrs,
1957+ GenericSignature specializedSignature,
1958+ DeclNameRef replacedFunction);
1959+
1960+ static SpecializedAttr *create (ASTContext &ctx, bool exported,
1961+ SpecializationKind kind,
1962+ ArrayRef<Identifier> spiGroups,
1963+ ArrayRef<AvailableAttr *> availabilityAttrs,
1964+ ArrayRef<Type> typeErasedParams,
1965+ GenericSignature specializedSignature,
1966+ DeclNameRef replacedFunction,
1967+ LazyMemberLoader *resolver, uint64_t data);
1968+
1969+ static bool classof (const DeclAttribute *DA) {
1970+ return DA->getKind () == DeclAttrKind::Specialized;
1971+ }
1972+
1973+ UNIMPLEMENTED_CLONE (SpecializedAttr)
1974+
1975+ bool isEquivalent (const SpecializedAttr *other, Decl *attachedTo) const {
1976+ return AbstractSpecializeAttr::isEquivalent (other, attachedTo);
1977+ }
1978+ };
1979+
1980+ template <typename Type>
1981+ const Type *AbstractSpecializeAttr::getSubclassTrailingObjects () const {
1982+ if (auto attr = dyn_cast<SpecializedAttr>(this )) {
1983+ return attr->getTrailingObjects <Type>();
1984+ }
1985+ if (auto attr = dyn_cast<SpecializeAttr>(this )) {
1986+ return attr->getTrailingObjects <Type>();
1987+ }
1988+ llvm_unreachable (" unhandled AbstractSpecializeAttr subclass?" );
1989+ }
1990+
1991+
1992+
18681993class StorageRestrictionsAttr final
18691994 : public DeclAttribute,
18701995 private llvm::TrailingObjects<StorageRestrictionsAttr, Identifier> {
0 commit comments