[cfe-commits] r147410 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclBase.cpp lib/AST/DeclObjC.cpp lib/CodeGen/CGObjCGNU.cpp lib/CodeGen/CGObjCMac.cpp lib/Sema/SemaLookup.cpp lib/Serialization/ASTCommon.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp
Douglas Gregor
dgregor at apple.com
Sun Jan 1 11:51:50 PST 2012
Author: dgregor
Date: Sun Jan 1 13:51:50 2012
New Revision: 147410
URL: http://llvm.org/viewvc/llvm-project?rev=147410&view=rev
Log:
Introduce the core infrastructure needed to model redeclaration chains
for Objective-C protocols, including:
- Using the first declaration as the canonical declaration
- Using the definition as the primary DeclContext
- Making sure that all declarations have a pointer to the definition
data, and that we know which declaration is the definition
- Serialization support for redeclaration chains and for adding
definitions to already-serialized declarations.
However, note that we're not taking advantage of much of this code
yet, because we're still re-using ObjCProtocolDecls.
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Serialization/ASTCommon.h
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sun Jan 1 13:51:50 2012
@@ -1063,10 +1063,14 @@
///
/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
///
-class ObjCProtocolDecl : public ObjCContainerDecl {
+class ObjCProtocolDecl : public ObjCContainerDecl,
+ public Redeclarable<ObjCProtocolDecl> {
virtual void anchor();
struct DefinitionData {
+ // \brief The declaration that defines this protocol.
+ ObjCProtocolDecl *Definition;
+
/// Referenced protocols
ObjCProtocolList ReferencedProtocols;
};
@@ -1093,7 +1097,12 @@
}
void allocateDefinitionData();
-
+
+ typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
+ virtual ObjCProtocolDecl *getNextRedeclaration() {
+ return RedeclLink.getNext();
+ }
+
public:
static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
@@ -1163,12 +1172,12 @@
/// \brief Retrieve the definition of this protocol, if any.
ObjCProtocolDecl *getDefinition() {
- return hasDefinition()? this : 0;
+ return Data? Data->Definition : 0;
}
/// \brief Retrieve the definition of this protocol, if any.
const ObjCProtocolDecl *getDefinition() const {
- return hasDefinition()? this : 0;
+ return Data? Data->Definition : 0;
}
/// \brief Determine whether this particular declaration is also the
@@ -1192,12 +1201,20 @@
SourceLocation getLocEnd() const { return EndLoc; }
void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ redecl_iterator redecls_begin() const {
+ return redeclarable_base::redecls_begin();
+ }
+ redecl_iterator redecls_end() const {
+ return redeclarable_base::redecls_end();
+ }
+
/// Retrieves the canonical declaration of this Objective-C protocol.
ObjCProtocolDecl *getCanonicalDecl() {
- return this;
+ return getFirstDeclaration();
}
const ObjCProtocolDecl *getCanonicalDecl() const {
- return this;
+ return getFirstDeclaration();
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Sun Jan 1 13:51:50 2012
@@ -784,8 +784,10 @@
return this;
case Decl::ObjCProtocol:
- // FIXME: Update when protocols properly model forward declarations.
- // For now, it's fine to fall through
+ if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(this)->getDefinition())
+ return Def;
+
+ return this;
case Decl::ObjCCategory:
return this;
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Sun Jan 1 13:51:50 2012
@@ -1005,11 +1005,17 @@
void ObjCProtocolDecl::allocateDefinitionData() {
assert(!Data && "Protocol already has a definition!");
- Data = new (getASTContext()) DefinitionData;
+ Data = new (getASTContext()) DefinitionData;
+ Data->Definition = this;
}
void ObjCProtocolDecl::startDefinition() {
allocateDefinitionData();
+
+ // Update all of the declarations with a pointer to the definition.
+ for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
+ RD != RDEnd; ++RD)
+ RD->Data = this->Data;
}
void ObjCProtocolDecl::completedForwardDecl() {
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Sun Jan 1 13:51:50 2012
@@ -1529,6 +1529,11 @@
void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
ASTContext &Context = CGM.getContext();
std::string ProtocolName = PD->getNameAsString();
+
+ // Use the protocol definition, if there is one.
+ if (const ObjCProtocolDecl *Def = PD->getDefinition())
+ PD = Def;
+
SmallVector<std::string, 16> Protocols;
for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
E = PD->protocol_end(); PI != E; ++PI)
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sun Jan 1 13:51:50 2012
@@ -1787,6 +1787,10 @@
if (Entry && Entry->hasInitializer())
return Entry;
+ // Use the protocol definition, if there is one.
+ if (const ObjCProtocolDecl *Def = PD->getDefinition())
+ PD = Def;
+
// FIXME: I don't understand why gcc generates this, or where it is
// resolved. Investigate. Its also wasteful to look this up over and over.
LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
@@ -5413,6 +5417,10 @@
if (Entry && Entry->hasInitializer())
return Entry;
+ // Use the protocol definition, if there is one.
+ if (const ObjCProtocolDecl *Def = PD->getDefinition())
+ PD = Def;
+
// Construct method lists.
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sun Jan 1 13:51:50 2012
@@ -1067,6 +1067,8 @@
return TD->getPreviousDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getPreviousDeclaration();
+ if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+ return PD->getPreviousDeclaration();
return 0;
}
Modified: cfe/trunk/lib/Serialization/ASTCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.h (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.h Sun Jan 1 13:51:50 2012
@@ -27,7 +27,8 @@
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
- UPD_OBJC_SET_CLASS_DEFINITIONDATA
+ UPD_OBJC_SET_CLASS_DEFINITIONDATA,
+ UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA
};
TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sun Jan 1 13:51:50 2012
@@ -6121,9 +6121,10 @@
PendingChainedObjCCategories.clear();
}
- // If we deserialized any C++ or Objective-C class definitions, make sure
- // that all redeclarations point to the definitions. Note that this can only
- // happen now, after the redeclaration chains have been fully wired.
+ // If we deserialized any C++ or Objective-C class definitions or any
+ // Objective-C protocol definitions, make sure that all redeclarations point
+ // to the definitions. Note that this can only happen now, after the
+ // redeclaration chains have been fully wired.
for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
DEnd = PendingDefinitions.end();
D != DEnd; ++D) {
@@ -6136,11 +6137,20 @@
continue;
}
- ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(*D);
- for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
- REnd = ID->redecls_end();
+ if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
+ for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
+ REnd = ID->redecls_end();
+ R != REnd; ++R)
+ R->Data = ID->Data;
+
+ continue;
+ }
+
+ ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(*D);
+ for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
+ REnd = PD->redecls_end();
R != REnd; ++R)
- R->Data = ID->Data;
+ R->Data = PD->Data;
}
PendingDefinitions.clear();
}
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Jan 1 13:51:50 2012
@@ -760,6 +760,7 @@
}
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
+ VisitRedeclarable(PD);
VisitObjCContainerDecl(PD);
PD->InitiallyForwardDecl = Record[Idx++];
PD->isForwardProtoDecl = Record[Idx++];
@@ -782,8 +783,8 @@
PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
Reader.getContext());
- // FIXME: Note that we have deserialized a definition.
- // Reader.PendingDefinitions.insert(PD);
+ // Note that we have deserialized a definition.
+ Reader.PendingDefinitions.insert(PD);
} else if (Def && Def->Data) {
PD->Data = Def->Data;
}
@@ -1712,6 +1713,8 @@
TD->RedeclLink.setPointer(cast<TypedefNameDecl>(previous));
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
+ } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ PD->RedeclLink.setPointer(cast<ObjCProtocolDecl>(previous));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1737,6 +1740,10 @@
ID->RedeclLink
= Redeclarable<ObjCInterfaceDecl>::LatestDeclLink(
cast<ObjCInterfaceDecl>(Latest));
+ } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ PD->RedeclLink
+ = Redeclarable<ObjCProtocolDecl>::LatestDeclLink(
+ cast<ObjCProtocolDecl>(Latest));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->getCommonPtr()->Latest = cast<RedeclarableTemplateDecl>(Latest);
@@ -2201,6 +2208,8 @@
return TD->getPreviousDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getPreviousDeclaration();
+ if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+ return PD->getPreviousDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getPreviousDeclaration();
}
@@ -2217,6 +2226,8 @@
return TD->getMostRecentDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getMostRecentDeclaration();
+ if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+ return PD->getMostRecentDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getMostRecentDeclaration();
}
@@ -2454,6 +2465,15 @@
ID->Data = Def->Data;
break;
}
+
+ case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA: {
+ ObjCProtocolDecl *ID = cast<ObjCProtocolDecl>(D);
+ ObjCProtocolDecl *Def
+ = Reader.ReadDeclAs<ObjCProtocolDecl>(ModuleFile, Record, Idx);
+ if (Def->Data)
+ ID->Data = Def->Data;
+ break;
+ }
}
}
}
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Jan 1 13:51:50 2012
@@ -3483,6 +3483,7 @@
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
case UPD_OBJC_SET_CLASS_DEFINITIONDATA:
+ case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA:
URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
++Idx;
break;
@@ -4447,6 +4448,24 @@
}
}
}
+
+ if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ for (ObjCProtocolDecl::redecl_iterator I = PD->redecls_begin(),
+ E = PD->redecls_end();
+ I != E; ++I) {
+ if (*I == PD)
+ continue;
+
+ // We are interested when a PCH decl is modified.
+ if (I->isFromASTFile()) {
+ UpdateRecord &Record = DeclUpdates[*I];
+ Record.push_back(UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA);
+ assert((*I)->hasDefinition());
+ assert((*I)->getDefinition() == D);
+ Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
+ }
+ }
+ }
}
void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=147410&r1=147409&r2=147410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Sun Jan 1 13:51:50 2012
@@ -517,6 +517,7 @@
}
void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ VisitRedeclarable(D);
VisitObjCContainerDecl(D);
Record.push_back(D->isInitiallyForwardDecl());
Record.push_back(D->isForwardProtoDecl);
More information about the cfe-commits
mailing list