aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp10
-rw-r--r--lib/AST/ASTImporter.cpp3
-rw-r--r--lib/AST/DeclObjC.cpp36
-rw-r--r--lib/Sema/Sema.cpp1
-rw-r--r--lib/Sema/SemaDeclObjC.cpp24
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp23
6 files changed, 56 insertions, 41 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index f65888fad8..de0250ced4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2808,11 +2808,17 @@ QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
/// getObjCInterfaceType - Return the unique reference to the type for the
/// specified ObjC interface decl. The list of protocols is optional.
-QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const {
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+ ObjCInterfaceDecl *PrevDecl) const {
if (Decl->TypeForDecl)
return QualType(Decl->TypeForDecl, 0);
- // FIXME: redeclarations?
+ if (PrevDecl) {
+ assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+ Decl->TypeForDecl = PrevDecl->TypeForDecl;
+ return QualType(PrevDecl->TypeForDecl, 0);
+ }
+
void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
Decl->TypeForDecl = T;
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index ac3b536ace..963643e542 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -3182,7 +3182,8 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
if (!ToIface) {
ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getAtStartLoc()),
- Name.getAsIdentifierInfo(), Loc,
+ Name.getAsIdentifierInfo(),
+ /*PrevDecl=*/0,Loc,
D->isImplicitInterfaceDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIface);
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index d420b2be49..317dc95f54 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -225,18 +225,19 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
void ObjCInterfaceDecl::allocateDefinitionData() {
assert(!hasDefinition() && "ObjC class already has a definition");
Data = new (getASTContext()) DefinitionData();
- Data->Definition = this;
-
+ Data->Definition = this;
+}
+
+void ObjCInterfaceDecl::startDefinition() {
+ allocateDefinitionData();
+
// Update all of the declarations with a pointer to the definition.
for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
RD != RDEnd; ++RD) {
if (*RD != this)
RD->Data = Data;
}
-}
-void ObjCInterfaceDecl::startDefinition() {
- allocateDefinitionData();
if (ASTMutationListener *L = getASTContext().getASTMutationListener())
L->CompletedObjCForwardRef(this);
}
@@ -674,9 +675,24 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation atLoc,
IdentifierInfo *Id,
+ ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc,
bool isInternal){
- return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, isInternal);
+ ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
+ isInternal);
+ C.getObjCInterfaceType(Result, PrevDecl);
+
+ if (PrevDecl) {
+ Result->Data = PrevDecl->Data;
+ Result->setPreviousDeclaration(PrevDecl);
+ }
+
+ return Result;
+}
+
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateEmpty(ASTContext &C) {
+ return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
+ false);
}
ObjCInterfaceDecl::
@@ -851,14 +867,6 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
return false;
}
-void ObjCInterfaceDecl::setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl) {
- redeclarable_base::setPreviousDeclaration(PrevDecl);
-
- // Inherit the 'Data' pointer from the previous declaration.
- if (PrevDecl)
- Data = PrevDecl->Data;
-}
-
//===----------------------------------------------------------------------===//
// ObjCIvarDecl
//===----------------------------------------------------------------------===//
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 2b7be7eaca..c95cf224cd 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -82,6 +82,7 @@ void Sema::ActOnTranslationUnitScope(Scope *S) {
ObjCInterfaceDecl *ProtocolDecl =
ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
&Context.Idents.get("Protocol"),
+ /*PrevDecl=*/0,
SourceLocation(), true);
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
PushOnScopeChains(ProtocolDecl, TUScope, false);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 02a83e5327..4f87db426d 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -366,11 +366,11 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
}
// Create a declaration to describe this @interface.
+ ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
ObjCInterfaceDecl *IDecl
= ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
- ClassLoc);
+ PrevIDecl, ClassLoc);
- ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (PrevIDecl) {
// Class already seen. Was it a definition?
if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -379,9 +379,6 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
Diag(Def->getLocation(), diag::note_previous_definition);
IDecl->setInvalidDecl();
}
-
- // Link to the previous declaration.
- IDecl->setPreviousDeclaration(PrevIDecl);
}
if (AttrList)
@@ -870,9 +867,8 @@ Decl *Sema::ActOnStartClassImplementation(
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
} else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
- if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
- diag::warn_undef_interface))
- IDecl = 0;
+ RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
+ diag::warn_undef_interface);
} else {
// We did not find anything with the name ClassName; try to correct for
// typos in the class name.
@@ -928,7 +924,8 @@ Decl *Sema::ActOnStartClassImplementation(
// FIXME: Do we support attributes on the @implementation? If so we should
// copy them over.
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
- ClassName, ClassLoc, true);
+ ClassName, /*PrevDecl=*/0, ClassLoc,
+ true);
IDecl->startDefinition();
if (SDecl) {
IDecl->setSuperClass(SDecl);
@@ -1774,16 +1771,13 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
}
// Create a declaration to describe this forward declaration.
+ ObjCInterfaceDecl *PrevIDecl
+ = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
ObjCInterfaceDecl *IDecl
= ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
- IdentList[i], IdentLocs[i], true);
+ IdentList[i], PrevIDecl, IdentLocs[i], true);
IDecl->setAtEndRange(IdentLocs[i]);
- // If there was a previous declaration, link to it.
- if (ObjCInterfaceDecl *PrevIDecl
- = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))
- IDecl->setPreviousDeclaration(PrevIDecl);
-
// Create the forward declaration. Note that we intentionally do this
// before we add the ObjCInterfaceDecl we just created, so that the
// rewriter sees the ObjCClassDecl first.
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index cacacd2394..5e5f1cb6fe 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -223,6 +223,9 @@ void ASTDeclReader::Visit(Decl *D) {
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
// if we have a fully initialized TypeDecl, we can safely read its type now.
TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
+ } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+ // if we have a fully initialized TypeDecl, we can safely read its type now.
+ ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// FunctionDecl's body was written last after all other Stmts/Exprs.
if (Record[Idx++])
@@ -556,7 +559,7 @@ void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
VisitRedeclarable(ID);
VisitObjCContainerDecl(ID);
- ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
+ TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
if (ID == Def) {
@@ -621,13 +624,13 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
// pending references were linked.
Reader.PendingForwardRefs.erase(ID);
#endif
- } else if (Def) {
- if (Def->Data) {
- ID->Data = Def->Data;
- } else {
- // The definition is still initializing.
- Reader.PendingForwardRefs[Def].push_back(ID);
- }
+ }
+ } else if (Def) {
+ if (Def->Data) {
+ ID->Data = Def->Data;
+ } else {
+ // The definition is still initializing.
+ Reader.PendingForwardRefs[Def].push_back(ID);
}
}
}
@@ -1561,6 +1564,8 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
FD->RedeclLink.setPointer(cast<FunctionDecl>(previous));
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
VD->RedeclLink.setPointer(cast<VarDecl>(previous));
+ } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(previous)) {
+ ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1736,7 +1741,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
Selector(), QualType(), 0, 0);
break;
case DECL_OBJC_INTERFACE:
- D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
+ D = ObjCInterfaceDecl::CreateEmpty(Context);
break;
case DECL_OBJC_IVAR:
D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), SourceLocation(),