diff options
author | John McCall <rjmccall@apple.com> | 2010-05-15 11:32:37 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-05-15 11:32:37 +0000 |
commit | c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44e (patch) | |
tree | f6b386f56c0925da061036cb04ba79a0bff05d91 | |
parent | d86c477fb5d3fc34864afecbbb5443da9355e8fb (diff) |
Substantially alter the design of the Objective C type AST by introducing
ObjCObjectType, which is basically just a pair of
one of {primitive-id, primitive-Class, user-defined @class}
with
a list of protocols.
An ObjCObjectPointerType is therefore just a pointer which always points to
one of these types (possibly sugared). ObjCInterfaceType is now just a kind
of ObjCObjectType which happens to not carry any protocols.
Alter a rather large number of use sites to use ObjCObjectType instead of
ObjCInterfaceType. Store an ObjCInterfaceType as a pointer on the decl rather
than hashing them in a FoldingSet. Remove some number of methods that are no
longer used, at least after this patch.
By simplifying ObjCObjectPointerType, we are now able to easily remove and apply
pointers to Objective-C types, which is crucial for a certain kind of ObjC++
metaprogramming common in WebKit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103870 91177308-0d34-0410-b5e6-96231b3b80d8
44 files changed, 747 insertions, 623 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index a53d803ecd..d1646e00d6 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -98,7 +98,7 @@ class ASTContext { llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes; llvm::FoldingSet<ElaboratedType> ElaboratedTypes; llvm::FoldingSet<DependentNameType> DependentNameTypes; - llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes; + llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes; llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; @@ -624,16 +624,15 @@ public: const TemplateSpecializationType *TemplateId, QualType Canon = QualType()); - QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, - ObjCProtocolDecl **Protocols = 0, - unsigned NumProtocols = 0); + QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl); - /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the - /// given interface decl and the conforming protocol list. - QualType getObjCObjectPointerType(QualType OIT, - ObjCProtocolDecl **ProtocolList = 0, - unsigned NumProtocols = 0, - unsigned Quals = 0); + QualType getObjCObjectType(QualType Base, + ObjCProtocolDecl * const *Protocols, + unsigned NumProtocols); + + /// getObjCObjectPointerType - Return a ObjCObjectPointerType type + /// for the given ObjCObjectType. + QualType getObjCObjectPointerType(QualType OIT); /// getTypeOfType - GCC extension. QualType getTypeOfExprType(Expr *e); @@ -1182,8 +1181,8 @@ public: // Check the safety of assignment from LHS to RHS bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); - bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS, - const ObjCInterfaceType *RHS); + bool canAssignObjCInterfaces(const ObjCObjectType *LHS, + const ObjCObjectType *RHS); bool canAssignObjCInterfacesInBlockPointer( const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 93dcad7512..4afb81dd05 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -643,6 +643,24 @@ struct CanProxyAdaptor<TemplateTypeParmType> }; template<> +struct CanProxyAdaptor<ObjCObjectType> + : public CanProxyBase<ObjCObjectType> { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *, + getInterface) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) + + typedef ObjCObjectPointerType::qual_iterator qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols) +}; + +template<> struct CanProxyAdaptor<ObjCObjectPointerType> : public CanProxyBase<ObjCObjectPointerType> { LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType) diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index a7a13409eb..36b151ddf3 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -623,6 +623,17 @@ case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S); template<typename Derived> bool RecursiveASTVisitor<Derived>::VisitObjCInterfaceType( ObjCInterfaceType *T) { + return getDerived().VisitObjCObjectType(T); + } + + template<typename Derived> + bool RecursiveASTVisitor<Derived>::VisitObjCObjectType(ObjCObjectType *T) { + // We have to watch out here because an ObjCInterfaceType's base + // type is itself. + if (T->getBaseType().getTypePtr() != T) + if (Visit(T->getBaseType())) + return true; + return getDerived().VisitType(T); } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 49022a8a61..b957708e3e 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -755,6 +755,9 @@ public: }; private: + Type(const Type&); // DO NOT IMPLEMENT. + void operator=(const Type&); // DO NOT IMPLEMENT. + QualType CanonicalType; /// TypeClass bitfield - Enum that specifies what subclass this belongs to. @@ -765,9 +768,9 @@ private: /// subclasses can pack their bitfields into the same word. bool Dependent : 1; - Type(const Type&); // DO NOT IMPLEMENT. - void operator=(const Type&); // DO NOT IMPLEMENT. protected: + enum { BitsRemainingInType = 23 }; + // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } Type(TypeClass tc, QualType Canonical, bool dependent) @@ -879,7 +882,7 @@ public: bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object. // FIXME: change this to 'raw' interface type, so we can used 'interface' type // for the common case. - bool isObjCInterfaceType() const; // NSString or NSString<foo> + bool isObjCObjectType() const; // NSString or typeof(*(id)0) bool isObjCQualifiedInterfaceType() const; // NSString<foo> bool isObjCQualifiedIdType() const; // id<foo> bool isObjCQualifiedClassType() const; // Class<foo> @@ -920,7 +923,7 @@ public: // for object declared using an interface. const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; - const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const; + const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; const CXXRecordDecl *getCXXRecordDeclForPointerType() const; /// \brief Retrieves the CXXRecordDecl that this type refers to, either @@ -935,10 +938,6 @@ public: // immediately following this class. template <typename T> const T *getAs() const; - /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC - /// interface, return the interface type, otherwise return null. - const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const; - /// getArrayElementTypeNoTypeQual - If this is an array type, return the /// element type of the array, potentially with type qualifiers missing. /// This method should never be used when type qualifiers are meaningful. @@ -2750,65 +2749,184 @@ public: static bool classof(const DependentNameType *T) { return true; } }; -/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for -/// object oriented design. They basically correspond to C++ classes. There -/// are two kinds of interface types, normal interfaces like "NSString" and -/// qualified interfaces, which are qualified with a protocol list like -/// "NSString<NSCopyable, NSAmazing>". -class ObjCInterfaceType : public Type, public llvm::FoldingSetNode { - ObjCInterfaceDecl *Decl; +/// ObjCObjectType - Represents a class type in Objective C. +/// Every Objective C type is a combination of a base type and a +/// list of protocols. +/// +/// Given the following declarations: +/// @class C; +/// @protocol P; +/// +/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType +/// with base C and no protocols. +/// +/// 'C<P>' is an ObjCObjectType with base C and protocol list [P]. +/// +/// 'id' is a TypedefType which is sugar for an ObjCPointerType with +/// base BuiltinType::ObjCIdType and no protocols. +/// +/// 'id<P>' is an ObjCPointerType 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 { + // Pad the bit count up so that NumProtocols is 2-byte aligned + unsigned : BitsRemainingInType - 16; + + /// \brief The number of protocols stored after the + /// ObjCObjectPointerType node. + /// + /// In the canonical object type, these are sorted alphabetically + /// and uniqued. + unsigned NumProtocols : 16; - /// \brief The number of protocols stored after the ObjCInterfaceType node. - /// The list of protocols is sorted on protocol name. No protocol is enterred - /// more than once. - unsigned NumProtocols; + /// Either a BuiltinType or an InterfaceType or sugar for either. + QualType BaseType; + + ObjCProtocolDecl * const *getProtocolStorage() const { + return const_cast<ObjCObjectType*>(this)->getProtocolStorage(); + } + + ObjCProtocolDecl **getProtocolStorage(); + +protected: + ObjCObjectType(QualType Canonical, QualType Base, + ObjCProtocolDecl * const *Protocols, unsigned NumProtocols); + + enum Nonce_ObjCInterface { Nonce_ObjCInterface }; + ObjCObjectType(enum Nonce_ObjCInterface) + : Type(ObjCInterface, QualType(), false), + NumProtocols(0), + BaseType(QualType(this_(), 0)) {} - ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D, - ObjCProtocolDecl **Protos, unsigned NumP); - friend class ASTContext; // ASTContext creates these. public: - void Destroy(ASTContext& C); + QualType getBaseType() const { return BaseType; } - ObjCInterfaceDecl *getDecl() const { return Decl; } + bool isObjCId() const { + return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); + } + bool isObjCClass() const { + return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); + } + bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } + bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } + bool isObjCUnqualifiedIdOrClass() const { + if (!qual_empty()) return false; + if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) + return T->getKind() == BuiltinType::ObjCId || + T->getKind() == BuiltinType::ObjCClass; + return false; + } + bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } + bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } + + /// Gets the interface declaration for this object type, if the base type + /// really is an interface. + ObjCInterfaceDecl *getInterface() const; + + typedef ObjCProtocolDecl * const *qual_iterator; + + qual_iterator qual_begin() const { return getProtocolStorage(); } + qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } + + bool qual_empty() const { return getNumProtocols() == 0; } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. unsigned getNumProtocols() const { return NumProtocols; } - /// \brief Retrieve the Ith protocol. + /// \brief Fetch a protocol by index. ObjCProtocolDecl *getProtocol(unsigned I) const { assert(I < getNumProtocols() && "Out-of-range protocol access"); return qual_begin()[I]; } - /// qual_iterator and friends: this provides access to the (potentially empty) - /// list of protocols qualifying this interface. - typedef ObjCProtocolDecl* const * qual_iterator; - qual_iterator qual_begin() const { - return reinterpret_cast<qual_iterator>(this + 1); - } - qual_iterator qual_end() const { - return qual_begin() + NumProtocols; - } - bool qual_empty() const { return NumProtocols == 0; } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } + Linkage getLinkage() const; // key function + + static bool classof(const Type *T) { + return T->getTypeClass() == ObjCObject || + T->getTypeClass() == ObjCInterface; + } + static bool classof(const ObjCObjectType *) { return true; } +}; + +/// ObjCObjectTypeImpl - A class providing a concrete implementation +/// of ObjCObjectType, so as to not increase the footprint of +/// ObjCInterfaceType. Code outside of ASTContext and the core type +/// system should not reference this type. +class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { + friend class ASTContext; + + // If anyone adds fields here, ObjCObjectType::getProtocolStorage() + // will need to be modified. + + ObjCObjectTypeImpl(QualType Canonical, QualType Base, + ObjCProtocolDecl * const *Protocols, + unsigned NumProtocols) + : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {} + +public: + void Destroy(ASTContext& C); // key function + void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, - const ObjCInterfaceDecl *Decl, - ObjCProtocolDecl * const *protocols, - unsigned NumProtocols); + QualType Base, + ObjCProtocolDecl *const *protocols, + unsigned NumProtocols); +}; - virtual Linkage getLinkage() const; +inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { + return reinterpret_cast<ObjCProtocolDecl**>( + static_cast<ObjCObjectTypeImpl*>(this) + 1); +} + +/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for +/// object oriented design. They basically correspond to C++ classes. There +/// are two kinds of interface types, normal interfaces like "NSString" and +/// qualified interfaces, which are qualified with a protocol list like +/// "NSString<NSCopyable, NSAmazing>". +class ObjCInterfaceType : public ObjCObjectType { + ObjCInterfaceDecl *Decl; + + ObjCInterfaceType(const ObjCInterfaceDecl *D) + : ObjCObjectType(Nonce_ObjCInterface), + Decl(const_cast<ObjCInterfaceDecl*>(D)) {} + friend class ASTContext; // ASTContext creates these. +public: + void Destroy(ASTContext& C); // key function + + ObjCInterfaceDecl *getDecl() const { return Decl; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } static bool classof(const Type *T) { return T->getTypeClass() == ObjCInterface; } static bool classof(const ObjCInterfaceType *) { return true; } + + // Nonsense to "hide" certain members of ObjCObjectType within this + // class. People asking for protocols on an ObjCInterfaceType are + // not going to get what they want: ObjCInterfaceTypes are + // guaranteed to have no protocols. + enum { + qual_iterator, + qual_begin, + qual_end, + getNumProtocols, + getProtocol + }; }; +inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { + if (const ObjCInterfaceType *T = + getBaseType()->getAs<ObjCInterfaceType>()) + return T->getDecl(); + return 0; +} + /// ObjCObjectPointerType - Used to represent 'id', 'Interface *', 'id <p>', /// and 'Interface <p> *'. /// @@ -2817,15 +2935,9 @@ public: class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; // A builtin or interface type. - /// \brief The number of protocols stored after the ObjCObjectPointerType - /// node. - /// - /// The list of protocols is sorted on protocol name. No protocol is enterred - /// more than once. - unsigned NumProtocols; - - ObjCObjectPointerType(QualType Canonical, QualType T, - ObjCProtocolDecl **Protos, unsigned NumP); + ObjCObjectPointerType(QualType Canonical, QualType Pointee) + : Type(ObjCObjectPointer, Canonical, false), + PointeeType(Pointee) {} friend class ASTContext; // ASTContext creates these. public: @@ -2838,8 +2950,12 @@ public: // For example: typedef NSObject T; T *var; QualType getPointeeType() const { return PointeeType; } + const ObjCObjectType *getObjectType() const { + return PointeeType->getAs<ObjCObjectType>(); + } + const ObjCInterfaceType *getInterfaceType() const { - return PointeeType->getAs<ObjCInterfaceType>(); + return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>(); } /// getInterfaceDecl - returns an interface decl for user-defined types. ObjCInterfaceDecl *getInterfaceDecl() const { @@ -2847,45 +2963,42 @@ public: } /// isObjCIdType - true for "id". bool isObjCIdType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - !NumProtocols; + return getObjectType()->isObjCUnqualifiedId(); } /// isObjCClassType - true for "Class". bool isObjCClassType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - !NumProtocols; + return getObjectType()->isObjCUnqualifiedClass(); } /// isObjCQualifiedIdType - true for "id <p>". bool isObjCQualifiedIdType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - NumProtocols; + return getObjectType()->isObjCQualifiedId(); } /// isObjCQualifiedClassType - true for "Class <p>". bool isObjCQualifiedClassType() const { - return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - NumProtocols; + return getObjectType()->isObjCQualifiedClass(); } /// qual_iterator and friends: this provides access to the (potentially empty) /// list of protocols qualifying this interface. - typedef ObjCProtocolDecl* const * qual_iterator; + typedef ObjCObjectType::qual_iterator qual_iterator; qual_iterator qual_begin() const { - return reinterpret_cast<qual_iterator> (this + 1); + return getObjectType()->qual_begin(); } - qual_iterator qual_end() const { - return qual_begin() + NumProtocols; + qual_iterator qual_end() const { + return getObjectType()->qual_end(); } - bool qual_empty() const { return NumProtocols == 0; } + bool qual_empty() const { return getObjectType()->qual_empty(); } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. - unsigned getNumProtocols() const { return NumProtocols; } + unsigned getNumProtocols() const { + return getObjectType()->getNumProtocols(); + } /// \brief Retrieve the Ith protocol. ObjCProtocolDecl *getProtocol(unsigned I) const { - assert(I < getNumProtocols() && "Out-of-range protocol access"); - return qual_begin()[I]; + return getObjectType()->getProtocol(I); } bool isSugared() const { return false; } @@ -2894,9 +3007,9 @@ public: virtual Linkage getLinkage() const; void Profile(llvm::FoldingSetNodeID &ID); - static void Profile(llvm::FoldingSetNodeID &ID, QualType T, - ObjCProtocolDecl *const *protocols, - unsigned NumProtocols); + static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { + ID.AddPointer(T.getAsOpaquePtr()); + } static bool classof(const Type *T) { return T->getTypeClass() == ObjCObjectPointer; } @@ -3135,12 +3248,6 @@ inline QualType QualType::getNonReferenceType() const { return *this; } -inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const { - if (const PointerType *PT = getAs<PointerType>()) - return PT->getPointeeType()->getAs<ObjCInterfaceType>(); - return 0; -} - inline bool Type::isFunctionType() const { return isa<FunctionType>(CanonicalType); } @@ -3207,8 +3314,8 @@ inline bool Type::isExtVectorType() const { inline bool Type::isObjCObjectPointerType() const { return isa<ObjCObjectPointerType>(CanonicalType); } -inline bool Type::isObjCInterfaceType() const { - return isa<ObjCInterfaceType>(CanonicalType); +inline bool Type::isObjCObjectType() const { + return isa<ObjCObjectType>(CanonicalType); } inline bool Type::isObjCQualifiedIdType() const { if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) @@ -3257,13 +3364,11 @@ inline bool Type::isOverloadableType() const { inline bool Type::hasPointerRepresentation() const { return (isPointerType() || isReferenceType() || isBlockPointerType() || - isObjCInterfaceType() || isObjCObjectPointerType() || - isObjCQualifiedInterfaceType() || isNullPtrType()); + isObjCObjectPointerType() || isNullPtrType()); } inline bool Type::hasObjCPointerRepresentation() const { - return (isObjCInterfaceType() || isObjCObjectPointerType() || - isObjCQualifiedInterfaceType()); + return isObjCObjectPointerType(); } /// Insertion operator for diagnostics. This allows sending QualType's into a diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 9927ae7edb..4896fe948b 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -559,6 +559,7 @@ class SubstTemplateTypeParmTypeLoc : struct ObjCProtocolListLocInfo { SourceLocation LAngleLoc; SourceLocation RAngleLoc; + bool HasBaseType; }; // A helper class for defining ObjC TypeLocs that can qualified with @@ -566,24 +567,15 @@ struct ObjCProtocolListLocInfo { // // TypeClass basically has to be either ObjCInterfaceType or // ObjCObjectPointerType. -template <class Derived, class TypeClass, class LocalData> -class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, - Derived, - TypeClass, - LocalData> { +class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + ObjCObjectTypeLoc, + ObjCObjectType, + ObjCProtocolListLocInfo> { // SourceLocations are stored after Info, one for each Protocol. SourceLocation *getProtocolLocArray() const { return (SourceLocation*) this->getExtraLocalData(); } -protected: - void initializeLocalBase(SourceLocation Loc) { - setLAngleLoc(Loc); - setRAngleLoc(Loc); - for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) - setProtocolLoc(i, Loc); - } - public: SourceLocation getLAngleLoc() const { return this->getLocalData()->LAngleLoc; @@ -617,29 +609,48 @@ public: return *(this->getTypePtr()->qual_begin() + i); } + bool hasBaseTypeAsWritten() const { + return getLocalData()->HasBaseType; + } + + void setHasBaseTypeAsWritten(bool HasBaseType) { + getLocalData()->HasBaseType = HasBaseType; + } + + TypeLoc getBaseLoc() const { + return getInnerTypeLoc(); + } + SourceRange getSourceRange() const { return SourceRange(getLAngleLoc(), getRAngleLoc()); } void initializeLocal(SourceLocation Loc) { - initializeLocalBase(Loc); + setLAngleLoc(Loc); + setRAngleLoc(Loc); + for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) + setProtocolLoc(i, Loc); } unsigned getExtraLocalDataSize() const { return this->getNumProtocols() * sizeof(SourceLocation); } + + QualType getInnerType() const { + return getTypePtr()->getBaseType(); + } }; -struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo { +struct ObjCInterfaceLocInfo { SourceLocation NameLoc; }; /// \brief Wrapper for source info for ObjC interfaces. -class ObjCInterfaceTypeLoc : - public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc, - ObjCInterfaceType, - ObjCInterfaceLocInfo> { +class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + ObjCInterfaceTypeLoc, + ObjCInterfaceType, + ObjCInterfaceLocInfo> { public: ObjCInterfaceDecl *getIFaceDecl() const { return getTypePtr()->getDecl(); @@ -654,84 +665,15 @@ public: } SourceRange getSourceRange() const { - if (getNumProtocols()) - return SourceRange(getNameLoc(), getRAngleLoc()); - else - return SourceRange(getNameLoc(), getNameLoc()); + return SourceRange(getNameLoc()); } void initializeLocal(SourceLocation Loc) { - initializeLocalBase(Loc); setNameLoc(Loc); } }; -struct |