From: Daniel Dunbar Date: Sat, 11 Jul 2009 21:12:14 +0000 (+0000) Subject: Fix type conversion of ObjCObjectPointerType. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=28e478010eb4d789da85c6378dbfa9d66b95830b;p=clang Fix type conversion of ObjCObjectPointerType. - Previous code was based on a misunderstanding (on my part) of the type representation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75385 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 30a69f1dc2..a83c72f2b8 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -355,13 +355,14 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { } case Type::ObjCObjectPointer: { - // Qualified id types don't influence the LLVM type, here we always return - // an opaque type for 'id'. - const llvm::Type *&T = InterfaceTypes[0]; - if (!T) - T = llvm::OpaqueType::get(); - return llvm::PointerType::getUnqual(T); + // Protocol qualifications do not influence the LLVM type, we just return a + // pointer to the underlying interface type. We don't need to worry about + // recursive conversion. + const llvm::Type *T = + ConvertTypeRecursive(cast(Ty).getPointeeType()); + return llvm::PointerType::getUnqual(T); } + case Type::Record: case Type::Enum: { const TagDecl *TD = cast(Ty).getDecl(); diff --git a/test/CodeGenObjC/protocols.m b/test/CodeGenObjC/protocols.m new file mode 100644 index 0000000000..c510685e52 --- /dev/null +++ b/test/CodeGenObjC/protocols.m @@ -0,0 +1,50 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +void p(const char*, ...); + +@interface Root +-(int) conformsTo: (id) x; +@end + +@protocol P0; + +@protocol P1 ++(void) classMethodReq0; +-(void) methodReq0; +@optional ++(void) classMethodOpt1; +-(void) methodOpt1; +@required ++(void) classMethodReq2; +-(void) methodReq2; +@end + +@protocol P2 +//@property(readwrite) int x; +@end + +@protocol P3 +-(id ) print0; +-(void) print1; +@end + +void foo(const id a) { + void *p = @protocol(P3); +} + +int main() { + Protocol *P0 = @protocol(P0); + Protocol *P1 = @protocol(P1); + Protocol *P2 = @protocol(P2); + Protocol *P3 = @protocol(P3); + +#define Pbool(X) p(#X ": %s\n", X ? "yes" : "no"); + Pbool([P0 conformsTo: P1]); + Pbool([P1 conformsTo: P0]); + Pbool([P1 conformsTo: P2]); + Pbool([P2 conformsTo: P1]); + Pbool([P3 conformsTo: P1]); + Pbool([P1 conformsTo: P3]); + + return 0; +}