AST import for Objective-C protocols

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96478 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2010-02-17 16:12:00 +00:00
Родитель df3a61bb51
Коммит 2e2a400383
4 изменённых файлов: 116 добавлений и 2 удалений

Просмотреть файл

@ -94,6 +94,7 @@ namespace {
Decl *VisitVarDecl(VarDecl *D);
Decl *VisitParmVarDecl(ParmVarDecl *D);
Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
// Importing statements
@ -2130,6 +2131,70 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
return ToMethod;
}
Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
// Import the major distinguishing characteristics of an @protocol.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
return 0;
ObjCProtocolDecl *MergeWithProtocol = 0;
for (DeclContext::lookup_result Lookup = DC->lookup(Name);
Lookup.first != Lookup.second;
++Lookup.first) {
if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
continue;
if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
break;
}
ObjCProtocolDecl *ToProto = MergeWithProtocol;
if (!ToProto || ToProto->isForwardDecl()) {
if (!ToProto) {
ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
Name.getAsIdentifierInfo());
ToProto->setForwardDecl(D->isForwardDecl());
ToProto->setLexicalDeclContext(LexicalDC);
LexicalDC->addDecl(ToProto);
}
Importer.Imported(D, ToProto);
// Import protocols
llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
ObjCProtocolDecl::protocol_loc_iterator
FromProtoLoc = D->protocol_loc_begin();
for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
FromProtoEnd = D->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
ObjCProtocolDecl *ToProto
= cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
if (!ToProto)
return 0;
Protocols.push_back(ToProto);
ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
}
// FIXME: If we're merging, make sure that the protocol list is the same.
ToProto->setProtocolList(Protocols.data(), Protocols.size(),
ProtocolLocs.data(), Importer.getToContext());
} else {
Importer.Imported(D, ToProto);
}
// Import all of the members of this class.
for (DeclContext::decl_iterator FromMem = D->decls_begin(),
FromMemEnd = D->decls_end();
FromMem != FromMemEnd;
++FromMem)
Importer.Import(*FromMem);
return ToProto;
}
Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Import the major distinguishing characteristics of an @interface.
DeclContext *DC, *LexicalDC;
@ -2158,6 +2223,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Importer.Import(D->getClassLoc()),
D->isForwardDecl(),
D->isImplicitInterfaceDecl());
ToIface->setForwardDecl(D->isForwardDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDecl(ToIface);
}
@ -2246,7 +2312,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
ToIface->setImplementation(Impl);
}
return 0;
return ToIface;
}
//----------------------------------------------------------------------------

Просмотреть файл

@ -45,3 +45,26 @@
- (int)foo;
+ (int)bar:(float)x;
@end
// Matching protocol
@protocol P0
+ (int)foo;
- (int)bar:(float)x;
@end
// Protocol with mismatching method
@protocol P1
+ (int)foo;
- (int)bar:(float)x;
@end
// Interface with protocol
@interface I9 <P0>
+ (int)foo;
- (int)bar:(float)x;
@end
// Protocol with protocol
@protocol P2 <P0>
- (float)wibble:(int)a1 second:(int)a2;
@end

Просмотреть файл

@ -44,3 +44,26 @@
- (int)foo;
+ (int)bar:(float)x, ...;
@end
// Matching protocol
@protocol P0
+ (int)foo;
- (int)bar:(float)x;
@end
// Protocol with mismatching method
@protocol P1
+ (int)foo;
- (int)bar:(double)x;
@end
// Interface with protocol
@interface I9 <P0>
+ (int)foo;
- (int)bar:(float)x;
@end
// Protocol with protocol
@protocol P2 <P0>
- (float)wibble:(int)a1 second:(int)a2;
@end

Просмотреть файл

@ -13,5 +13,7 @@
// CHECK: interface1.m:40:17: note: declared here with type 'int'
// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another
// CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
// CHECK: 11 diagnostics generated
// CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
// CHECK: interface1.m:58:19: note: declared here with type 'float'
// CHECK: 13 diagnostics generated