From 368eefa081d12f0a265ee90ee8ec61b54168d57d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 7 Apr 2008 00:27:04 +0000 Subject: [PATCH] clean up some logic in objc type handling. Specifically, make it so that there are QualType::getAsObjc* type methods, and make isa return true for ObjCQualifiedInterfaceType's. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49300 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 17 +++++++-------- include/clang/AST/Type.h | 28 +++++++++++++++++------- lib/AST/ASTContext.cpp | 21 +++++++++--------- lib/AST/Type.cpp | 40 ++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 27 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index f4de3f460b..1829c76159 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -353,23 +353,22 @@ public: return T->getAsStructureType() == SelStructType; } + //===--------------------------------------------------------------------===// + // Serialization + //===--------------------------------------------------------------------===// + + void Emit(llvm::Serializer& S) const; + static ASTContext* Create(llvm::Deserializer& D); + private: ASTContext(const ASTContext&); // DO NOT IMPLEMENT void operator=(const ASTContext&); // DO NOT IMPLEMENT void InitBuiltinTypes(); void InitBuiltinType(QualType &R, BuiltinType::Kind K); - + /// helper function for Objective-C specific type checking. bool interfaceTypesAreCompatible(QualType, QualType); - - //===--------------------------------------------------------------------===// - // Serialization - //===--------------------------------------------------------------------===// - -public: - void Emit(llvm::Serializer& S) const; - static ASTContext* Create(llvm::Deserializer& D); }; } // end namespace clang diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 4b1f2c6b41..9d4fc10cd0 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -52,6 +52,8 @@ namespace clang { class FunctionType; class OCUVectorType; class BuiltinType; + class ObjCInterfaceType; + class ObjCQualifiedIdType; class ObjCQualifiedInterfaceType; class StmtIteratorBase; @@ -153,9 +155,11 @@ public: void dump(const char *s = 0) const; +//private: /// getCanonicalType - Return the canonical version of this type, with the /// appropriate type qualifiers on it. inline QualType getCanonicalType() const; +public: /// getAddressSpace - Return the address space of this type. inline unsigned getAddressSpace() const; @@ -313,11 +317,12 @@ public: bool isRecordType() const; bool isStructureType() const; bool isUnionType() const; - bool isComplexIntegerType() const; // GCC complex int type. - bool isVectorType() const; // GCC vector type. - bool isOCUVectorType() const; // OCU vector type. - bool isObjCInterfaceType() const; // includes conforming protocol type - bool isObjCQualifiedIdType() const; // id includes conforming protocol type + bool isComplexIntegerType() const; // GCC _Complex integer type. + bool isVectorType() const; // GCC vector type. + bool isOCUVectorType() const; // OCU vector type. + bool isObjCInterfaceType() const; // NSString or NSString + bool isObjCQualifiedInterfaceType() const; // NSString + bool isObjCQualifiedIdType() const; // id // Type Checking Functions: Check to see if this type is structurally the // specified type, ignoring typedefs and qualifiers, and return a pointer to @@ -338,6 +343,10 @@ public: const ComplexType *getAsComplexType() const; const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. const OCUVectorType *getAsOCUVectorType() const; // OCU vector type. + const ObjCInterfaceType *getAsObjCInterfaceType() const; + const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const; + const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const; + /// getDesugaredType - Return the specified type with any "sugar" removed from /// type type. This takes off typedefs, typeof's etc. If the outer level of @@ -1060,7 +1069,8 @@ public: virtual void getAsStringInternal(std::string &InnerString) const; static bool classof(const Type *T) { - return T->getTypeClass() == ObjCInterface; + return T->getTypeClass() == ObjCInterface || + T->getTypeClass() == ObjCQualifiedInterface; } static bool classof(const ObjCInterfaceType *) { return true; } }; @@ -1204,8 +1214,10 @@ inline bool Type::isOCUVectorType() const { return isa(CanonicalType.getUnqualifiedType()); } inline bool Type::isObjCInterfaceType() const { - return isa(CanonicalType) - || isa(CanonicalType); + return isa(CanonicalType); +} +inline bool Type::isObjCQualifiedInterfaceType() const { + return isa(CanonicalType); } inline bool Type::isObjCQualifiedIdType() const { return isa(CanonicalType); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 265804872d..12eb5a15de 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1427,17 +1427,18 @@ bool ASTContext::objcTypesAreCompatible(QualType lhs, QualType rhs) { return true; else if (isObjCIdType(lhs) && rhs->isObjCInterfaceType()) return true; - if (ObjCInterfaceType *lhsIT = - dyn_cast(lhs.getCanonicalType().getTypePtr())) { - ObjCQualifiedInterfaceType *rhsQI = - dyn_cast(rhs.getCanonicalType().getTypePtr()); - return rhsQI && (lhsIT->getDecl() == rhsQI->getDecl()); + + if (const ObjCInterfaceType *lhsIT = lhs->getAsObjCInterfaceType()) { + const ObjCQualifiedInterfaceType *rhsQI = + rhs->getAsObjCQualifiedInterfaceType(); + if (!isa(lhsIT)) + return rhsQI && (lhsIT->getDecl() == rhsQI->getDecl()); } - else if (ObjCInterfaceType *rhsIT = - dyn_cast(rhs.getCanonicalType().getTypePtr())) { - ObjCQualifiedInterfaceType *lhsQI = - dyn_cast(lhs.getCanonicalType().getTypePtr()); - return lhsQI && (rhsIT->getDecl() == lhsQI->getDecl()); + if (const ObjCInterfaceType *rhsIT = rhs->getAsObjCInterfaceType()) { + const ObjCQualifiedInterfaceType *lhsQI = + lhs->getAsObjCQualifiedInterfaceType(); + if (!isa(rhsIT)) + return lhsQI && (rhsIT->getDecl() == lhsQI->getDecl()); } return false; } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 01f90ba961..16f54cae13 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -428,6 +428,46 @@ const OCUVectorType *Type::getAsOCUVectorType() const { return getDesugaredType()->getAsOCUVectorType(); } +const ObjCInterfaceType *Type::getAsObjCInterfaceType() const { + // Are we directly an ObjCInterface type? + if (const ObjCInterfaceType *VTy = dyn_cast(this)) + return VTy; + + // If the canonical form of this type isn't the right kind, reject it. + if (!isa(CanonicalType)) { + // Look through type qualifiers + if (isa(CanonicalType.getUnqualifiedType())) + return CanonicalType.getUnqualifiedType()->getAsObjCInterfaceType(); + return 0; + } + + // If this is a typedef for an objc interface type, strip the typedef off + // without losing all typedef information. + return getDesugaredType()->getAsObjCInterfaceType(); +} + +const ObjCQualifiedInterfaceType * +Type::getAsObjCQualifiedInterfaceType() const { + // Are we directly an ObjCQualifiedInterfaceType? + if (const ObjCQualifiedInterfaceType *VTy = + dyn_cast(this)) + return VTy; + + // If the canonical form of this type isn't the right kind, reject it. + if (!isa(CanonicalType)) { + // Look through type qualifiers + if (isa(CanonicalType.getUnqualifiedType())) + return CanonicalType.getUnqualifiedType()-> + getAsObjCQualifiedInterfaceType(); + return 0; + } + + // If this is a typedef for an objc qual interface type, strip the typedef off + // without losing all typedef information. + return getDesugaredType()->getAsObjCQualifiedInterfaceType(); +} + + bool Type::isIntegerType() const { if (const BuiltinType *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && -- 2.40.0