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/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 2506f27..047c349 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -37,6 +37,21 @@
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<ObjCProtocolDecl>::Destroy(Ctx);
+}
//===----------------------------------------------------------------------===//
// ObjCInterfaceDecl
@@ -141,16 +156,18 @@
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<ObjCProtocolDecl*, 8> ProtocolRefs;
+ llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
for (unsigned i = 0; i < ExtNum; i++) {
bool protocolExists = false;
ObjCProtocolDecl *ProtoInExtension = ExtList[i];
@@ -164,18 +181,23 @@
}
// 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 @@
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::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 69343ed..138ad82 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -223,7 +223,12 @@
Protocols.reserve(NumProtocols);
for (unsigned I = 0; I != NumProtocols; ++I)
Protocols.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setProtocolList(Protocols.data(), NumProtocols, *Reader.getContext());
+ llvm::SmallVector<SourceLocation, 16> 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<ObjCIvarDecl *, 16> IVars;
IVars.reserve(NumIvars);
@@ -253,7 +258,12 @@
ProtoRefs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, *Reader.getContext());
+ llvm::SmallVector<SourceLocation, 16> 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 @@
ProtoRefs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, *Reader.getContext());
+ llvm::SmallVector<SourceLocation, 16> 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 @@
ProtoRefs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, *Reader.getContext());
+ llvm::SmallVector<SourceLocation, 16> 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<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 2dbcc27..6f4cd8f 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -223,6 +223,10 @@
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 @@
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::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 @@
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 95afb90..a91dd8d 100644
--- a/lib/Frontend/PrintParserCallbacks.cpp
+++ b/lib/Frontend/PrintParserCallbacks.cpp
@@ -65,6 +65,7 @@
SourceLocation SuperLoc,
const DeclPtrTy *ProtoRefs,
unsigned NumProtocols,
+ const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
AttributeList *AttrList) {
Out << __FUNCTION__ << "\n";
@@ -72,7 +73,8 @@
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 8b207fa..5f48897 100644
--- a/lib/Parse/MinimalAction.cpp
+++ b/lib/Parse/MinimalAction.cpp
@@ -204,6 +204,7 @@
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 5e23635..ae85aa3 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -186,6 +186,7 @@
categoryId, categoryLoc,
ProtocolRefs.data(),
ProtocolRefs.size(),
+ ProtocolLocs.data(),
EndProtoLoc);
ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
@@ -224,6 +225,7 @@
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 @@
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 00a85f8..c14ce29 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -3312,6 +3312,7 @@
SourceLocation SuperLoc,
const DeclPtrTy *ProtoRefs,
unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
AttributeList *AttrList);
@@ -3329,6 +3330,7 @@
SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
const DeclPtrTy *ProtoRefNames, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
AttributeList *AttrList);
@@ -3339,6 +3341,7 @@
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 f2fc1f4..cfea875 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -81,6 +81,7 @@
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 @@
/// Check then save referenced protocols.
if (NumProtoRefs) {
IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
- Context);
+ ProtoLocs, Context);
IDecl->setLocEnd(EndProtoLoc);
}
@@ -279,6 +280,7 @@
SourceLocation ProtocolLoc,
const DeclPtrTy *ProtoRefs,
unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
AttributeList *AttrList) {
// FIXME: Deal with AttrList.
@@ -312,7 +314,8 @@
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 @@
unsigned NumElts,
AttributeList *attrList) {
llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
+ llvm::SmallVector<SourceLocation, 8> ProtoLocs;
for (unsigned i = 0; i != NumElts; ++i) {
IdentifierInfo *Ident = IdentList[i].first;
@@ -571,11 +575,13 @@
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 @@
SourceLocation CategoryLoc,
const DeclPtrTy *ProtoRefs,
unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc) {
ObjCCategoryDecl *CDecl =
ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName);
@@ -623,12 +630,13 @@
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);