зеркало из https://github.com/microsoft/clang-1.git
If we end up merging an Objective-C class with an existing Objective-C
class that comes from a different module file, make sure that we load all of the pending declarations for the original declaration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147168 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
567003e572
Коммит
cce54aa6a4
|
@ -675,6 +675,13 @@ private:
|
|||
/// \brief Keeps track of the elements added to PendingDeclChains.
|
||||
llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
|
||||
|
||||
/// \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.
|
||||
llvm::DenseMap<Decl *, serialization::GlobalDeclID> DeclToID;
|
||||
|
||||
typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> >
|
||||
MergedDeclsMap;
|
||||
|
||||
|
|
|
@ -643,10 +643,13 @@ void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
|
|||
}
|
||||
|
||||
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
||||
// Record the declaration -> global ID mapping.
|
||||
Reader.DeclToID[ID] = ThisDeclID;
|
||||
|
||||
RedeclarableResult Redecl = VisitRedeclarable(ID);
|
||||
VisitObjCContainerDecl(ID);
|
||||
TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
|
||||
|
||||
|
||||
// Determine whether we need to merge this declaration with another @interface
|
||||
// with the same name.
|
||||
// FIXME: Not needed unless the module file graph is a DAG.
|
||||
|
@ -660,6 +663,18 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
|||
// appropriate canonical declaration.
|
||||
ID->RedeclLink = ObjCInterfaceDecl::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.
|
||||
if (IDCanon == ID)
|
||||
|
@ -2192,7 +2207,6 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
|
|||
if (Chains.empty())
|
||||
return;
|
||||
|
||||
|
||||
// Capture all of the parsed declarations and put them at the end.
|
||||
Decl *MostRecent = getMostRecentDecl(CanonDecl);
|
||||
Decl *FirstParsed = MostRecent;
|
||||
|
|
|
@ -51,6 +51,10 @@ module redecl_merge_left {
|
|||
header "redecl-merge-left.h"
|
||||
export *
|
||||
}
|
||||
module redecl_merge_left_left {
|
||||
header "redecl-merge-left-left.h"
|
||||
export *
|
||||
}
|
||||
module redecl_merge_right {
|
||||
header "redecl-merge-right.h"
|
||||
export *
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
__import_module__ redecl_merge_left;
|
||||
|
||||
@class C4;
|
||||
@class C4;
|
||||
__import_module__ redecl_merge_right;
|
||||
|
||||
@class B;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
__import_module__ redecl_merge_left;
|
||||
|
||||
@class C4;
|
||||
void accept_a_C4(C4*);
|
||||
|
|
@ -18,6 +18,12 @@ C2 *get_a_C2(void);
|
|||
@class C3;
|
||||
C3 *get_a_C3(void);
|
||||
|
||||
@class C4;
|
||||
@class C4;
|
||||
@class C4;
|
||||
@class C4;
|
||||
C4 *get_a_C4(void);
|
||||
|
||||
@class Explicit;
|
||||
|
||||
int *explicit_func(void);
|
||||
|
|
|
@ -55,6 +55,14 @@ void test_C3(C3 *c3) {
|
|||
accept_a_C3(c3);
|
||||
}
|
||||
|
||||
C4 *global_C4;
|
||||
__import_module__ redecl_merge_left_left;
|
||||
|
||||
void test_C4(C4 *c4) {
|
||||
global_C4 = c4 = get_a_C4();
|
||||
accept_a_C4(c4);
|
||||
}
|
||||
|
||||
__import_module__ redecl_merge_bottom;
|
||||
|
||||
@implementation B
|
||||
|
|
Загрузка…
Ссылка в новой задаче