From 7e5f052772a5952b0be7255bfea4dc1b03a4b686 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 11 Jul 2009 21:12:14 +0000 Subject: [PATCH] Fix type conversion of ObjCObjectPointerType. - Previous code was based on a misunderstanding (on my part) of the type representation. llvm-svn: 75385 --- clang/lib/CodeGen/CodeGenTypes.cpp | 13 ++++---- clang/test/CodeGenObjC/protocols.m | 50 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGenObjC/protocols.m diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 30a69f1dc225..a83c72f2b84c 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/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/clang/test/CodeGenObjC/protocols.m b/clang/test/CodeGenObjC/protocols.m new file mode 100644 index 000000000000..c510685e521d --- /dev/null +++ b/clang/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; +} -- GitLab