diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/IdentifierResolver.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 91 |
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); } |