virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}
- /// \brief A objc interface or protocol forward reference was completed.
- virtual void CompletedObjCForwardRef(const ObjCContainerDecl *D) {}
-
/// \brief A objc class extension redeclared or introduced a property.
///
/// \param Prop the property in the class extension
virtual void StaticDataMemberInstantiated(const VarDecl *D);
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD);
- virtual void CompletedObjCForwardRef(const ObjCContainerDecl *D);
virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
const ObjCPropertyDecl *OrigProp,
const ObjCCategoryDecl *ClassExt);
if (*RD != this)
RD->Data = Data;
}
-
- if (ASTMutationListener *L = getASTContext().getASTMutationListener())
- L->CompletedObjCForwardRef(this);
}
/// getFirstClassExtension - Find first class extension of the given class.
for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
RD != RDEnd; ++RD)
RD->Data = this->Data;
-
- if (ASTMutationListener *L = getASTContext().getASTMutationListener())
- L->CompletedObjCForwardRef(this);
}
//===----------------------------------------------------------------------===//
namespace serialization {
enum DeclUpdateKind {
- UPD_CXX_SET_DEFINITIONDATA,
UPD_CXX_ADDED_IMPLICIT_MEMBER,
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
- UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
- UPD_OBJC_SET_CLASS_DEFINITIONDATA,
- UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA
+ UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER
};
TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
// Read the definition.
ID->allocateDefinitionData();
+ // Set the definition data of the canonical declaration, so other
+ // redeclarations will see it.
+ ID->getCanonicalDecl()->Data = ID->Data;
+
ObjCInterfaceDecl::DefinitionData &Data = ID->data();
// Read the superclass.
// Note that we have deserialized a definition.
Reader.PendingDefinitions.insert(ID);
- } else if (Def && Def->Data) {
- ID->Data = Def->Data;
+ } else {
+ ID->Data = ID->getCanonicalDecl()->Data;
}
}
// Read the definition.
PD->allocateDefinitionData();
+ // Set the definition data of the canonical declaration, so other
+ // redeclarations will see it.
+ PD->getCanonicalDecl()->Data = PD->Data;
+
unsigned NumProtoRefs = Record[Idx++];
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
ProtoRefs.reserve(NumProtoRefs);
// Note that we have deserialized a definition.
Reader.PendingDefinitions.insert(PD);
- } else if (Def && Def->Data) {
- PD->Data = Def->Data;
+ } else {
+ PD->Data = PD->getCanonicalDecl()->Data;
}
}
if (D == DefinitionDecl) {
D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
+
+ // Propagate the DefinitionData pointer to the canonical declaration, so
+ // that all other deserialized declarations will see it.
+ // FIXME: Complain if there already is a DefinitionData!
+ D->getCanonicalDecl()->DefinitionData = D->DefinitionData;
+
ReadCXXDefinitionData(*D->DefinitionData, Record, Idx);
- // Note that we have deserialized a definition.
+ // Note that we have deserialized a definition. Any declarations
+ // deserialized before this one will be be given the DefinitionData pointer
+ // at the end.
Reader.PendingDefinitions.insert(D);
- } else if (DefinitionDecl && DefinitionDecl->DefinitionData) {
- D->DefinitionData = DefinitionDecl->DefinitionData;
+ } else {
+ // Propagate DefinitionData pointer from the canonical declaration.
+ D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
}
}
static_cast<NamespaceDecl *>(static_cast<void*>(ExistingCanon)));
}
- // FIXME: Update common pointer for RedeclarableTemplateDecls?
-
// Don't introduce DCanon into the set of pending declaration chains.
Redecl.suppress();
unsigned Idx = 0;
while (Idx < Record.size()) {
switch ((DeclUpdateKind)Record[Idx++]) {
- case UPD_CXX_SET_DEFINITIONDATA: {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
- CXXRecordDecl *DefinitionDecl
- = Reader.ReadDeclAs<CXXRecordDecl>(ModuleFile, Record, Idx);
- assert(!RD->DefinitionData && "DefinitionData is already set!");
- InitializeCXXDefinitionData(RD, DefinitionDecl, Record, Idx);
- break;
- }
-
case UPD_CXX_ADDED_IMPLICIT_MEMBER:
cast<CXXRecordDecl>(D)->addedMember(Reader.ReadDecl(ModuleFile, Record, Idx));
break;
cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation(
Reader.ReadSourceLocation(ModuleFile, Record, Idx));
break;
-
- case UPD_OBJC_SET_CLASS_DEFINITIONDATA: {
- ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
- ObjCInterfaceDecl *Def
- = Reader.ReadDeclAs<ObjCInterfaceDecl>(ModuleFile, Record, Idx);
- if (Def->Data)
- ID->Data = Def->Data;
- break;
- }
-
- case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA: {
- ObjCProtocolDecl *ID = cast<ObjCProtocolDecl>(D);
- ObjCProtocolDecl *Def
- = Reader.ReadDeclAs<ObjCProtocolDecl>(ModuleFile, Record, Idx);
- if (Def->Data)
- ID->Data = Def->Data;
- break;
- }
}
}
}
unsigned Idx = 0, N = URec.size();
while (Idx < N) {
switch ((DeclUpdateKind)URec[Idx++]) {
- case UPD_CXX_SET_DEFINITIONDATA:
case UPD_CXX_ADDED_IMPLICIT_MEMBER:
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
- case UPD_OBJC_SET_CLASS_DEFINITIONDATA:
- case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA:
URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
++Idx;
break;
// have created a new definition decl instead ?
RewriteDecl(RD);
}
-
- for (CXXRecordDecl::redecl_iterator
- I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) {
- CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I);
- if (Redecl == RD)
- continue;
-
- // We are interested when a PCH decl is modified.
- if (Redecl->isFromASTFile()) {
- UpdateRecord &Record = DeclUpdates[Redecl];
- Record.push_back(UPD_CXX_SET_DEFINITIONDATA);
- assert(Redecl->DefinitionData);
- assert(Redecl->DefinitionData->Definition == D);
- Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
- }
- }
}
}
void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
LocalChainedObjCCategories.push_back(Data);
}
-void ASTWriter::CompletedObjCForwardRef(const ObjCContainerDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
-
- if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
- for (ObjCInterfaceDecl::redecl_iterator I = ID->redecls_begin(),
- E = ID->redecls_end();
- I != E; ++I) {
- if (*I == ID)
- continue;
-
- // We are interested when a PCH decl is modified.
- if (I->isFromASTFile()) {
- UpdateRecord &Record = DeclUpdates[*I];
- Record.push_back(UPD_OBJC_SET_CLASS_DEFINITIONDATA);
- assert((*I)->hasDefinition());
- assert((*I)->getDefinition() == D);
- Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
- }
- }
- }
-
- if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
- for (ObjCProtocolDecl::redecl_iterator I = PD->redecls_begin(),
- E = PD->redecls_end();
- I != E; ++I) {
- if (*I == PD)
- continue;
-
- // We are interested when a PCH decl is modified.
- if (I->isFromASTFile()) {
- UpdateRecord &Record = DeclUpdates[*I];
- Record.push_back(UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA);
- assert((*I)->hasDefinition());
- assert((*I)->getDefinition() == D);
- Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
- }
- }
- }
-}
void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
const ObjCPropertyDecl *OrigProp,
@class C4;
void accept_a_C4(C4*);
+@class ClassWithDef;
+
int ONE;
@import redecl_merge_top.Explicit;
const int one = ONE;
+
+@interface ClassWithDef
+- (void)method;
+@end
}
C4 *global_C4;
+
+ClassWithDef *cwd1;
+
@import redecl_merge_left_left;
void test_C4a(C4 *c4) {
accept_a_C4(c4);
}
+void test_ClassWithDef(ClassWithDef *cwd) {
+ [cwd method];
+}
+
@import redecl_merge_bottom;
void test_C4b() {