aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/IdentifierResolver.cpp9
-rw-r--r--lib/Sema/SemaCodeComplete.cpp4
-rw-r--r--lib/Sema/SemaDeclObjC.cpp91
3 files changed, 44 insertions, 60 deletions
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 812f5d64fa..a80f23f58e 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -318,15 +318,6 @@ static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New) {
return DMK_Ignore;
}
- // If the declarations are both Objective-C classes, and one is a forward
- // declaration and the other is not, take the full definition.
- // FIXME: At some point, we'll actually have to detect collisions better.
- // This logic, however, belongs in the AST reader, not here.
- if (ObjCInterfaceDecl *ExistingIFace = dyn_cast<ObjCInterfaceDecl>(Existing))
- if (ObjCInterfaceDecl *NewIFace = dyn_cast<ObjCInterfaceDecl>(New))
- if (ExistingIFace->isForwardDecl() != NewIFace->isForwardDecl())
- return ExistingIFace->isForwardDecl()? DMK_Replace : DMK_Ignore;
-
return DMK_Different;
}
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 7e7e87a065..79985e8b32 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -5487,14 +5487,14 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
D != DEnd; ++D) {
// Record any interfaces we find.
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
- if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
+ if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
(!OnlyUnimplemented || !Class->getImplementation()))
Results.AddResult(Result(Class, 0), CurContext, 0, false);
// Record any forward-declared interfaces we find.
if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
ObjCInterfaceDecl *IDecl = Forward->getForwardInterfaceDecl();
- if ((!OnlyForwardDeclarations || IDecl->isForwardDecl()) &&
+ if ((!OnlyForwardDeclarations || !IDecl->hasDefinition()) &&
(!OnlyUnimplemented || !IDecl->getImplementation()))
Results.AddResult(Result(IDecl, 0), CurContext,
0, false);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 6947d7e211..3d1f01fec3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -60,7 +60,7 @@ bool Sema::checkInitMethod(ObjCMethodDecl *method,
// It's okay for the result type to still be a forward declaration
// if we're checking an interface declaration.
- if (resultClass->isForwardDecl()) {
+ if (!resultClass->hasDefinition()) {
if (receiverTypeIfCall.isNull() &&
!isa<ObjCImplementationDecl>(method->getDeclContext()))
return false;
@@ -365,45 +365,31 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
}
- ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
- if (IDecl) {
- // Class already seen. Is it a forward declaration?
- if (ObjCInterfaceDecl *Def = IDecl->getDefinition()) {
- IDecl->setInvalidDecl();
- Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
+ // Create a declaration to describe this @interface.
+ ObjCInterfaceDecl *IDecl
+ = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
+ ClassLoc);
+
+ ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+ if (PrevIDecl) {
+ // Class already seen. Was it a definition?
+ if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
+ Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
+ << PrevIDecl->getDeclName();
Diag(Def->getLocation(), diag::note_previous_definition);
-
- // Create a new one; the other may be in a different DeclContex, (e.g.
- // this one may be in a LinkageSpecDecl while the other is not) which
- // will break invariants.
- IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
- ClassName, ClassLoc);
- if (AttrList)
- ProcessDeclAttributeList(TUScope, IDecl, AttrList);
- PushOnScopeChains(IDecl, TUScope);
-
- } else {
- IDecl->setLocation(ClassLoc);
- IDecl->setAtStartLoc(AtInterfaceLoc);
-
- // Since this ObjCInterfaceDecl was created by a forward declaration,
- // we now add it to the DeclContext since it wasn't added before
- // (see ActOnForwardClassDeclaration).
- IDecl->setLexicalDeclContext(CurContext);
- CurContext->addDecl(IDecl);
-
- if (AttrList)
- ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+ IDecl->setInvalidDecl();
}
- } else {
- IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
- ClassName, ClassLoc);
- if (AttrList)
- ProcessDeclAttributeList(TUScope, IDecl, AttrList);
- PushOnScopeChains(IDecl, TUScope);
+ // Link to the previous declaration.
+ IDecl->setPreviousDeclaration(PrevIDecl);
}
+
+ if (AttrList)
+ ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+ PushOnScopeChains(IDecl, TUScope);
+ // Start the definition of this class. If we're in a redefinition case, there
+ // may already be a definition, so we'll end up adding to it.
if (!IDecl->hasDefinition())
IDecl->startDefinition();
@@ -942,7 +928,7 @@ 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, false, true);
+ ClassName, ClassLoc, true);
IDecl->startDefinition();
IDecl->setSuperClass(SDecl);
IDecl->setLocEnd(ClassLoc);
@@ -1781,22 +1767,29 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
PrevDecl = OI->getInterface();
}
}
- ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
- if (!IDecl) { // Not already seen? Make a forward decl.
- IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
- IdentList[i], IdentLocs[i], true);
-
- // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
- // the current DeclContext. This prevents clients that walk DeclContext
- // from seeing the imaginary ObjCInterfaceDecl until it is actually
- // declared later (if at all). We also take care to explicitly make
- // sure this declaration is visible for name lookup.
- PushOnScopeChains(IDecl, TUScope, false);
- CurContext->makeDeclVisibleInContext(IDecl, true);
- }
+
+ // Create a declaration to describe this forward declaration.
+ ObjCInterfaceDecl *IDecl
+ = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
+ IdentList[i], IdentLocs[i], true);
+ IDecl->setAtEndRange(IdentLocs[i]);
+ IDecl->setLocEnd(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.
+ // FIXME: ObjCClassDecl should probably just go away.
ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
IDecl, IdentLocs[i]);
CurContext->addDecl(CDecl);
+
+ PushOnScopeChains(IDecl, TUScope);
+
CheckObjCDeclScope(CDecl);
DeclsInGroup.push_back(CDecl);
}