From: Chris Lattner Date: Sat, 26 Jul 2008 04:03:38 +0000 (+0000) Subject: pull protocol resolution out into ActOnStartProtocolInterface. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e13b9595dc1e2f4288bec34f3412359f648e84a5;p=clang pull protocol resolution out into ActOnStartProtocolInterface. This temporarily duplicates ParseObjCProtocolReferences, but it will be removed in the future. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54092 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 47047b911f..7ffbbfaf9c 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -645,13 +645,12 @@ public: // ActOnStartProtocolInterface - this action is called immdiately after // parsing the prologue for a protocol interface. - virtual DeclTy *ActOnStartProtocolInterface( - SourceLocation AtProtoInterfaceLoc, - IdentifierInfo *ProtocolName, - SourceLocation ProtocolLoc, - const IdentifierLocPair *ProtoRefNames, - unsigned NumProtoRefs, - SourceLocation EndProtoLoc) { + virtual DeclTy *ActOnStartProtocolInterface(SourceLocation AtProtoLoc, + IdentifierInfo *ProtocolName, + SourceLocation ProtocolLoc, + DeclTy * const *ProtoRefNames, + unsigned NumProtoRefs, + SourceLocation EndProtoLoc) { return 0; } // ActOnStartCategoryInterface - this action is called immdiately after @@ -776,8 +775,7 @@ public: /// FindProtocolDeclaration - This routine looks up protocols and /// issues error if they are not declared. It returns list of valid /// protocols found. - virtual void FindProtocolDeclaration(SourceLocation TypeLoc, - bool WarnOnDeclarations, + virtual void FindProtocolDeclaration(bool WarnOnDeclarations, const IdentifierLocPair *ProtocolId, unsigned NumProtocols, llvm::SmallVectorImpl &ResProtos) { diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index a4033a0ca6..00f7822015 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -328,6 +328,9 @@ private: SourceLocation atLoc); bool ParseObjCProtocolReferences(llvm::SmallVectorImpl &, SourceLocation &endProtoLoc); + bool ParseObjCProtocolReferences(llvm::SmallVectorImpl &P, + bool WarnOnDeclarations, + SourceLocation &EndProtoLoc); void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, tok::ObjCKeywordKind contextKey); DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index e047d601ef..f66bb99962 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -431,13 +431,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { continue; SourceLocation EndProtoLoc; - llvm::SmallVector ProtocolRefs; - ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc); - llvm::SmallVector ProtocolDecl; - Actions.FindProtocolDeclaration(Loc, false, - &ProtocolRefs[0], ProtocolRefs.size(), - ProtocolDecl); + ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc); DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size()); DS.SetRangeEnd(EndProtoLoc); @@ -572,12 +567,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { { SourceLocation EndProtoLoc; - llvm::SmallVector ProtocolRefs; - ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc); llvm::SmallVector ProtocolDecl; - Actions.FindProtocolDeclaration(Loc, false, - &ProtocolRefs[0], ProtocolRefs.size(), - ProtocolDecl); + ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc); DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size()); DS.SetRangeEnd(EndProtoLoc); diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index d495e6f062..1bfc2a949b 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -746,6 +746,48 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl &Protocols, return true; } +/// objc-protocol-refs: +/// '<' identifier-list '>' +/// +bool Parser:: +ParseObjCProtocolReferences(llvm::SmallVectorImpl &Protocols, + bool WarnOnDeclarations, SourceLocation &EndLoc) { + assert(Tok.is(tok::less) && "expected <"); + + ConsumeToken(); // the "<" + + llvm::SmallVector ProtocolIdents; + + while (1) { + if (Tok.isNot(tok::identifier)) { + Diag(Tok, diag::err_expected_ident); + SkipUntil(tok::greater); + return true; + } + ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), + Tok.getLocation())); + ConsumeToken(); + + if (Tok.isNot(tok::comma)) + break; + ConsumeToken(); + } + + // Consume the '>'. + if (Tok.isNot(tok::greater)) { + Diag(Tok, diag::err_expected_greater); + return true; + } + + EndLoc = ConsumeAnyToken(); + + // Convert the list of protocols identifiers into a list of protocol decls. + Actions.FindProtocolDeclaration(WarnOnDeclarations, + &ProtocolIdents[0], ProtocolIdents.size(), + Protocols); + return false; +} + /// objc-class-instance-variables: /// '{' objc-instance-variable-decl-list[opt] '}' /// @@ -899,17 +941,17 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) { } // Last, and definitely not least, parse a protocol declaration. - SourceLocation endProtoLoc; - llvm::SmallVector ProtocolRefs; + SourceLocation EndProtoLoc; + llvm::SmallVector ProtocolRefs; if (Tok.is(tok::less) && - ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc)) + ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) return 0; - DeclTy *ProtoType = Actions.ActOnStartProtocolInterface(AtLoc, - protocolName, nameLoc, - &ProtocolRefs[0], - ProtocolRefs.size(), endProtoLoc); + DeclTy *ProtoType = + Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, + &ProtocolRefs[0], ProtocolRefs.size(), + EndProtoLoc); ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); // The @ sign was already consumed by ParseObjCInterfaceDeclList(). diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 3d4552d202..7772006510 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -621,8 +621,7 @@ public: virtual DeclTy *ActOnStartProtocolInterface( SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, - const IdentifierLocPair *ProtoRefNames, - unsigned NumProtoRefs, + DeclTy * const *ProtoRefNames, unsigned NumProtoRefs, SourceLocation EndProtoLoc); virtual DeclTy *ActOnStartCategoryInterface( @@ -654,8 +653,7 @@ public: const IdentifierLocPair *IdentList, unsigned NumElts); - virtual void FindProtocolDeclaration(SourceLocation TypeLoc, - bool WarnOnDeclarations, + virtual void FindProtocolDeclaration(bool WarnOnDeclarations, const IdentifierLocPair *ProtocolId, unsigned NumProtocols, llvm::SmallVectorImpl &Protocols); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 9d2869be8a..5bafa236fb 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -195,11 +195,13 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc, return AliasDecl; } -Sema::DeclTy *Sema::ActOnStartProtocolInterface( - SourceLocation AtProtoInterfaceLoc, - IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, - const IdentifierLocPair *ProtoRefNames, unsigned NumProtoRefs, - SourceLocation EndProtoLoc) { +Sema::DeclTy * +Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, + IdentifierInfo *ProtocolName, + SourceLocation ProtocolLoc, + DeclTy * const *ProtoRefs, + unsigned NumProtoRefs, + SourceLocation EndProtoLoc) { assert(ProtocolName && "Missing protocol identifier"); ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName]; if (PDecl) { @@ -221,21 +223,7 @@ Sema::DeclTy *Sema::ActOnStartProtocolInterface( if (NumProtoRefs) { /// Check then save referenced protocols. - llvm::SmallVector Protocols; - for (unsigned int i = 0; i != NumProtoRefs; i++) { - ObjCProtocolDecl *RefPDecl = ObjCProtocols[ProtoRefNames[i].first]; - if (!RefPDecl) - Diag(ProtoRefNames[i].second, diag::err_undeclared_protocol, - ProtoRefNames[i].first->getName()); - else { - if (RefPDecl->isForwardDecl()) - Diag(ProtoRefNames[i].second, diag::warn_undef_protocolref, - ProtoRefNames[i].first->getName()); - Protocols.push_back(RefPDecl); - } - } - if (!Protocols.empty()) - PDecl->addReferencedProtocols(&Protocols[0], Protocols.size()); + PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs); PDecl->setLocEnd(EndProtoLoc); } return PDecl; @@ -245,7 +233,7 @@ Sema::DeclTy *Sema::ActOnStartProtocolInterface( /// issuer error if they are not declared. It returns list of protocol /// declarations in its 'Protocols' argument. void -Sema::FindProtocolDeclaration(SourceLocation TypeLoc, bool WarnOnDeclarations, +Sema::FindProtocolDeclaration(bool WarnOnDeclarations, const IdentifierLocPair *ProtocolId, unsigned NumProtocols, llvm::SmallVectorImpl &Protocols) {