}
};
-/// This class wraps the list of protocol qualifiers. For types that can
-/// take ObjC protocol qualifers, they can subclass this class.
-template <class T>
-class ObjCProtocolQualifiers {
-protected:
- ObjCProtocolQualifiers() {}
- ObjCProtocolDecl * const *getProtocolStorage() const {
- return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage();
- }
-
- ObjCProtocolDecl **getProtocolStorage() {
- return static_cast<T*>(this)->getProtocolStorageImpl();
- }
- void setNumProtocols(unsigned N) {
- static_cast<T*>(this)->setNumProtocolsImpl(N);
- }
- void initialize(ArrayRef<ObjCProtocolDecl *> protocols) {
- setNumProtocols(protocols.size());
- assert(getNumProtocols() == protocols.size() &&
- "bitfield overflow in protocol count");
- if (!protocols.empty())
- memcpy(getProtocolStorage(), protocols.data(),
- protocols.size() * sizeof(ObjCProtocolDecl*));
- }
-
-public:
- typedef ObjCProtocolDecl * const *qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
-
- qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
- qual_iterator qual_begin() const { return getProtocolStorage(); }
- qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
-
- bool qual_empty() const { return getNumProtocols() == 0; }
-
- /// Return the number of qualifying protocols in this type, or 0 if
- /// there are none.
- unsigned getNumProtocols() const {
- return static_cast<const T*>(this)->getNumProtocolsImpl();
- }
-
- /// Fetch a protocol by index.
- ObjCProtocolDecl *getProtocol(unsigned I) const {
- assert(I < getNumProtocols() && "Out-of-range protocol access");
- return qual_begin()[I];
- }
-
- /// Retrieve all of the protocol qualifiers.
- ArrayRef<ObjCProtocolDecl *> getProtocols() const {
- return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
- }
-};
-
/// Represents a class type in Objective C.
///
/// Every Objective C type is a combination of a base type, a set of
/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
/// this should get its own sugar class to better represent the source.
-class ObjCObjectType : public Type,
- public ObjCProtocolQualifiers<ObjCObjectType> {
- template <class T> friend class ObjCProtocolQualifiers;
+class ObjCObjectType : public Type {
// ObjCObjectType.NumTypeArgs - the number of type arguments stored
// after the ObjCObjectPointerType node.
// ObjCObjectType.NumProtocols - the number of protocols stored
mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
CachedSuperClassType;
+ ObjCProtocolDecl * const *getProtocolStorage() const {
+ return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
+ }
+
QualType *getTypeArgStorage();
const QualType *getTypeArgStorage() const {
return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
}
- ObjCProtocolDecl **getProtocolStorageImpl();
- /// Return the number of qualifying protocols in this interface type,
- /// or 0 if there are none.
- unsigned getNumProtocolsImpl() const {
- return ObjCObjectTypeBits.NumProtocols;
- }
- void setNumProtocolsImpl(unsigned N) {
- ObjCObjectTypeBits.NumProtocols = N;
- }
+ ObjCProtocolDecl **getProtocolStorage();
protected:
ObjCObjectType(QualType Canonical, QualType Base,
ObjCObjectTypeBits.NumTypeArgs);
}
+ typedef ObjCProtocolDecl * const *qual_iterator;
+ typedef llvm::iterator_range<qual_iterator> qual_range;
+
+ qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
+ qual_iterator qual_begin() const { return getProtocolStorage(); }
+ qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+ bool qual_empty() const { return getNumProtocols() == 0; }
+
+ /// Return the number of qualifying protocols in this interface type,
+ /// or 0 if there are none.
+ unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
+
+ /// Fetch a protocol by index.
+ ObjCProtocolDecl *getProtocol(unsigned I) const {
+ assert(I < getNumProtocols() && "Out-of-range protocol access");
+ return qual_begin()[I];
+ }
+
+ /// Retrieve all of the protocol qualifiers.
+ ArrayRef<ObjCProtocolDecl *> getProtocols() const {
+ return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
+ }
+
/// Whether this is a "__kindof" type as written.
bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
}
-inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() {
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
return reinterpret_cast<ObjCProtocolDecl**>(
getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
}
ObjCObjectTypeBits.NumTypeArgs = typeArgs.size();
assert(getTypeArgsAsWritten().size() == typeArgs.size() &&
"bitfield overflow in type argument count");
+ ObjCObjectTypeBits.NumProtocols = protocols.size();
+ assert(getNumProtocols() == protocols.size() &&
+ "bitfield overflow in protocol count");
if (!typeArgs.empty())
memcpy(getTypeArgStorage(), typeArgs.data(),
typeArgs.size() * sizeof(QualType));
+ if (!protocols.empty())
+ memcpy(getProtocolStorage(), protocols.data(),
+ protocols.size() * sizeof(ObjCProtocolDecl*));
for (auto typeArg : typeArgs) {
if (typeArg->isDependentType())
if (typeArg->containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack();
}
- // Initialize the protocol qualifiers. The protocol storage is known
- // after we set number of type arguments.
- initialize(protocols);
}
bool ObjCObjectType::isSpecialized() const {