diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index 024ff14456e4..ad80a930edc0 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -29,6 +29,12 @@ namespace llvm { namespace clang { struct LangOptions; class MultiKeywordSelector; // a private class used by Selector. + class IdentifierInfo; + class SourceLocation; + + /// IdentifierLocPair - A simple pair of identifier info and location. + typedef std::pair IdentifierLocPair; + /// IdentifierInfo - One of these records is kept for each identifier that /// is lexed. This contains information about whether the token was #define'd, diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 533c6b4846a0..ba1c62fb6b12 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -207,7 +207,7 @@ public: /// name of the referenced class. virtual void ActOnDefs(Scope *S, SourceLocation DeclStart, IdentifierInfo *ClassName, - llvm::SmallVector &Decls) {} + llvm::SmallVectorImpl &Decls) {} virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart, Declarator &D, ExprTy *BitfieldWidth) { return 0; @@ -627,7 +627,7 @@ public: SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, - IdentifierInfo **ProtocolNames, + const IdentifierLocPair *ProtocolNames, unsigned NumProtocols, SourceLocation EndProtoLoc, AttributeList *AttrList) { @@ -649,7 +649,7 @@ public: SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, - IdentifierInfo **ProtoRefNames, + const IdentifierLocPair *ProtoRefNames, unsigned NumProtoRefs, SourceLocation EndProtoLoc) { return 0; @@ -662,7 +662,7 @@ public: SourceLocation ClassLoc, IdentifierInfo *CategoryName, SourceLocation CategoryLoc, - IdentifierInfo **ProtoRefNames, + const IdentifierLocPair *ProtoRefNames, unsigned NumProtoRefs, SourceLocation EndProtoLoc) { return 0; @@ -768,7 +768,7 @@ public: } virtual DeclTy *ActOnForwardProtocolDeclaration( SourceLocation AtProtocolLoc, - IdentifierInfo **IdentList, + const IdentifierLocPair*IdentList, unsigned NumElts) { return 0; } @@ -777,10 +777,9 @@ public: /// issues error if they are not declared. It returns list of valid /// protocols found. virtual void FindProtocolDeclaration(SourceLocation TypeLoc, - IdentifierInfo **ProtocolId, + const IdentifierLocPair *ProtocolId, unsigned NumProtocols, - llvm::SmallVector & - Protocols) { + llvm::SmallVectorImpl &Protocols) { } //===----------------------- Obj-C Expressions --------------------------===// @@ -852,7 +851,8 @@ public: virtual DeclTy *ActOnStartClassInterface(SourceLocation interLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, - IdentifierInfo **ProtocolNames, unsigned NumProtocols, + const IdentifierLocPair *ProtocolNames, + unsigned NumProtocols, SourceLocation EndProtoLoc, AttributeList *AttrList); }; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 3421cc4c5024..0287120f0f0b 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -325,7 +325,7 @@ private: AttributeList *prefixAttrs = 0); void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, SourceLocation atLoc); - bool ParseObjCProtocolReferences(llvm::SmallVectorImpl &, + bool ParseObjCProtocolReferences(llvm::SmallVectorImpl &, SourceLocation &endProtoLoc); void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, tok::ObjCKeywordKind contextKey); diff --git a/clang/lib/Parse/MinimalAction.cpp b/clang/lib/Parse/MinimalAction.cpp index f48e8461666e..91f3c6e4a4d2 100644 --- a/clang/lib/Parse/MinimalAction.cpp +++ b/clang/lib/Parse/MinimalAction.cpp @@ -91,7 +91,8 @@ Action::DeclTy * MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, - IdentifierInfo **ProtocolNames, unsigned NumProtocols, + const IdentifierLocPair *ProtocolNames, + unsigned NumProtocols, SourceLocation EndProtoLoc, AttributeList *AttrList) { TypeNameInfo *TI = new TypeNameInfo(1, ClassName->getFETokenInfo()); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 95344c438ef7..1ac26a309fa2 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -413,8 +413,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { ConsumeToken(); // The identifier if (Tok.is(tok::less)) { SourceLocation endProtoLoc; - llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolRefs; ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc); + + // FIXME: New'ing this here seems wrong, why not have the action do + // it? llvm::SmallVector *ProtocolDecl = new llvm::SmallVector; DS.setProtocolQualifiers(ProtocolDecl); @@ -553,7 +556,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { case tok::less: if (!DS.hasTypeSpecifier()) { SourceLocation endProtoLoc; - llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolRefs; ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc); llvm::SmallVector *ProtocolDecl = new llvm::SmallVector; diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index baf2667a54f1..7d7ba10a38bf 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -131,7 +131,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( SourceLocation lparenLoc = ConsumeParen(); SourceLocation categoryLoc, rparenLoc; IdentifierInfo *categoryId = 0; - llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolRefs; // For ObjC2, the category name is optional (not an error). if (Tok.is(tok::identifier)) { @@ -185,7 +185,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( superClassLoc = ConsumeToken(); } // Next, we need to check for any protocol references. - llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolRefs; SourceLocation endProtoLoc; if (Tok.is(tok::less)) { if (ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc)) @@ -337,7 +337,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, /// copy /// nonatomic /// -void Parser::ParseObjCPropertyAttribute (ObjCDeclSpec &DS) { +void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { SourceLocation loc = ConsumeParen(); // consume '(' while (isObjCPropertyAttribute()) { const IdentifierInfo *II = Tok.getIdentifierInfo(); @@ -715,8 +715,9 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc, /// objc-protocol-refs: /// '<' identifier-list '>' /// -bool Parser::ParseObjCProtocolReferences( - llvm::SmallVectorImpl &ProtocolRefs, SourceLocation &endLoc){ +bool Parser:: +ParseObjCProtocolReferences(llvm::SmallVectorImpl &Protocols, + SourceLocation &endLoc) { assert(Tok.is(tok::less) && "expected <"); ConsumeToken(); // the "<" @@ -727,7 +728,8 @@ bool Parser::ParseObjCProtocolReferences( SkipUntil(tok::greater); return true; } - ProtocolRefs.push_back(Tok.getIdentifierInfo()); + Protocols.push_back(std::make_pair(Tok.getIdentifierInfo(), + Tok.getLocation())); ConsumeToken(); if (Tok.isNot(tok::comma)) @@ -865,15 +867,17 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) { IdentifierInfo *protocolName = Tok.getIdentifierInfo(); SourceLocation nameLoc = ConsumeToken(); - llvm::SmallVector ProtocolRefs; if (Tok.is(tok::semi)) { // forward declaration of one protocol. + IdentifierLocPair ProtoInfo(protocolName, nameLoc); ConsumeToken(); - ProtocolRefs.push_back(protocolName); + return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1); } + if (Tok.is(tok::comma)) { // list of forward declarations. + llvm::SmallVector ProtocolRefs; + ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc)); + // Parse the list of forward declarations. - ProtocolRefs.push_back(protocolName); - while (1) { ConsumeToken(); // the ',' if (Tok.isNot(tok::identifier)) { @@ -881,7 +885,8 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) { SkipUntil(tok::semi); return 0; } - ProtocolRefs.push_back(Tok.getIdentifierInfo()); + ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), + Tok.getLocation())); ConsumeToken(); // the identifier if (Tok.isNot(tok::comma)) @@ -890,17 +895,19 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) { // Consume the ';'. if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol")) return 0; - } - if (!ProtocolRefs.empty()) + return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtocolRefs[0], ProtocolRefs.size()); + } + // Last, and definitely not least, parse a protocol declaration. SourceLocation endProtoLoc; - if (Tok.is(tok::less)) { - if (ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc)) - return 0; - } + llvm::SmallVector ProtocolRefs; + + if (Tok.is(tok::less) && + ParseObjCProtocolReferences(ProtocolRefs, endProtoLoc)) + return 0; DeclTy *ProtoType = Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 4e563a934eaf..714256a4cf72 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -241,7 +241,7 @@ private: SourceLocation KWLoc, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr); virtual void ActOnDefs(Scope *S, SourceLocation DeclStart, IdentifierInfo - *ClassName, llvm::SmallVector &Decls); + *ClassName, llvm::SmallVectorImpl &Decls); virtual DeclTy *ActOnField(Scope *S, SourceLocation DeclStart, Declarator &D, ExprTy *BitfieldWidth); @@ -615,7 +615,8 @@ public: SourceLocation AtInterafceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, - IdentifierInfo **ProtocolNames, unsigned NumProtocols, + const IdentifierLocPair *ProtocolNames, + unsigned NumProtocols, SourceLocation EndProtoLoc, AttributeList *AttrList); virtual DeclTy *ActOnCompatiblityAlias( @@ -626,14 +627,16 @@ public: virtual DeclTy *ActOnStartProtocolInterface( SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, - IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs, + const IdentifierLocPair *ProtoRefNames, + unsigned NumProtoRefs, SourceLocation EndProtoLoc); virtual DeclTy *ActOnStartCategoryInterface( SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *CategoryName, SourceLocation CategoryLoc, - IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs, + const IdentifierLocPair *ProtoRefNames, + unsigned NumProtoRefs, SourceLocation EndProtoLoc); virtual DeclTy *ActOnStartClassImplementation( @@ -654,14 +657,13 @@ public: unsigned NumElts); virtual DeclTy *ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, - IdentifierInfo **IdentList, + const IdentifierLocPair *IdentList, unsigned NumElts); virtual void FindProtocolDeclaration(SourceLocation TypeLoc, - IdentifierInfo **ProtocolId, + const IdentifierLocPair *ProtocolId, unsigned NumProtocols, - llvm::SmallVector & - Protocols); + llvm::SmallVectorImpl &Protocols); void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e2ac7c5ea51a..7753a757961d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1789,7 +1789,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, /// Collect the instance variables declared in an Objective-C object. Used in /// the creation of structures from objects using the @defs directive. static void CollectIvars(ObjCInterfaceDecl *Class, - llvm::SmallVector &ivars) { + llvm::SmallVectorImpl &ivars) { if (Class->getSuperClass()) CollectIvars(Class->getSuperClass(), ivars); ivars.append(Class->ivar_begin(), Class->ivar_end()); @@ -1799,7 +1799,7 @@ static void CollectIvars(ObjCInterfaceDecl *Class, /// instance variables of ClassName into Decls. void Sema::ActOnDefs(Scope *S, SourceLocation DeclStart, IdentifierInfo *ClassName, - llvm::SmallVector &Decls) { + llvm::SmallVectorImpl &Decls) { // Check that ClassName is a valid class ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName); if (!Class) { diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 9de9efab4cdd..f71f4f4b786d 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -68,12 +68,13 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) { } } -Sema::DeclTy *Sema::ActOnStartClassInterface( - SourceLocation AtInterfaceLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *SuperName, SourceLocation SuperLoc, - IdentifierInfo **ProtocolNames, unsigned NumProtocols, - SourceLocation EndProtoLoc, AttributeList *AttrList) { +Sema::DeclTy *Sema:: +ActOnStartClassInterface(SourceLocation AtInterfaceLoc, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *SuperName, SourceLocation SuperLoc, + const IdentifierLocPair *ProtocolNames, + unsigned NumProtocols, + SourceLocation EndProtoLoc, AttributeList *AttrList) { assert(ClassName && "Missing class identifier"); // Check for another declaration kind with the same name. @@ -133,14 +134,14 @@ Sema::DeclTy *Sema::ActOnStartClassInterface( if (NumProtocols) { llvm::SmallVector RefProtos; for (unsigned int i = 0; i != NumProtocols; i++) { - ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtocolNames[i]]; + ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtocolNames[i].first]; if (!RefPDecl) - Diag(EndProtoLoc, diag::err_undef_protocolref, - ProtocolNames[i]->getName(), ClassName->getName()); + Diag(ProtocolNames[i].second, diag::err_undef_protocolref, + ProtocolNames[i].first->getName(), ClassName->getName()); else { if (RefPDecl->isForwardDecl()) - Diag(EndProtoLoc, diag::warn_undef_protocolref, - ProtocolNames[i]->getName(), ClassName->getName()); + Diag(ProtocolNames[i].second, diag::warn_undef_protocolref, + ProtocolNames[i].first->getName(), ClassName->getName()); RefProtos.push_back(RefPDecl); } } @@ -194,7 +195,7 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc, Sema::DeclTy *Sema::ActOnStartProtocolInterface( SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, - IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs, + const IdentifierLocPair *ProtoRefNames, unsigned NumProtoRefs, SourceLocation EndProtoLoc) { assert(ProtocolName && "Missing protocol identifier"); ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName]; @@ -219,14 +220,14 @@ Sema::DeclTy *Sema::ActOnStartProtocolInterface( /// Check then save referenced protocols. llvm::SmallVector Protocols; for (unsigned int i = 0; i != NumProtoRefs; i++) { - ObjCProtocolDecl *RefPDecl = ObjCProtocols[ProtoRefNames[i]]; + ObjCProtocolDecl *RefPDecl = ObjCProtocols[ProtoRefNames[i].first]; if (!RefPDecl) - Diag(ProtocolLoc, diag::err_undef_protocolref, - ProtoRefNames[i]->getName(), ProtocolName->getName()); + Diag(ProtoRefNames[i].second, diag::err_undef_protocolref, + ProtoRefNames[i].first->getName(), ProtocolName->getName()); else { if (RefPDecl->isForwardDecl()) - Diag(ProtocolLoc, diag::warn_undef_protocolref, - ProtoRefNames[i]->getName(), ProtocolName->getName()); + Diag(ProtoRefNames[i].second, diag::warn_undef_protocolref, + ProtoRefNames[i].first->getName(), ProtocolName->getName()); Protocols.push_back(RefPDecl); } } @@ -242,16 +243,15 @@ Sema::DeclTy *Sema::ActOnStartProtocolInterface( /// declarations in its 'Protocols' argument. void Sema::FindProtocolDeclaration(SourceLocation TypeLoc, - IdentifierInfo **ProtocolId, + const IdentifierLocPair *ProtocolId, unsigned NumProtocols, - llvm::SmallVector &Protocols) { + llvm::SmallVectorImpl &Protocols) { for (unsigned i = 0; i != NumProtocols; ++i) { - ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i]]; - if (!PDecl) - Diag(TypeLoc, diag::err_undeclared_protocol, - ProtocolId[i]->getName()); - else + if (ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i].first]) Protocols.push_back(PDecl); + else + Diag(ProtocolId[i].second, diag::err_undeclared_protocol, + ProtocolId[i].first->getName()); } } @@ -382,16 +382,15 @@ Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, /// ActOnForwardProtocolDeclaration - Action::DeclTy * Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, - IdentifierInfo **IdentList, unsigned NumElts) { + const IdentifierLocPair *IdentList, + unsigned NumElts) { llvm::SmallVector Protocols; for (unsigned i = 0; i != NumElts; ++i) { - IdentifierInfo *Ident = IdentList[i]; + IdentifierInfo *Ident = IdentList[i].first; ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident]; - if (PDecl == 0) { // Not already seen? - // FIXME: Pass in the location of the identifier! - PDecl = ObjCProtocolDecl::Create(Context, AtProtocolLoc, Ident); - } + if (PDecl == 0) // Not already seen? + PDecl = ObjCProtocolDecl::Create(Context, IdentList[i].second, Ident); Protocols.push_back(PDecl); } @@ -399,12 +398,14 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, &Protocols[0], Protocols.size()); } -Sema::DeclTy *Sema::ActOnStartCategoryInterface( - SourceLocation AtInterfaceLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *CategoryName, SourceLocation CategoryLoc, - IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs, - SourceLocation EndProtoLoc) { +Sema::DeclTy *Sema:: +ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *CategoryName, + SourceLocation CategoryLoc, + const IdentifierLocPair *ProtoRefNames, + unsigned NumProtoRefs, + SourceLocation EndProtoLoc) { ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName); ObjCCategoryDecl *CDecl = @@ -433,14 +434,14 @@ Sema::DeclTy *Sema::ActOnStartCategoryInterface( llvm::SmallVector RefProtocols; /// Check and then save the referenced protocols. for (unsigned int i = 0; i != NumProtoRefs; i++) { - ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtoRefNames[i]]; + ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtoRefNames[i].first]; if (!RefPDecl) - Diag(CategoryLoc, diag::err_undef_protocolref, - ProtoRefNames[i]->getName(), CategoryName->getName()); + Diag(ProtoRefNames[i].second, diag::err_undef_protocolref, + ProtoRefNames[i].first->getName(), CategoryName->getName()); else { if (RefPDecl->isForwardDecl()) - Diag(CategoryLoc, diag::warn_undef_protocolref, - ProtoRefNames[i]->getName(), CategoryName->getName()); + Diag(ProtoRefNames[i].second, diag::warn_undef_protocolref, + ProtoRefNames[i].first->getName(), CategoryName->getName()); RefProtocols.push_back(RefPDecl); } }