forked from OSchip/llvm-project
Implement declaration merging for Objective-C protocols across
multiple, disjoint modules. There is far too much duplicating with the ObjCInterfaceDecl case here, which I'll eliminate shortly. llvm-svn: 147417
This commit is contained in:
parent
a503bb9ce4
commit
da38930cf3
|
@ -677,9 +677,9 @@ private:
|
|||
|
||||
/// \brief Reverse mapping from declarations to their global declaration IDs.
|
||||
///
|
||||
/// FIXME: This data structure is currently only used for ObjCInterfaceDecls,
|
||||
/// support declaration merging. If we must have this for other declarations,
|
||||
/// allocate it along with the Decl itself.
|
||||
/// FIXME: This data structure is currently only used for ObjCInterfaceDecls
|
||||
/// and ObjCProtocolDecls to support declaration merging. If we must have
|
||||
/// this for other declarations, allocate it along with the Decl itself.
|
||||
llvm::DenseMap<Decl *, serialization::GlobalDeclID> DeclToID;
|
||||
|
||||
typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> >
|
||||
|
|
|
@ -759,12 +759,54 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
|
|||
}
|
||||
|
||||
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
|
||||
VisitRedeclarable(PD);
|
||||
// Record the declaration -> global ID mapping.
|
||||
Reader.DeclToID[PD] = ThisDeclID;
|
||||
|
||||
RedeclarableResult Redecl = VisitRedeclarable(PD);
|
||||
VisitObjCContainerDecl(PD);
|
||||
PD->InitiallyForwardDecl = Record[Idx++];
|
||||
PD->isForwardProtoDecl = Record[Idx++];
|
||||
PD->setLocEnd(ReadSourceLocation(Record, Idx));
|
||||
|
||||
// Determine whether we need to merge this declaration with another @protocol
|
||||
// with the same name.
|
||||
// FIXME: Not needed unless the module file graph is a DAG.
|
||||
if (FindExistingResult ExistingRes = findExisting(PD)) {
|
||||
if (ObjCProtocolDecl *Existing = ExistingRes) {
|
||||
ObjCProtocolDecl *ExistingCanon = Existing->getCanonicalDecl();
|
||||
ObjCProtocolDecl *PDCanon = PD->getCanonicalDecl();
|
||||
if (ExistingCanon != PDCanon) {
|
||||
// Have our redeclaration link point back at the canonical declaration
|
||||
// of the existing declaration, so that this declaration has the
|
||||
// appropriate canonical declaration.
|
||||
PD->RedeclLink = ObjCProtocolDecl::PreviousDeclLink(ExistingCanon);
|
||||
|
||||
// Don't introduce IDCanon into the set of pending declaration chains.
|
||||
Redecl.suppress();
|
||||
|
||||
// Introduce ExistingCanon into the set of pending declaration chains,
|
||||
// if in fact it came from a module file.
|
||||
if (ExistingCanon->isFromASTFile()) {
|
||||
GlobalDeclID ExistingCanonID = Reader.DeclToID[ExistingCanon];
|
||||
assert(ExistingCanonID && "Unrecorded canonical declaration ID?");
|
||||
if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID))
|
||||
Reader.PendingDeclChains.push_back(ExistingCanonID);
|
||||
}
|
||||
|
||||
// If this declaration was the canonical declaration, make a note of
|
||||
// that. We accept the linear algorithm here because the number of
|
||||
// unique canonical declarations of an entity should always be tiny.
|
||||
if (PDCanon == PD) {
|
||||
SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
|
||||
if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
|
||||
== Merged.end())
|
||||
Merged.push_back(Redecl.getFirstID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ObjCProtocolDecl *Def = ReadDeclAs<ObjCProtocolDecl>(Record, Idx);
|
||||
if (PD == Def) {
|
||||
// Read the definition.
|
||||
|
@ -1645,8 +1687,8 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
|
|||
Y->getDeclContext()->getRedeclContext()))
|
||||
return false;
|
||||
|
||||
// Objective-C classes with the same name always match.
|
||||
if (isa<ObjCInterfaceDecl>(X))
|
||||
// Objective-C classes and protocols with the same name always match.
|
||||
if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))
|
||||
return true;
|
||||
|
||||
// FIXME: Many other cases to implement.
|
||||
|
|
|
@ -2,6 +2,9 @@ __import_module__ redecl_merge_left;
|
|||
|
||||
@class C4;
|
||||
@class C4;
|
||||
@protocol P4;
|
||||
@protocol P4;
|
||||
@protocol P4;
|
||||
__import_module__ redecl_merge_right;
|
||||
|
||||
@class B;
|
||||
|
|
|
@ -35,6 +35,10 @@ int *explicit_func(void);
|
|||
|
||||
struct explicit_struct;
|
||||
|
||||
@protocol P3, P4;
|
||||
|
||||
@protocol P3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<typename T> class Vector;
|
||||
|
||||
|
|
|
@ -42,6 +42,11 @@ int *explicit_func(void);
|
|||
|
||||
struct explicit_struct;
|
||||
|
||||
@protocol P4, P3;
|
||||
@protocol P3;
|
||||
@protocol P3;
|
||||
@protocol P3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<typename T> class Vector {
|
||||
public:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
@class C3;
|
||||
__import_module__ redecl_merge_left;
|
||||
|
||||
@protocol P4;
|
||||
@class C3;
|
||||
@class C3;
|
||||
__import_module__ redecl_merge_right;
|
||||
|
@ -83,6 +84,13 @@ void g(A *a) {
|
|||
[a init];
|
||||
}
|
||||
|
||||
@protocol P3
|
||||
- (void)p3_method;
|
||||
@end
|
||||
|
||||
id<P4> p4;
|
||||
id<P3> p3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
void testVector() {
|
||||
Vector<int> vec_int;
|
||||
|
|
Loading…
Reference in New Issue