diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-01 19:29:29 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-01 19:29:29 +0000 |
commit | 5e2a1ff9f28d2eab256d2553e76a9c9d54693875 (patch) | |
tree | 9b6a413be6f25d57bd1e0737cb63227d337493e5 /lib/Sema | |
parent | 27b7ce6199bfd008ba8d10c8bd91d926e2274df3 (diff) |
Move the data that corresponds to the definition of a protocol into a
separately-allocated DefinitionData structure. Introduce various
functions that will help with the separation of declarations from
definitions (isThisDeclarationADefinition(), hasDefinition(),
getDefinition()).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 39 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 25 |
2 files changed, 39 insertions, 25 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 72cc37ccdd..6843ca7e6c 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4554,13 +4554,16 @@ static void AddObjCMethods(ObjCContainerDecl *Container, // Visit the protocols of protocols. if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { - const ObjCList<ObjCProtocolDecl> &Protocols - = Protocol->getReferencedProtocols(); - for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), - E = Protocols.end(); - I != E; ++I) - AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents, - CurContext, Selectors, AllowSameLength, Results, false); + if (Protocol->hasDefinition()) { + const ObjCList<ObjCProtocolDecl> &Protocols + = Protocol->getReferencedProtocols(); + for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), + E = Protocols.end(); + I != E; ++I) + AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, + NumSelIdents, CurContext, Selectors, AllowSameLength, + Results, false); + } } ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container); @@ -5417,7 +5420,7 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, D != DEnd; ++D) { // Record any protocols we find. if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D)) - if (!OnlyForwardDeclarations || Proto->isForwardDecl()) + if (!OnlyForwardDeclarations || !Proto->hasDefinition()) Results.AddResult(Result(Proto, 0), CurContext, 0, false); // Record any forward-declared protocols we find. @@ -5427,7 +5430,7 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, P = Forward->protocol_begin(), PEnd = Forward->protocol_end(); P != PEnd; ++P) - if (!OnlyForwardDeclarations || (*P)->isForwardDecl()) + if (!OnlyForwardDeclarations || !(*P)->hasDefinition()) Results.AddResult(Result(*P, 0), CurContext, 0, false); } } @@ -5823,14 +5826,16 @@ static void FindImplementableMethods(ASTContext &Context, } if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { - // Recurse into protocols. - const ObjCList<ObjCProtocolDecl> &Protocols - = Protocol->getReferencedProtocols(); - for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), - E = Protocols.end(); - I != E; ++I) - FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, - KnownMethods, false); + if (Protocol->hasDefinition()) { + // Recurse into protocols. + const ObjCList<ObjCProtocolDecl> &Protocols + = Protocol->getReferencedProtocols(); + for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), + E = Protocols.end(); + I != E; ++I) + FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, + KnownMethods, false); + } } // Add methods in this container. This operation occurs last because diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 168ccfc3f5..eb178612c8 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -545,6 +545,10 @@ bool Sema::CheckForwardProtocolDeclarationForCircularDependency( Diag(PrevLoc, diag::note_previous_definition); res = true; } + + if (!PDecl->hasDefinition()) + continue; + if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc, PDecl->getLocation(), PDecl->getReferencedProtocols())) res = true; @@ -568,18 +572,18 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolName, ProtocolLoc); if (PDecl) { // Protocol already seen. Better be a forward protocol declaration - if (!PDecl->isForwardDecl()) { + if (ObjCProtocolDecl *Def = PDecl->getDefinition()) { Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName; - Diag(PDecl->getLocation(), diag::note_previous_definition); + 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. - // We will not add it to scope chains to ignore it as the warning says. + // Create a new protocol that is completely distinct from previous + // declarations, and do not make this protocol available for name lookup. + // That way, we'll end up completely ignoring the duplicate. + // FIXME: Can we turn this into an error? PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, ProtocolLoc, AtProtoInterfaceLoc, /*isForwardDecl=*/false); - + PDecl->startDefinition(); } else { ObjCList<ObjCProtocolDecl> PList; PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); @@ -600,7 +604,9 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, ProtocolLoc, AtProtoInterfaceLoc, /*isForwardDecl=*/false); PushOnScopeChains(PDecl, TUScope); + PDecl->startDefinition(); } + if (AttrList) ProcessDeclAttributeList(TUScope, PDecl, AttrList); if (!err && NumProtoRefs ) { @@ -647,7 +653,7 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, // If this is a forward declaration and we are supposed to warn in this // case, do it. - if (WarnOnDeclarations && PDecl->isForwardDecl()) + if (WarnOnDeclarations && !PDecl->hasDefinition()) Diag(ProtocolId[i].second, diag::warn_undef_protocolref) << ProtocolId[i].first; Protocols.push_back(PDecl); @@ -2497,6 +2503,9 @@ private: } void searchFrom(ObjCProtocolDecl *protocol) { + if (!protocol->hasDefinition()) + return; + // A method in a protocol declaration overrides declarations from // referenced ("parent") protocols. search(protocol->getReferencedProtocols()); |