diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 7 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 12 | ||||
-rw-r--r-- | lib/AST/DumpXML.cpp | 1 | ||||
-rw-r--r-- | lib/Rewrite/RewriteObjC.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 39 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 25 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 34 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 25 |
8 files changed, 95 insertions, 50 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 67045059cf..fe7049492f 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -3119,7 +3119,7 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { } ObjCProtocolDecl *ToProto = MergeWithProtocol; - if (!ToProto || ToProto->isForwardDecl()) { + if (!ToProto || !ToProto->hasDefinition()) { if (!ToProto) { ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Name.getAsIdentifierInfo(), Loc, @@ -3127,9 +3127,12 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { D->isInitiallyForwardDecl()); ToProto->setLexicalDeclContext(LexicalDC); LexicalDC->addDeclInternal(ToProto); - if (D->isInitiallyForwardDecl() && !D->isForwardDecl()) + if (D->isInitiallyForwardDecl() && D->hasDefinition()) ToProto->completedForwardDecl(); } + if (!ToProto->hasDefinition()) + ToProto->startDefinition(); + Importer.Imported(D, ToProto); // Import protocols diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 75100ecb3c..f5828fcb4c 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -1003,9 +1003,19 @@ ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, return NULL; } +void ObjCProtocolDecl::allocateDefinitionData() { + assert(!Data && "Protocol already has a definition!"); + Data = new (getASTContext()) DefinitionData; +} + +void ObjCProtocolDecl::startDefinition() { + allocateDefinitionData(); +} + void ObjCProtocolDecl::completedForwardDecl() { - assert(isForwardDecl() && "Only valid to call for forward refs"); + assert(!hasDefinition() && "Only valid to call for forward refs"); isForwardProtoDecl = false; + startDefinition(); if (ASTMutationListener *L = getASTContext().getASTMutationListener()) L->CompletedObjCForwardRef(this); } diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp index 959bbcbb17..561fb8f372 100644 --- a/lib/AST/DumpXML.cpp +++ b/lib/AST/DumpXML.cpp @@ -819,7 +819,6 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>, // ObjCProtocolDecl void visitObjCProtocolDeclAttrs(ObjCProtocolDecl *D) { - setFlag("forward_decl", D->isForwardDecl()); } void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) { if (D->protocol_begin() != D->protocol_end()) { diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp index 1b39061d50..a126e8524e 100644 --- a/lib/Rewrite/RewriteObjC.cpp +++ b/lib/Rewrite/RewriteObjC.cpp @@ -5171,7 +5171,7 @@ void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( static bool objc_protocol_methods = false; // Output struct protocol_methods holder of method selector and type. - if (!objc_protocol_methods && !PDecl->isForwardDecl()) { + if (!objc_protocol_methods && PDecl->hasDefinition()) { /* struct protocol_methods { SEL _cmd; char *method_types; 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()); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 476f8b5c02..f88a394e90 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -764,17 +764,29 @@ void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { PD->InitiallyForwardDecl = Record[Idx++]; PD->isForwardProtoDecl = Record[Idx++]; PD->setLocEnd(ReadSourceLocation(Record, Idx)); - unsigned NumProtoRefs = Record[Idx++]; - SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; - ProtoRefs.reserve(NumProtoRefs); - for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx)); - SmallVector<SourceLocation, 16> ProtoLocs; - ProtoLocs.reserve(NumProtoRefs); - for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); - PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), - Reader.getContext()); + + ObjCProtocolDecl *Def = ReadDeclAs<ObjCProtocolDecl>(Record, Idx); + if (PD == Def) { + // Read the definition. + PD->allocateDefinitionData(); + + unsigned NumProtoRefs = Record[Idx++]; + SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; + ProtoRefs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx)); + SmallVector<SourceLocation, 16> ProtoLocs; + ProtoLocs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); + PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), + Reader.getContext()); + + // FIXME: Note that we have deserialized a definition. + // Reader.PendingDefinitions.insert(PD); + } else if (Def && Def->Data) { + PD->Data = Def->Data; + } } void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) { diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 0692c023e4..f1394850ed 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -519,16 +519,23 @@ void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) { void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { VisitObjCContainerDecl(D); Record.push_back(D->isInitiallyForwardDecl()); - Record.push_back(D->isForwardDecl()); + Record.push_back(D->isForwardProtoDecl); Writer.AddSourceLocation(D->getLocEnd(), Record); - Record.push_back(D->protocol_size()); - for (ObjCProtocolDecl::protocol_iterator - I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) - Writer.AddDeclRef(*I, Record); - for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(), - PLEnd = D->protocol_loc_end(); - PL != PLEnd; ++PL) - Writer.AddSourceLocation(*PL, Record); + + ObjCProtocolDecl *Def = D->getDefinition(); + Writer.AddDeclRef(Def, Record); + + if (D == Def) { + Record.push_back(D->protocol_size()); + for (ObjCProtocolDecl::protocol_iterator + I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) + Writer.AddDeclRef(*I, Record); + for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(), + PLEnd = D->protocol_loc_end(); + PL != PLEnd; ++PL) + Writer.AddSourceLocation(*PL, Record); + } + Code = serialization::DECL_OBJC_PROTOCOL; } |