[cfe-commits] r45203 - in /cfe/trunk: AST/ASTContext.cpp Sema/SemaExpr.cpp include/clang/AST/ASTContext.h include/clang/AST/Type.h test/Sema/protocol-id-test-3.m
Fariborz Jahanian
fjahanian at apple.com
Wed Dec 19 09:45:59 PST 2007
Author: fjahanian
Date: Wed Dec 19 11:45:58 2007
New Revision: 45203
URL: http://llvm.org/viewvc/llvm-project?rev=45203&view=rev
Log:
This patch concludes implementation of dynamic objective-c type qualified by
protocol list.
Added:
cfe/trunk/test/Sema/protocol-id-test-3.m
Modified:
cfe/trunk/AST/ASTContext.cpp
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Type.h
Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=45203&r1=45202&r2=45203&view=diff
==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Wed Dec 19 11:45:58 2007
@@ -1265,12 +1265,100 @@
return true;
}
-// TODO: id<P1,...> vs. id<P,...>
-#if 0
-bool ASTContext::QualifiedIdTypesAreCompatible(QualType lhs,
- QualType rhs) {
+/// ObjcQualifiedIdTypesAreCompatible - Compares two types, at least
+/// one of which is a protocol qualified 'id' type.
+bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs,
+ QualType rhs) {
+ // match id<P..> with an 'id' type in all cases.
+ if (const PointerType *PT = lhs->getAsPointerType()) {
+ QualType PointeeTy = PT->getPointeeType();
+ if (isObjcIdType(PointeeTy))
+ return true;
+
+ }
+ else if (const PointerType *PT = rhs->getAsPointerType()) {
+ QualType PointeeTy = PT->getPointeeType();
+ if (isObjcIdType(PointeeTy))
+ return true;
+
+ }
+
+ ObjcQualifiedInterfaceType *lhsQI = 0;
+ ObjcQualifiedInterfaceType *rhsQI = 0;
+ ObjcQualifiedIdType *lhsQID = dyn_cast<ObjcQualifiedIdType>(lhs);
+ ObjcQualifiedIdType *rhsQID = dyn_cast<ObjcQualifiedIdType>(rhs);
+
+ if (lhsQID) {
+ if (!rhsQID && rhs->getTypeClass() == Type::Pointer) {
+ QualType rtype =
+ cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
+ rhsQI =
+ dyn_cast<ObjcQualifiedInterfaceType>(
+ rtype.getCanonicalType().getTypePtr());
+ }
+ if (!rhsQI && !rhsQID)
+ return false;
+
+ for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) {
+ bool match = false;
+ ObjcProtocolDecl *lhsProto = lhsQID->getProtocols(i);
+ unsigned numRhsProtocols;
+ ObjcProtocolDecl **rhsProtoList;
+ if (rhsQI) {
+ numRhsProtocols = rhsQI->getNumProtocols();
+ rhsProtoList = rhsQI->getReferencedProtocols();
+ }
+ else {
+ numRhsProtocols = rhsQID->getNumProtocols();
+ rhsProtoList = rhsQID->getReferencedProtocols();
+ }
+ for (unsigned j = 0; j < numRhsProtocols; j++) {
+ ObjcProtocolDecl *rhsProto = rhsProtoList[j];
+ if (lhsProto == rhsProto) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ return false;
+ }
+ }
+ else if (rhsQID) {
+ if (!lhsQID && lhs->getTypeClass() == Type::Pointer) {
+ QualType ltype =
+ cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
+ lhsQI =
+ dyn_cast<ObjcQualifiedInterfaceType>(
+ ltype.getCanonicalType().getTypePtr());
+ }
+ if (!lhsQI && !lhsQID)
+ return false;
+ unsigned numLhsProtocols;
+ ObjcProtocolDecl **lhsProtoList;
+ if (lhsQI) {
+ numLhsProtocols = lhsQI->getNumProtocols();
+ lhsProtoList = lhsQI->getReferencedProtocols();
+ }
+ else {
+ numLhsProtocols = lhsQID->getNumProtocols();
+ lhsProtoList = lhsQID->getReferencedProtocols();
+ }
+ for (unsigned i =0; i < numLhsProtocols; i++) {
+ bool match = false;
+ ObjcProtocolDecl *lhsProto = lhsProtoList[i];
+ for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
+ ObjcProtocolDecl *rhsProto = rhsQID->getProtocols(j);
+ if (lhsProto == rhsProto) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ return false;
+ }
+ }
+ return true;
}
-#endif
bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
const VectorType *lVector = lhs->getAsVectorType();
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=45203&r1=45202&r2=45203&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Wed Dec 19 11:45:58 2007
@@ -1103,6 +1103,8 @@
///
Sema::AssignmentCheckResult
Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
+
+
if (lhsType.getCanonicalType().getUnqualifiedType() ==
rhsType.getCanonicalType().getUnqualifiedType())
return Compatible; // common case, fast path...
@@ -1110,7 +1112,13 @@
if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
if (Context.referenceTypesAreCompatible(lhsType, rhsType))
return Compatible;
- } else if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
+ }
+ else if (lhsType->isObjcQualifiedIdType()
+ || rhsType->isObjcQualifiedIdType()) {
+ if (Context.ObjcQualifiedIdTypesAreCompatible(lhsType, rhsType))
+ return Compatible;
+ }
+ else if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
if (lhsType->isVectorType() || rhsType->isVectorType()) {
if (!getLangOptions().LaxVectorConversions) {
if (lhsType.getCanonicalType() != rhsType.getCanonicalType())
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=45203&r1=45202&r2=45203&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Dec 19 11:45:58 2007
@@ -297,6 +297,7 @@
/// Objective-C specific type checking.
bool interfaceTypesAreCompatible(QualType, QualType);
bool QualifiedInterfaceTypesAreCompatible(QualType, QualType);
+ bool ObjcQualifiedIdTypesAreCompatible(QualType, QualType);
bool objcTypesAreCompatible(QualType, QualType);
bool isObjcIdType(QualType T) const {
if (!IdStructType) // ObjC isn't enabled
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=45203&r1=45202&r2=45203&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Dec 19 11:45:58 2007
@@ -943,7 +943,9 @@
unsigned getNumProtocols() const {
return Protocols.size();
}
-
+ ObjcProtocolDecl **getReferencedProtocols() {
+ return &Protocols[0];
+ }
virtual void getAsStringInternal(std::string &InnerString) const;
void Profile(llvm::FoldingSetNodeID &ID);
@@ -975,6 +977,9 @@
unsigned getNumProtocols() const {
return Protocols.size();
}
+ ObjcProtocolDecl **getReferencedProtocols() {
+ return &Protocols[0];
+ }
virtual void getAsStringInternal(std::string &InnerString) const;
@@ -1024,7 +1029,8 @@
return isa<FunctionType>(CanonicalType);
}
inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType);
+ return isa<PointerType>(CanonicalType) ||
+ isa<ObjcQualifiedIdType>(CanonicalType);
}
inline bool Type::isFunctionPointerType() const {
if (const PointerType* T = getAsPointerType())
Added: cfe/trunk/test/Sema/protocol-id-test-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/protocol-id-test-3.m?rev=45203&view=auto
==============================================================================
--- cfe/trunk/test/Sema/protocol-id-test-3.m (added)
+++ cfe/trunk/test/Sema/protocol-id-test-3.m Wed Dec 19 11:45:58 2007
@@ -0,0 +1,94 @@
+// RUN: clang -pedantic -fsyntax-only -verify %s
+
+ at protocol MyProto1
+ at end
+
+ at protocol MyProto2
+ at end
+
+ at interface INTF @end
+
+id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2)
+{
+ return p2;
+}
+
+
+
+
+ id<MyProto1> Gunc(id <MyProto1, MyProto2>p2)
+{
+ return p2;
+}
+
+
+ id<MyProto1> Gunc1(id <MyProto1, MyProto2>p2)
+{
+ return p2;
+}
+
+id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2)
+{
+ Func(p2); // expected-error {{incompatible types passing 'id<MyProto1>' to function expecting 'INTF<MyProto1,MyProto2> *'}}
+ return p2; // expected-error {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}}
+}
+
+
+
+id<MyProto1> Gunc3(id <MyProto2>p2)
+{
+ return p2; // expected-error {{incompatible type returning 'id<MyProto2>', expected 'id<MyProto1>'}}
+}
+
+
+id<MyProto1, MyProto2> Gunc4(id <MyProto2, MyProto1>p2)
+{
+ return p2;
+}
+
+
+
+INTF<MyProto1> * Hunc(id <MyProto1, MyProto2>p2)
+{
+ return p2;
+}
+
+
+INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2)
+{
+ return p2;
+}
+
+INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2)
+{
+ Func(p2); // expected-error {{incompatible types passing 'id<MyProto1>' to function expecting 'INTF<MyProto1,MyProto2> *'}}
+ return p2; // expected-error {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
+}
+
+INTF<MyProto1> * Hunc3(id <MyProto2>p2)
+{
+ return p2; // expected-error {{incompatible type returning 'id<MyProto2>', expected 'INTF<MyProto1> *'}}
+}
+
+
+INTF<MyProto1, MyProto2> * Hunc4(id <MyProto2, MyProto1>p2)
+{
+ return p2;
+}
+
+id Iunc(id <MyProto1, MyProto2>p2)
+{
+ return p2;
+}
+
+
+id<MyProto1> Iunc1(id p2)
+{
+ return p2;
+}
+
+id<MyProto1, MyProto2> Iunc2(id p2)
+{
+ Iunc(p2);
+ return p2;
+}
More information about the cfe-commits
mailing list