From: Douglas Gregor Date: Sun, 1 Jan 2012 21:23:57 +0000 (+0000) Subject: Eliminate ObjCForwardProtocolDecl, which is redundant now that X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd9482d859a74bf2c45ef8b8aedec61c0e1c8374;p=clang Eliminate ObjCForwardProtocolDecl, which is redundant now that ObjCProtocolDecl modules forward declarations properly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147415 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index f99203ade4..157544ff86 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1221,55 +1221,6 @@ public: friend class ASTDeclWriter; }; -/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations. -/// For example: -/// -/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; -/// -class ObjCForwardProtocolDecl : public Decl { - virtual void anchor(); - - ObjCProtocolList ReferencedProtocols; - - ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, - ObjCProtocolDecl *const *Elts, unsigned nElts, - const SourceLocation *Locs, ASTContext &C); - -public: - static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - ObjCProtocolDecl *const *Elts, - unsigned Num, - const SourceLocation *Locs); - - static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L) { - return Create(C, DC, L, 0, 0, 0); - } - - typedef ObjCProtocolList::iterator protocol_iterator; - protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} - protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } - typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; - protocol_loc_iterator protocol_loc_begin() const { - return ReferencedProtocols.loc_begin(); - } - protocol_loc_iterator protocol_loc_end() const { - return ReferencedProtocols.loc_end(); - } - - unsigned protocol_size() const { return ReferencedProtocols.size(); } - - /// setProtocolList - Set the list of forward protocols. - void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - const SourceLocation *Locs, ASTContext &C) { - ReferencedProtocols.set(List, Num, Locs, C); - } - static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCForwardProtocolDecl *D) { return true; } - static bool classofKind(Kind K) { return K == ObjCForwardProtocol; } -}; - /// ObjCCategoryDecl - Represents a category declaration. A category allows /// you to add methods to an existing class (without subclassing or modifying /// the original class interface or implementation:-). Categories don't allow diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0c19351d88..d22d67dbc2 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1162,10 +1162,6 @@ DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, { DEF_TRAVERSE_DECL(LinkageSpecDecl, { }) -DEF_TRAVERSE_DECL(ObjCForwardProtocolDecl, { - // FIXME: implement this - }) - DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, { // FIXME: implement this }) diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index fbe4831f6b..6f2bb35725 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -66,7 +66,6 @@ def Named : Decl<1>; def ObjCCompatibleAlias : DDecl; def LinkageSpec : Decl, DeclContext; def ObjCPropertyImpl : Decl; -def ObjCForwardProtocol : Decl; def FileScopeAsm : Decl; def AccessSpec : Decl; def Friend : Decl; diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index e3ca12af9f..7b6042ecf7 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -1206,8 +1206,8 @@ private: ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations - Parser::DeclGroupPtrTy ParseObjCAtDirectives(); - Parser::DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); + DeclGroupPtrTy ParseObjCAtDirectives(); + DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, ParsedAttributes &prefixAttrs); void ParseObjCClassInstanceVariables(Decl *interfaceDecl, @@ -1221,8 +1221,8 @@ private: bool ParseObjCProtocolQualifiers(DeclSpec &DS); void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Decl *CDecl); - Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc, - ParsedAttributes &prefixAttrs); + DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc, + ParsedAttributes &prefixAttrs); Decl *ObjCImpDecl; SmallVector PendingObjCImpDecl; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 0ea55f8db8..cd401792b6 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5255,7 +5255,7 @@ public: SourceLocation *IdentLocs, unsigned NumElts); - Decl *ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, + DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, const IdentifierLocPair *IdentList, unsigned NumElts, AttributeList *attrList); diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index bd6e3a2b40..5d9e86cb08 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -816,8 +816,6 @@ namespace clang { DECL_OBJC_IVAR, /// \brief A ObjCAtDefsFieldDecl record. DECL_OBJC_AT_DEFS_FIELD, - /// \brief A ObjCForwardProtocolDecl record. - DECL_OBJC_FORWARD_PROTOCOL, /// \brief A ObjCCategoryDecl record. DECL_OBJC_CATEGORY, /// \brief A ObjCCategoryImplDecl record. diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 9931961c05..6ee8ba3a5f 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -127,7 +127,6 @@ namespace clang { Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D); Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D); Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); - Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); @@ -3562,50 +3561,6 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { return ToImpl; } -Decl * -ASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - // Import the context of this declaration. - DeclContext *DC = Importer.ImportContext(D->getDeclContext()); - if (!DC) - return 0; - - DeclContext *LexicalDC = DC; - if (D->getDeclContext() != D->getLexicalDeclContext()) { - LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); - if (!LexicalDC) - return 0; - } - - // Import the location of this declaration. - SourceLocation Loc = Importer.Import(D->getLocation()); - - SmallVector Protocols; - SmallVector Locations; - ObjCForwardProtocolDecl::protocol_loc_iterator FromProtoLoc - = D->protocol_loc_begin(); - for (ObjCForwardProtocolDecl::protocol_iterator FromProto - = D->protocol_begin(), FromProtoEnd = D->protocol_end(); - FromProto != FromProtoEnd; - ++FromProto, ++FromProtoLoc) { - ObjCProtocolDecl *ToProto - = cast_or_null(Importer.Import(*FromProto)); - if (!ToProto) - continue; - - Protocols.push_back(ToProto); - Locations.push_back(Importer.Import(*FromProtoLoc)); - } - - ObjCForwardProtocolDecl *ToForward - = ObjCForwardProtocolDecl::Create(Importer.getToContext(), DC, Loc, - Protocols.data(), Protocols.size(), - Locations.data()); - ToForward->setLexicalDeclContext(LexicalDC); - LexicalDC->addDeclInternal(ToForward); - Importer.Imported(D, ToForward); - return ToForward; -} - Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { // For template arguments, we adopt the translation unit as our declaration // context. This context will be fixed when the actual template declaration diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index b4a4eb1d13..847e906af7 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -733,7 +733,6 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { case Decl::ObjCCategory: case Decl::ObjCCategoryImpl: case Decl::ObjCCompatibleAlias: - case Decl::ObjCForwardProtocol: case Decl::ObjCImplementation: case Decl::ObjCMethod: case Decl::ObjCProperty: diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index a71275a2c1..d60edd06e9 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -496,7 +496,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case FileScopeAsm: case StaticAssert: case ObjCPropertyImpl: - case ObjCForwardProtocol: case Block: case TranslationUnit: diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 27da21a18f..aabea0434c 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -1041,30 +1041,6 @@ void ObjCProtocolDecl::startDefinition() { L->CompletedObjCForwardRef(this); } -//===----------------------------------------------------------------------===// -// ObjCForwardProtocolDecl -//===----------------------------------------------------------------------===// - -void ObjCForwardProtocolDecl::anchor() { } - -ObjCForwardProtocolDecl:: -ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, - ObjCProtocolDecl *const *Elts, unsigned nElts, - const SourceLocation *Locs, ASTContext &C) -: Decl(ObjCForwardProtocol, DC, L) { - ReferencedProtocols.set(Elts, nElts, Locs, C); -} - - -ObjCForwardProtocolDecl * -ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - ObjCProtocolDecl *const *Elts, - unsigned NumElts, - const SourceLocation *Locs) { - return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C); -} - //===----------------------------------------------------------------------===// // ObjCCategoryDecl //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 9b72bb416a..73dac3b73e 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -72,7 +72,6 @@ namespace { void VisitObjCMethodDecl(ObjCMethodDecl *D); void VisitObjCImplementationDecl(ObjCImplementationDecl *D); void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); - void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); void VisitObjCProtocolDecl(ObjCProtocolDecl *D); void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); void VisitObjCCategoryDecl(ObjCCategoryDecl *D); @@ -932,17 +931,12 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { // FIXME: implement the rest... } -void DeclPrinter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - Out << "@protocol "; - for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); - I != E; ++I) { - if (I != D->protocol_begin()) Out << ", "; - Out << **I; - } -} - void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { + if (!PID->isThisDeclarationADefinition()) { + Out << "@protocol " << PID->getIdentifier() << ";\n"; + return; + } + Out << "@protocol " << *PID << '\n'; VisitDeclContext(PID, false); Out << "@end"; diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp index 561fb8f372..4ef4ce5e38 100644 --- a/lib/AST/DumpXML.cpp +++ b/lib/AST/DumpXML.cpp @@ -810,17 +810,13 @@ struct XMLDumper : public XMLDeclVisitor, } } - // ObjCForwardProtocolDecl - void visitObjCForwardProtocolDeclChildren(ObjCForwardProtocolDecl *D) { - for (ObjCForwardProtocolDecl::protocol_iterator - I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I) - visitDeclRef(*I); - } - // ObjCProtocolDecl void visitObjCProtocolDeclAttrs(ObjCProtocolDecl *D) { } void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) { + if (!D->isThisDeclarationADefinition()) + return; + if (D->protocol_begin() != D->protocol_end()) { TemporaryContainer C(*this, "protocols"); for (ObjCInterfaceDecl::protocol_iterator @@ -829,6 +825,9 @@ struct XMLDumper : public XMLDeclVisitor, } } void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) { + if (!D->isThisDeclarationADefinition()) + return; + visitDeclContext(D); } diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 43077cefa0..05087f0e95 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -65,7 +65,6 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::AccessSpec: case Decl::LinkageSpec: case Decl::ObjCPropertyImpl: - case Decl::ObjCForwardProtocol: case Decl::FileScopeAsm: case Decl::Friend: case Decl::FriendTemplate: diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 12c4dff39c..9e772b40c4 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2375,7 +2375,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { // Objective-C Decls // Forward declarations, no (immediate) code generation. - case Decl::ObjCForwardProtocol: case Decl::ObjCInterface: break; @@ -2386,10 +2385,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; } - case Decl::ObjCProtocol: - ObjCRuntime->GenerateProtocol(cast(D)); + case Decl::ObjCProtocol: { + ObjCProtocolDecl *Proto = cast(D); + if (Proto->isThisDeclarationADefinition()) + ObjCRuntime->GenerateProtocol(Proto); break; - + } + case Decl::ObjCCategoryImpl: // Categories have properties but don't support synthesize so we // can ignore them here. diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 5a9f077263..5272636fa9 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -827,17 +827,7 @@ void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { Hash = llvm::HashString(NameStr, Hash); } return; - } - - if (ObjCForwardProtocolDecl *Forward - = dyn_cast(D)) { - for (ObjCForwardProtocolDecl::protocol_iterator - P = Forward->protocol_begin(), - PEnd = Forward->protocol_end(); - P != PEnd; ++P) - AddTopLevelDeclarationToHash(*P, Hash); - return; - } + } } class TopLevelDeclTrackerConsumer : public ASTConsumer { diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 83b1ed0c3c..8260d188a3 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -50,15 +50,13 @@ Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() { } case tok::objc_protocol: { ParsedAttributes attrs(AttrFactory); - SingleDecl = ParseObjCAtProtocolDeclaration(AtLoc, attrs); - break; + return ParseObjCAtProtocolDeclaration(AtLoc, attrs); } case tok::objc_implementation: SingleDecl = ParseObjCAtImplementationDeclaration(AtLoc); break; case tok::objc_end: return ParseObjCAtEndDeclaration(AtLoc); - break; case tok::objc_compatibility_alias: SingleDecl = ParseObjCAtAliasDeclaration(AtLoc); break; @@ -1349,8 +1347,9 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, /// "@protocol identifier ;" should be resolved as "@protocol /// identifier-list ;": objc-interface-decl-list may not start with a /// semicolon in the first alternative if objc-protocol-refs are omitted. -Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, - ParsedAttributes &attrs) { +Parser::DeclGroupPtrTy +Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, + ParsedAttributes &attrs) { assert(Tok.isObjCAtKeyword(tok::objc_protocol) && "ParseObjCAtProtocolDeclaration(): Expected @protocol"); ConsumeToken(); // the "protocol" identifier @@ -1358,12 +1357,12 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCProtocolDecl(getCurScope()); cutOffParsing(); - return 0; + return DeclGroupPtrTy(); } if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing protocol name. - return 0; + return DeclGroupPtrTy(); } // Save the protocol name, then consume it. IdentifierInfo *protocolName = Tok.getIdentifierInfo(); @@ -1388,7 +1387,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); SkipUntil(tok::semi); - return 0; + return DeclGroupPtrTy(); } ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), Tok.getLocation())); @@ -1399,7 +1398,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, } // Consume the ';'. if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol")) - return 0; + return DeclGroupPtrTy(); return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtocolRefs[0], @@ -1415,7 +1414,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (Tok.is(tok::less) && ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, LAngleLoc, EndProtoLoc)) - return 0; + return DeclGroupPtrTy(); Decl *ProtoType = Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, @@ -1425,7 +1424,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, EndProtoLoc, attrs.getList()); ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType); - return ProtoType; + return Actions.ConvertDeclToDeclGroup(ProtoType); } /// objc-implementation: diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 8cfc02bde1..6914b8e018 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -776,12 +776,11 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS, if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID)) Diag(AtLoc, DiagID) << PrevSpec; - Decl *TheDecl = 0; if (Tok.isObjCAtKeyword(tok::objc_protocol)) - TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); - else - TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()); - return Actions.ConvertDeclToDeclGroup(TheDecl); + return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); + + return Actions.ConvertDeclToDeclGroup( + ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes())); } // If the declspec consisted only of 'extern' and we have a string diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp index a126e8524e..19277e8ea4 100644 --- a/lib/Rewrite/RewriteObjC.cpp +++ b/lib/Rewrite/RewriteObjC.cpp @@ -172,6 +172,13 @@ namespace { } } + if (ObjCProtocolDecl *Proto = dyn_cast(*I)) { + if (!Proto->isThisDeclarationADefinition()) { + RewriteForwardProtocolDecl(D); + break; + } + } + HandleTopLevelSingleDecl(*I); } return true; @@ -275,7 +282,8 @@ namespace { ValueDecl *VD, bool def=false); void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); - void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl); + void RewriteForwardProtocolDecl(DeclGroupRef D); + void RewriteForwardProtocolDecl(const llvm::SmallVector &DG); void RewriteMethodDeclaration(ObjCMethodDecl *Method); void RewriteProperty(ObjCPropertyDecl *prop); void RewriteFunctionDecl(FunctionDecl *FD); @@ -662,10 +670,8 @@ void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) { } else if (ObjCCategoryDecl *CD = dyn_cast(D)) { RewriteCategoryDecl(CD); } else if (ObjCProtocolDecl *PD = dyn_cast(D)) { - RewriteProtocolDecl(PD); - } else if (ObjCForwardProtocolDecl *FP = - dyn_cast(D)){ - RewriteForwardProtocolDecl(FP); + if (PD->isThisDeclarationADefinition()) + RewriteProtocolDecl(PD); } else if (LinkageSpecDecl *LSD = dyn_cast(D)) { // Recurse into linkage specifications for (DeclContext::decl_iterator DI = LSD->decls_begin(), @@ -689,6 +695,26 @@ void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) { continue; } } + + if (ObjCProtocolDecl *Proto = dyn_cast((*DI))) { + if (!Proto->isThisDeclarationADefinition()) { + SmallVector DG; + SourceLocation StartLoc = Proto->getLocStart(); + do { + if (isa(*DI) && + !cast(*DI)->isThisDeclarationADefinition() && + StartLoc == (*DI)->getLocStart()) + DG.push_back(*DI); + else + break; + + ++DI; + } while (DI != DIEnd); + RewriteForwardProtocolDecl(DG); + continue; + } + } + HandleTopLevelSingleDecl(*DI); ++DI; } @@ -1002,8 +1028,17 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { } } -void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) { - SourceLocation LocStart = PDecl->getLocation(); +void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { + SourceLocation LocStart = (*D.begin())->getLocStart(); + if (LocStart.isInvalid()) + llvm_unreachable("Invalid SourceLocation"); + // FIXME: handle forward protocol that are declared across multiple lines. + ReplaceText(LocStart, 0, "// "); +} + +void +RewriteObjC::RewriteForwardProtocolDecl(const llvm::SmallVector &DG) { + SourceLocation LocStart = DG[0]->getLocStart(); if (LocStart.isInvalid()) llvm_unreachable("Invalid SourceLocation"); // FIXME: handle forward protocol that are declared across multiple lines. diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 17e02c7473..80496c5c44 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -425,10 +425,13 @@ void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { CursorKind = getCursorKindForDecl(Declaration); if (CursorKind == CXCursor_UnexposedDecl) { - // FIXME: Forward declarations of Objective-C classes are not directly - // exposed, but we want code completion to treat them like an @interface. + // FIXME: Forward declarations of Objective-C classes and protocols + // are not directly exposed, but we want code completion to treat them + // like a definition. if (isa(Declaration)) CursorKind = CXCursor_ObjCInterfaceDecl; + else if (isa(Declaration)) + CursorKind = CXCursor_ObjCProtocolDecl; else CursorKind = CXCursor_NotImplemented; } diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 6843ca7e6c..78e3c355d6 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -2783,9 +2783,6 @@ CXCursorKind clang::getCursorKindForDecl(Decl *D) { case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl; // FIXME return CXCursor_UnexposedDecl; - case Decl::ObjCForwardProtocol: - // FIXME - return CXCursor_UnexposedDecl; case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl; case Decl::ObjCInterface: @@ -2804,7 +2801,12 @@ CXCursorKind clang::getCursorKindForDecl(Decl *D) { case Decl::CXXDestructor: return CXCursor_Destructor; case Decl::CXXConversion: return CXCursor_ConversionFunction; case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl; - case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; + case Decl::ObjCProtocol: + if (cast(D)->isThisDeclarationADefinition()) + return CXCursor_ObjCProtocolDecl; + + return CXCursor_UnexposedDecl; + case Decl::ParmVar: return CXCursor_ParmDecl; case Decl::Typedef: return CXCursor_TypedefDecl; case Decl::TypeAlias: return CXCursor_TypeAliasDecl; @@ -5422,17 +5424,6 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, if (ObjCProtocolDecl *Proto = dyn_cast(*D)) if (!OnlyForwardDeclarations || !Proto->hasDefinition()) Results.AddResult(Result(Proto, 0), CurContext, 0, false); - - // Record any forward-declared protocols we find. - if (ObjCForwardProtocolDecl *Forward - = dyn_cast(*D)) { - for (ObjCForwardProtocolDecl::protocol_iterator - P = Forward->protocol_begin(), - PEnd = Forward->protocol_end(); - P != PEnd; ++P) - if (!OnlyForwardDeclarations || !(*P)->hasDefinition()) - Results.AddResult(Result(*P, 0), CurContext, 0, false); - } } } diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 3612e94371..51d282a546 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -694,14 +694,12 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, } /// ActOnForwardProtocolDeclaration - Handle @protocol foo; -Decl * +Sema::DeclGroupPtrTy Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, const IdentifierLocPair *IdentList, unsigned NumElts, AttributeList *attrList) { - SmallVector Protocols; - SmallVector ProtoLocs; - + SmallVector DeclsInGroup; for (unsigned i = 0; i != NumElts; ++i) { IdentifierInfo *Ident = IdentList[i].first; ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentList[i].second, @@ -712,6 +710,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, PrevDecl, /*isForwardDecl=*/true); PushOnScopeChains(PDecl, TUScope); + CheckObjCDeclScope(PDecl); if (attrList) ProcessDeclAttributeList(TUScope, PDecl, attrList); @@ -719,17 +718,10 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, if (PrevDecl) mergeDeclAttributes(PDecl, PrevDecl); - Protocols.push_back(PDecl); - ProtoLocs.push_back(IdentList[i].second); + DeclsInGroup.push_back(PDecl); } - ObjCForwardProtocolDecl *PDecl = - ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc, - Protocols.data(), Protocols.size(), - ProtoLocs.data()); - CurContext->addDecl(PDecl); - CheckObjCDeclScope(PDecl); - return PDecl; + return BuildDeclaratorGroup(DeclsInGroup.data(), DeclsInGroup.size(), false); } Decl *Sema:: diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 63d14f46c1..4f53487dcd 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2767,18 +2767,6 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); Visited.add(ND); } - } else if (ObjCForwardProtocolDecl *ForwardProto - = dyn_cast(*D)) { - for (ObjCForwardProtocolDecl::protocol_iterator - P = ForwardProto->protocol_begin(), - PEnd = ForwardProto->protocol_end(); - P != PEnd; - ++P) { - if (NamedDecl *ND = Result.getAcceptableDecl(*P)) { - Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); - Visited.add(ND); - } - } } // Visit transparent contexts and inline namespaces inside this context. diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 566b0e74f4..1df67f22ab 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -279,7 +279,6 @@ namespace clang { void VisitObjCIvarDecl(ObjCIvarDecl *D); void VisitObjCProtocolDecl(ObjCProtocolDecl *D); void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D); - void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); void VisitObjCCategoryDecl(ObjCCategoryDecl *D); void VisitObjCImplDecl(ObjCImplDecl *D); void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); @@ -794,21 +793,6 @@ void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) { VisitFieldDecl(FD); } -void ASTDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) { - VisitDecl(FPD); - unsigned NumProtoRefs = Record[Idx++]; - SmallVector ProtoRefs; - ProtoRefs.reserve(NumProtoRefs); - for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoRefs.push_back(ReadDeclAs(Record, Idx)); - SmallVector ProtoLocs; - ProtoLocs.reserve(NumProtoRefs); - for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); - FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), - Reader.getContext()); -} - void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { VisitObjCContainerDecl(CD); CD->ClassInterface = ReadDeclAs(Record, Idx); @@ -1956,9 +1940,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0); break; - case DECL_OBJC_FORWARD_PROTOCOL: - D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation()); - break; case DECL_OBJC_CATEGORY: D = ObjCCategoryDecl::Create(Context, Decl::EmptyShell()); break; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 7a3916f91b..9ed2a6c6d9 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -865,7 +865,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_OBJC_PROTOCOL); RECORD(DECL_OBJC_IVAR); RECORD(DECL_OBJC_AT_DEFS_FIELD); - RECORD(DECL_OBJC_FORWARD_PROTOCOL); RECORD(DECL_OBJC_CATEGORY); RECORD(DECL_OBJC_CATEGORY_IMPL); RECORD(DECL_OBJC_IMPLEMENTATION); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index f6fc4304e7..b0c54e391b 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -114,7 +114,6 @@ namespace clang { void VisitObjCIvarDecl(ObjCIvarDecl *D); void VisitObjCProtocolDecl(ObjCProtocolDecl *D); void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D); - void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); void VisitObjCCategoryDecl(ObjCCategoryDecl *D); void VisitObjCImplDecl(ObjCImplDecl *D); void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); @@ -545,19 +544,6 @@ void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) { Code = serialization::DECL_OBJC_AT_DEFS_FIELD; } -void ASTDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - VisitDecl(D); - Record.push_back(D->protocol_size()); - for (ObjCForwardProtocolDecl::protocol_iterator - I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) - Writer.AddDeclRef(*I, Record); - for (ObjCForwardProtocolDecl::protocol_loc_iterator - PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end(); - PL != PLEnd; ++PL) - Writer.AddSourceLocation(*PL, Record); - Code = serialization::DECL_OBJC_FORWARD_PROTOCOL; -} - void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { VisitObjCContainerDecl(D); Writer.AddDeclRef(D->getClassInterface(), Record); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f2e6b01329..280a48c101 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -951,6 +951,9 @@ bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { } bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { + if (!PID->isThisDeclarationADefinition()) + return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU)); + ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), E = PID->protocol_end(); I != E; ++I, ++PL) @@ -1046,17 +1049,6 @@ bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { return VisitObjCImplDecl(D); } -bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); - for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); - I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return false; -} - bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) { if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl()) return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU)); @@ -3882,9 +3874,6 @@ CXCursor clang_getCursorReferenced(CXCursor C) { return clang_getNullCursor(); if (UsingDecl *Using = dyn_cast(D)) return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu); - if (ObjCForwardProtocolDecl *Protocols - = dyn_cast(D)) - return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu); if (ObjCPropertyImplDecl *PropImpl =dyn_cast(D)) if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) return MakeCXCursor(Property, tu); @@ -4158,10 +4147,6 @@ CXCursor clang_getCursorDefinition(CXCursor C) { return clang_getNullCursor(); - case Decl::ObjCForwardProtocol: - return MakeCursorOverloadedDeclRef(cast(D), - D->getLocation(), TU); - case Decl::Friend: if (NamedDecl *Friend = cast(D)->getFriendDecl()) return clang_getCursorDefinition(MakeCXCursor(Friend, TU)); @@ -4217,8 +4202,6 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) { Decl *D = Storage.get(); if (UsingDecl *Using = dyn_cast(D)) return Using->shadow_size(); - if (ObjCForwardProtocolDecl *Protocols =dyn_cast(D)) - return Protocols->protocol_size(); return 0; } @@ -4246,8 +4229,6 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { std::advance(Pos, index); return MakeCXCursor(cast(*Pos)->getTargetDecl(), TU); } - if (ObjCForwardProtocolDecl *Protocols = dyn_cast(D)) - return MakeCXCursor(Protocols->protocol_begin()[index], TU); return clang_getNullCursor(); } @@ -5175,7 +5156,6 @@ static CXLanguageKind getDeclLanguage(const Decl *D) { case Decl::ObjCCategory: case Decl::ObjCCategoryImpl: case Decl::ObjCCompatibleAlias: - case Decl::ObjCForwardProtocol: case Decl::ObjCImplementation: case Decl::ObjCInterface: case Decl::ObjCIvar: diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp index 1b57ef23ad..1c2ffbfeb8 100644 --- a/tools/libclang/CIndexUSRs.cpp +++ b/tools/libclang/CIndexUSRs.cpp @@ -76,7 +76,6 @@ public: void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); void VisitObjCContainerDecl(ObjCContainerDecl *CD); - void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *P); void VisitObjCMethodDecl(ObjCMethodDecl *MD); void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); @@ -309,12 +308,6 @@ void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { N.printName(Out); } -void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - // FIXME: @protocol declarations can refer to multiple protocols. We need - // to be able to traverse these. - IgnoreResults = true; -} - void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { switch (D->getKind()) { default: diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h index 184d36f180..f1258cb666 100644 --- a/tools/libclang/CursorVisitor.h +++ b/tools/libclang/CursorVisitor.h @@ -215,7 +215,6 @@ public: bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. - bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD); bool VisitLinkageSpecDecl(LinkageSpecDecl *D); bool VisitNamespaceDecl(NamespaceDecl *D); diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp index ee37bba942..9ff65b30f4 100644 --- a/tools/libclang/IndexDecl.cpp +++ b/tools/libclang/IndexDecl.cpp @@ -77,19 +77,6 @@ public: return true; } - bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - ObjCForwardProtocolDecl::protocol_loc_iterator LI = D->protocol_loc_begin(); - for (ObjCForwardProtocolDecl::protocol_iterator - I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) { - SourceLocation Loc = *LI; - ObjCProtocolDecl *PD = *I; - - bool isRedeclaration = PD->getLocation() != Loc; - IndexCtx.handleObjCForwardProtocol(PD, Loc, isRedeclaration); - } - return true; - } - bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { IndexCtx.handleObjCInterface(D); @@ -101,14 +88,12 @@ public: } bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) { - // Forward decls are handled at VisitObjCForwardProtocolDecl. - if (!D->isThisDeclarationADefinition()) - return true; - IndexCtx.handleObjCProtocol(D); - IndexCtx.indexTUDeclsInObjCContainer(); - IndexCtx.indexDeclContext(D); + if (D->isThisDeclarationADefinition()) { + IndexCtx.indexTUDeclsInObjCContainer(); + IndexCtx.indexDeclContext(D); + } return true; } diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp index 28efe3fd56..14dbc97002 100644 --- a/tools/libclang/IndexingContext.cpp +++ b/tools/libclang/IndexingContext.cpp @@ -390,17 +390,22 @@ bool IndexingContext::handleObjCImplementation( return handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo); } -bool IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D, - SourceLocation Loc, - bool isRedeclaration) { - ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, - isRedeclaration, - /*isImplementation=*/false); - return handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU), - ContDInfo); -} - bool IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) { + if (!D->isThisDeclarationADefinition()) { + if (suppressRefs() && markEntityOccurrenceInFile(D, D->getLocation())) + return false; // already occurred. + + // FIXME: This seems like the wrong definition for redeclaration. + bool isRedeclaration = D->hasDefinition() || D->getPreviousDeclaration(); + ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, + isRedeclaration, + /*isImplementation=*/false); + return handleObjCContainer(D, D->getLocation(), + MakeCursorObjCProtocolRef(D, D->getLocation(), + CXTU), + ContDInfo); + } + ScratchAlloc SA(*this); ObjCProtocolList EmptyProtoList; ObjCProtocolListInfo ProtListInfo(D->isThisDeclarationADefinition() diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h index 90801d9694..0091fd1f8c 100644 --- a/tools/libclang/IndexingContext.h +++ b/tools/libclang/IndexingContext.h @@ -372,10 +372,6 @@ public: bool handleObjCInterface(const ObjCInterfaceDecl *D); bool handleObjCImplementation(const ObjCImplementationDecl *D); - bool handleObjCForwardProtocol(const ObjCProtocolDecl *D, - SourceLocation Loc, - bool isRedeclaration); - bool handleObjCProtocol(const ObjCProtocolDecl *D); bool handleObjCCategory(const ObjCCategoryDecl *D);