From a28ba16927e269339385c19cbb8c0630bff31d42 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Tue, 13 Sep 2016 16:45:29 +0000 Subject: [PATCH] Add a class ObjCProtocolQualifiers to wrap APIs for ObjC protocol list. Now ObjCObjectType extends from ObjCProtocolQualifiers. We save number of protocols in ObjCProtocolQualifiers. This is in preparation of adding a new type class ObjCTypeParamType that can take protocol qualifiers. rdar://24619481 rdar://25060179 Differential Revision: http://reviews.llvm.org/D23078 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@281351 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Type.h | 97 +++++++++++++++++++++++++++------------- lib/AST/Type.cpp | 9 ++-- 2 files changed, 69 insertions(+), 37 deletions(-) diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 6bbba48a9c..ed74832c01 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -4699,6 +4699,59 @@ public: } }; +/// This class wraps the list of protocol qualifiers. For types that can +/// take ObjC protocol qualifers, they can subclass this class. +template +class ObjCProtocolQualifiers { +protected: + ObjCProtocolQualifiers() {} + ObjCProtocolDecl * const *getProtocolStorage() const { + return const_cast(this)->getProtocolStorage(); + } + + ObjCProtocolDecl **getProtocolStorage() { + return static_cast(this)->getProtocolStorageImpl(); + } + void setNumProtocols(unsigned N) { + static_cast(this)->setNumProtocolsImpl(N); + } + void initialize(ArrayRef 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_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(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 getProtocols() const { + return ArrayRef(qual_begin(), getNumProtocols()); + } +}; + /// Represents a class type in Objective C. /// /// Every Objective C type is a combination of a base type, a set of @@ -4727,7 +4780,9 @@ public: /// 'id

' 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 { +class ObjCObjectType : public Type, + public ObjCProtocolQualifiers { + friend class ObjCProtocolQualifiers; // ObjCObjectType.NumTypeArgs - the number of type arguments stored // after the ObjCObjectPointerType node. // ObjCObjectType.NumProtocols - the number of protocols stored @@ -4747,16 +4802,20 @@ class ObjCObjectType : public Type { mutable llvm::PointerIntPair CachedSuperClassType; - ObjCProtocolDecl * const *getProtocolStorage() const { - return const_cast(this)->getProtocolStorage(); - } - QualType *getTypeArgStorage(); const QualType *getTypeArgStorage() const { return const_cast(this)->getTypeArgStorage(); } - ObjCProtocolDecl **getProtocolStorage(); + 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; + } protected: ObjCObjectType(QualType Canonical, QualType Base, @@ -4833,30 +4892,6 @@ public: ObjCObjectTypeBits.NumTypeArgs); } - typedef ObjCProtocolDecl * const *qual_iterator; - typedef llvm::iterator_range 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 getProtocols() const { - return ArrayRef(qual_begin(), getNumProtocols()); - } - /// Whether this is a "__kindof" type as written. bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; } @@ -4919,7 +4954,7 @@ inline QualType *ObjCObjectType::getTypeArgStorage() { return reinterpret_cast(static_cast(this)+1); } -inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { +inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() { return reinterpret_cast( getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs); } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 4c1d4ec540..2629aecbe5 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -546,15 +546,9 @@ ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, 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()) @@ -565,6 +559,9 @@ ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, 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 { -- 2.40.0