From: Douglas Gregor Date: Sat, 16 Jan 2010 15:02:53 +0000 (+0000) Subject: Keep track of the source locations for each protocol reference in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=18df52bbb5d28ca082064d31ae7558dbdae52377;p=clang Keep track of the source locations for each protocol reference in Objective-C classes, protocol definitions, forward protocol declarations, and categories. This information isn't actually used yet; that's coming next. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93636 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 920d31fc7c..9dc5abb3ad 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -75,6 +75,24 @@ public: } }; +/// \brief A list of Objective-C protocols, along with the source +/// locations at which they were referenced. +class ObjCProtocolList : public ObjCList { + SourceLocation *Locations; + + using ObjCList::set; + +public: + ObjCProtocolList() : ObjCList(), Locations(0) { } + + typedef const SourceLocation *loc_iterator; + loc_iterator loc_begin() const { return Locations; } + loc_iterator loc_end() const { return Locations + size(); } + + void set(ObjCProtocolDecl* const* InList, unsigned Elts, + const SourceLocation *Locs, ASTContext &Ctx); + void Destroy(ASTContext &Ctx); +}; /// ObjCMethodDecl - Represents an instance or class method declaration. @@ -410,7 +428,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { ObjCInterfaceDecl *SuperClass; /// Protocols referenced in interface header declaration - ObjCList ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; /// Instance variables in the interface. ObjCList IVars; @@ -442,7 +460,7 @@ public: SourceLocation ClassLoc = SourceLocation(), bool ForwardDecl = false, bool isInternal = false); - const ObjCList &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } @@ -459,9 +477,16 @@ public: : getClassMethod(Sel); } - typedef ObjCList::iterator protocol_iterator; + 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(); } typedef ObjCList::iterator ivar_iterator; @@ -473,14 +498,16 @@ public: /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } /// mergeClassExtensionProtocolList - Merge class extension's protocol list /// into the protocol list for this class. - void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, unsigned Num, - ASTContext &C); + void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, + unsigned Num, + const SourceLocation *Locs, + ASTContext &C); void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) { IVars.set(List, Num, C); @@ -660,7 +687,7 @@ public: /// class ObjCProtocolDecl : public ObjCContainerDecl { /// Referenced protocols - ObjCList ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; bool isForwardProtoDecl; // declared with @protocol. @@ -680,19 +707,26 @@ public: /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - const ObjCList &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } - typedef ObjCList::iterator protocol_iterator; + 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 protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); @@ -772,31 +806,45 @@ public: /// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; /// class ObjCForwardProtocolDecl : public Decl { - ObjCList ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, unsigned nElts, - ASTContext &C); + const SourceLocation *Locs, ASTContext &C); virtual ~ObjCForwardProtocolDecl() {} public: static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCProtocolDecl *const *Elts = 0, - unsigned Num = 0); + 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); + } /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - typedef ObjCList::iterator protocol_iterator; + 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, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } static bool classof(const Decl *D) { return D->getKind() == ObjCForwardProtocol; @@ -826,7 +874,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl { ObjCInterfaceDecl *ClassInterface; /// referenced protocols in this category. - ObjCList ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; /// Next category belonging to this class. /// FIXME: this should not be a singly-linked list. Move storage elsewhere. @@ -853,18 +901,25 @@ public: /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } - const ObjCList &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } - typedef ObjCList::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } unsigned protocol_size() const { return ReferencedProtocols.size(); } + 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(); + } ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } void setNextClassCategory(ObjCCategoryDecl *Cat) { diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 7209e0a843..4b9ff7be0d 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -2110,6 +2110,7 @@ public: SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { return DeclPtrTy(); @@ -2131,6 +2132,7 @@ public: SourceLocation ProtocolLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { return DeclPtrTy(); @@ -2144,6 +2146,7 @@ public: SourceLocation CategoryLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc) { return DeclPtrTy(); } @@ -2771,6 +2774,7 @@ public: SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); }; diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 2506f27e6f..047c349217 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -37,6 +37,21 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { memcpy(List, InList, sizeof(void*)*Elts); } +void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, + const SourceLocation *Locs, ASTContext &Ctx) { + if (Elts == 0) + return; + + Locations = new (Ctx) SourceLocation[Elts]; + memcpy(Locations, Locs, sizeof(SourceLocation) * Elts); + set(InList, Elts, Ctx); +} + +void ObjCProtocolList::Destroy(ASTContext &Ctx) { + Ctx.Deallocate(Locations); + Locations = 0; + ObjCList::Destroy(Ctx); +} //===----------------------------------------------------------------------===// // ObjCInterfaceDecl @@ -141,16 +156,18 @@ ObjCContainerDecl::FindPropertyVisibleInPrimaryClass( void ObjCInterfaceDecl::mergeClassExtensionProtocolList( ObjCProtocolDecl *const* ExtList, unsigned ExtNum, + const SourceLocation *Locs, ASTContext &C) { if (ReferencedProtocols.empty()) { - ReferencedProtocols.set(ExtList, ExtNum, C); + ReferencedProtocols.set(ExtList, ExtNum, Locs, C); return; } // Check for duplicate protocol in class's protocol list. // This is (O)2. But it is extremely rare and number of protocols in // class or its extension are very few. llvm::SmallVector ProtocolRefs; + llvm::SmallVector ProtocolLocs; for (unsigned i = 0; i < ExtNum; i++) { bool protocolExists = false; ObjCProtocolDecl *ProtoInExtension = ExtList[i]; @@ -164,18 +181,23 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList( } // Do we want to warn on a protocol in extension class which // already exist in the class? Probably not. - if (!protocolExists) + if (!protocolExists) { ProtocolRefs.push_back(ProtoInExtension); + ProtocolLocs.push_back(Locs[i]); + } } if (ProtocolRefs.empty()) return; // Merge ProtocolRefs into class's protocol list; + protocol_loc_iterator pl = protocol_loc_begin(); for (protocol_iterator p = protocol_begin(), e = protocol_end(); - p != e; p++) + p != e; ++p, ++pl) { ProtocolRefs.push_back(*p); + ProtocolLocs.push_back(*pl); + } ReferencedProtocols.Destroy(C); unsigned NumProtoRefs = ProtocolRefs.size(); - setProtocolList((ObjCProtocolDecl**)&ProtocolRefs[0], NumProtoRefs, C); + setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C); } ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, @@ -627,9 +649,9 @@ SourceRange ObjCClassDecl::getSourceRange() const { ObjCForwardProtocolDecl:: ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, unsigned nElts, - ASTContext &C) + const SourceLocation *Locs, ASTContext &C) : Decl(ObjCForwardProtocol, DC, L) { - ReferencedProtocols.set(Elts, nElts, C); + ReferencedProtocols.set(Elts, nElts, Locs, C); } @@ -637,8 +659,9 @@ ObjCForwardProtocolDecl * ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, - unsigned NumElts) { - return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C); + unsigned NumElts, + const SourceLocation *Locs) { + return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C); } void ObjCForwardProtocolDecl::Destroy(ASTContext &C) { diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 69343ed48c..138ad8226f 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -223,7 +223,12 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { Protocols.reserve(NumProtocols); for (unsigned I = 0; I != NumProtocols; ++I) Protocols.push_back(cast(Reader.GetDecl(Record[Idx++]))); - ID->setProtocolList(Protocols.data(), NumProtocols, *Reader.getContext()); + llvm::SmallVector ProtoLocs; + ProtoLocs.reserve(NumProtocols); + for (unsigned I = 0; I != NumProtocols; ++I) + ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(), + *Reader.getContext()); unsigned NumIvars = Record[Idx++]; llvm::SmallVector IVars; IVars.reserve(NumIvars); @@ -253,7 +258,12 @@ void PCHDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { ProtoRefs.reserve(NumProtoRefs); for (unsigned I = 0; I != NumProtoRefs; ++I) ProtoRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); - PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, *Reader.getContext()); + llvm::SmallVector ProtoLocs; + ProtoLocs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), + *Reader.getContext()); } void PCHDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) { @@ -282,7 +292,12 @@ void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) { ProtoRefs.reserve(NumProtoRefs); for (unsigned I = 0; I != NumProtoRefs; ++I) ProtoRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); - FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, *Reader.getContext()); + llvm::SmallVector ProtoLocs; + ProtoLocs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), + *Reader.getContext()); } void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { @@ -293,7 +308,12 @@ void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { ProtoRefs.reserve(NumProtoRefs); for (unsigned I = 0; I != NumProtoRefs; ++I) ProtoRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); - CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, *Reader.getContext()); + llvm::SmallVector ProtoLocs; + ProtoLocs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), + *Reader.getContext()); CD->setNextClassCategory(cast_or_null(Reader.GetDecl(Record[Idx++]))); CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); } diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 2dbcc27f95..6f4cd8f361 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -223,6 +223,10 @@ void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { PEnd = D->protocol_end(); P != PEnd; ++P) Writer.AddDeclRef(*P, Record); + for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(), + PLEnd = D->protocol_loc_end(); + PL != PLEnd; ++PL) + Writer.AddSourceLocation(*PL, Record); Record.push_back(D->ivar_size()); for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(), IEnd = D->ivar_end(); I != IEnd; ++I) @@ -251,6 +255,10 @@ void PCHDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { 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 = pch::DECL_OBJC_PROTOCOL; } @@ -272,9 +280,13 @@ void PCHDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) { void PCHDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { VisitDecl(D); Record.push_back(D->protocol_size()); - for (ObjCProtocolDecl::protocol_iterator + 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 = pch::DECL_OBJC_FORWARD_PROTOCOL; } @@ -282,9 +294,13 @@ void PCHDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { VisitObjCContainerDecl(D); Writer.AddDeclRef(D->getClassInterface(), Record); Record.push_back(D->protocol_size()); - for (ObjCProtocolDecl::protocol_iterator + for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) Writer.AddDeclRef(*I, Record); + for (ObjCCategoryDecl::protocol_loc_iterator + PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end(); + PL != PLEnd; ++PL) + Writer.AddSourceLocation(*PL, Record); Writer.AddDeclRef(D->getNextClassCategory(), Record); Writer.AddSourceLocation(D->getLocEnd(), Record); Code = pch::DECL_OBJC_CATEGORY; diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp index 95afb908df..a91dd8d55e 100644 --- a/lib/Frontend/PrintParserCallbacks.cpp +++ b/lib/Frontend/PrintParserCallbacks.cpp @@ -65,6 +65,7 @@ namespace { SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtocols, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { Out << __FUNCTION__ << "\n"; @@ -72,7 +73,8 @@ namespace { ClassName, ClassLoc, SuperName, SuperLoc, ProtoRefs, NumProtocols, - EndProtoLoc, AttrList); + ProtoLocs, EndProtoLoc, + AttrList); } /// ActOnForwardClassDeclaration - diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp index 8b207fab43..5f48897235 100644 --- a/lib/Parse/MinimalAction.cpp +++ b/lib/Parse/MinimalAction.cpp @@ -204,6 +204,7 @@ MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc, SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtocols, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { // Allocate and add the 'TypeNameInfo' "decl". diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 5e23635353..ae85aa3a8a 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -186,6 +186,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( categoryId, categoryLoc, ProtocolRefs.data(), ProtocolRefs.size(), + ProtocolLocs.data(), EndProtoLoc); ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword); @@ -224,6 +225,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc, superClassId, superClassLoc, ProtocolRefs.data(), ProtocolRefs.size(), + ProtocolLocs.data(), EndProtoLoc, attrList); if (Tok.is(tok::l_brace)) @@ -1127,6 +1129,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(), + ProtocolLocs.data(), EndProtoLoc, attrList); ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); return ProtoType; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 00a85f8851..c14ce293ac 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3312,6 +3312,7 @@ public: SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); @@ -3329,6 +3330,7 @@ public: SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, const DeclPtrTy *ProtoRefNames, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); @@ -3339,6 +3341,7 @@ public: SourceLocation CategoryLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc); virtual DeclPtrTy ActOnStartClassImplementation( diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index f2fc1f4f56..cfea87504d 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -81,6 +81,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { assert(ClassName && "Missing class identifier"); @@ -201,7 +202,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, /// Check then save referenced protocols. if (NumProtoRefs) { IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs, - Context); + ProtoLocs, Context); IDecl->setLocEnd(EndProtoLoc); } @@ -279,6 +280,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, SourceLocation ProtocolLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { // FIXME: Deal with AttrList. @@ -312,7 +314,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, ProcessDeclAttributeList(TUScope, PDecl, AttrList); if (NumProtoRefs) { /// Check then save referenced protocols. - PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,Context); + PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs, + ProtoLocs, Context); PDecl->setLocEnd(EndProtoLoc); } @@ -559,6 +562,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, unsigned NumElts, AttributeList *attrList) { llvm::SmallVector Protocols; + llvm::SmallVector ProtoLocs; for (unsigned i = 0; i != NumElts; ++i) { IdentifierInfo *Ident = IdentList[i].first; @@ -571,11 +575,13 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, if (attrList) ProcessDeclAttributeList(TUScope, PDecl, attrList); Protocols.push_back(PDecl); + ProtoLocs.push_back(IdentList[i].second); } ObjCForwardProtocolDecl *PDecl = ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc, - &Protocols[0], Protocols.size()); + Protocols.data(), Protocols.size(), + ProtoLocs.data()); CurContext->addDecl(PDecl); CheckObjCDeclScope(PDecl); return DeclPtrTy::make(PDecl); @@ -588,6 +594,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, SourceLocation CategoryLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc) { ObjCCategoryDecl *CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName); @@ -623,12 +630,13 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, if (NumProtoRefs) { CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs, - Context); + ProtoLocs, Context); CDecl->setLocEnd(EndProtoLoc); // Protocols in the class extension belong to the class. if (!CDecl->getIdentifier()) IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs, - NumProtoRefs,Context); + NumProtoRefs, ProtoLocs, + Context); } CheckObjCDeclScope(CDecl);