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 47047b9..7ffbbfa 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -645,13 +645,12 @@
// 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 @@
/// 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<DeclTy*> &ResProtos) {
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index a4033a0..00f7822 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -328,6 +328,9 @@
SourceLocation atLoc);
bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierLocPair> &,
SourceLocation &endProtoLoc);
+ bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &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 e047d60..f66bb99 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -431,13 +431,8 @@
continue;
SourceLocation EndProtoLoc;
- llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
- ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc);
-
llvm::SmallVector<DeclTy *, 8> 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 @@
{
SourceLocation EndProtoLoc;
- llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
- ParseObjCProtocolReferences(ProtocolRefs, EndProtoLoc);
llvm::SmallVector<DeclTy *, 8> 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 d495e6f..1bfc2a9 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -746,6 +746,48 @@
return true;
}
+/// objc-protocol-refs:
+/// '<' identifier-list '>'
+///
+bool Parser::
+ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &Protocols,
+ bool WarnOnDeclarations, SourceLocation &EndLoc) {
+ assert(Tok.is(tok::less) && "expected <");
+
+ ConsumeToken(); // the "<"
+
+ llvm::SmallVector<IdentifierLocPair, 8> 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 @@
}
// Last, and definitely not least, parse a protocol declaration.
- SourceLocation endProtoLoc;
- llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
+ SourceLocation EndProtoLoc;
+ llvm::SmallVector<DeclTy *, 8> 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 3d4552d..7772006 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -621,8 +621,7 @@
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 @@
const IdentifierLocPair *IdentList,
unsigned NumElts);
- virtual void FindProtocolDeclaration(SourceLocation TypeLoc,
- bool WarnOnDeclarations,
+ virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
const IdentifierLocPair *ProtocolId,
unsigned NumProtocols,
llvm::SmallVectorImpl<DeclTy *> &Protocols);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 9d2869b..5bafa23 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -195,11 +195,13 @@
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 @@
if (NumProtoRefs) {
/// Check then save referenced protocols.
- llvm::SmallVector<ObjCProtocolDecl*, 8> 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 @@
/// 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<DeclTy*> &Protocols) {