forked from OSchip/llvm-project
Patch to implement Protocols on class extensions.
<rdar://problem/7269631> Protocols on class extensions don't work llvm-svn: 83322
This commit is contained in:
parent
1b7035da6f
commit
092cd6e624
|
@ -469,6 +469,11 @@ public:
|
|||
ReferencedProtocols.set(List, Num, C);
|
||||
}
|
||||
|
||||
/// mergeClassExtensionProtocolList - Merge class extension's protocol list
|
||||
/// into the protocol list for this class.
|
||||
void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
|
||||
ASTContext &C);
|
||||
|
||||
void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) {
|
||||
IVars.set(List, Num, C);
|
||||
}
|
||||
|
|
|
@ -118,6 +118,47 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
|
||||
ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
|
||||
ASTContext &C)
|
||||
{
|
||||
if (ReferencedProtocols.empty()) {
|
||||
ReferencedProtocols.set(ExtList, ExtNum, C);
|
||||
return;
|
||||
}
|
||||
// Check for duplicate protocol in class's protocol list.
|
||||
// This is (O)2. But it is extremely rare and number of protocols in
|
||||
// class or its extension are very few.
|
||||
llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
|
||||
for (unsigned i = 0; i < ExtNum; i++) {
|
||||
bool protocolExists = false;
|
||||
ObjCProtocolDecl *ProtoInExtension = ExtList[i];
|
||||
for (protocol_iterator p = protocol_begin(), e = protocol_end();
|
||||
p != e; p++) {
|
||||
ObjCProtocolDecl *Proto = (*p);
|
||||
if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
|
||||
protocolExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Do we want to warn on a protocol in extension class which
|
||||
// already exist in the class? Probably not.
|
||||
if (!protocolExists)
|
||||
ProtocolRefs.push_back(ProtoInExtension);
|
||||
}
|
||||
if (ProtocolRefs.empty())
|
||||
return;
|
||||
|
||||
for (protocol_iterator p = protocol_begin(), e = protocol_end();
|
||||
p != e; p++)
|
||||
ProtocolRefs.push_back(*p);
|
||||
ReferencedProtocols.Destroy(C);
|
||||
unsigned NumProtoRefs = ProtocolRefs.size();
|
||||
setProtocolList((ObjCProtocolDecl**)&ProtocolRefs[0], NumProtoRefs, C);
|
||||
// Merge ProtocolRefs into class's protocol list;
|
||||
|
||||
}
|
||||
|
||||
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
|
||||
ObjCInterfaceDecl *&clsDeclared) {
|
||||
ObjCInterfaceDecl* ClassDecl = this;
|
||||
|
|
|
@ -588,8 +588,15 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
|||
CDecl->insertNextClassCategory();
|
||||
|
||||
if (NumProtoRefs) {
|
||||
CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,Context);
|
||||
CDecl->setLocEnd(EndProtoLoc);
|
||||
// Protocols in the class extension belong to the class.
|
||||
if (!CDecl->getIdentifier())
|
||||
IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs,
|
||||
NumProtoRefs,Context);
|
||||
else {
|
||||
CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
|
||||
Context);
|
||||
CDecl->setLocEnd(EndProtoLoc);
|
||||
}
|
||||
}
|
||||
|
||||
CheckObjCDeclScope(CDecl);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: clang-cc -triple x86_64-apple-darwin10 -S %s -o %t-64.s &&
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
|
||||
// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s &&
|
||||
// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
|
||||
// RUN: true
|
||||
|
||||
@protocol MyProtocol
|
||||
@end
|
||||
|
||||
@protocol ExtendedProtocol
|
||||
@end
|
||||
|
||||
@interface ItDoesntWork<MyProtocol> {
|
||||
}
|
||||
-(void) Meth;
|
||||
@end
|
||||
|
||||
@interface ItDoesntWork() <MyProtocol, ExtendedProtocol>
|
||||
@end
|
||||
|
||||
@implementation ItDoesntWork
|
||||
-(void) Meth {
|
||||
ItDoesntWork <MyProtocol, ExtendedProtocol> *p = 0;
|
||||
}
|
||||
@end
|
||||
|
||||
// CHECK-LP64: l_OBJC_PROTOCOL_$_ExtendedProtocol:
|
||||
|
||||
// CHECK-LP32: L_OBJC_PROTOCOL_ExtendedProtocol:
|
Loading…
Reference in New Issue