[cfe-commits] r111679 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/DeclObjC.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/DeclObjC.cpp lib/CodeGen/CGObjCMac.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp lib/Serialization/ASTReaderDecl.cpp
Fariborz Jahanian
fjahanian at apple.com
Fri Aug 20 14:21:08 PDT 2010
Author: fjahanian
Date: Fri Aug 20 16:21:08 2010
New Revision: 111679
URL: http://llvm.org/viewvc/llvm-project?rev=111679&view=rev
Log:
objective-c ivar refactoring patch. Iterations
over ivars for a varienty of puposes is now
consolidated into two small routines; DeepCollectObjCIvars
and ShallowCollectObjCIvars.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Aug 20 16:21:08 2010
@@ -1009,13 +1009,12 @@
/// of class definition.
const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
- void CollectObjCIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<FieldDecl*> &Fields);
-
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
- void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+
+ void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri Aug 20 16:21:08 2010
@@ -464,6 +464,10 @@
/// List of categories defined for this class.
/// FIXME: Why is this a linked list??
ObjCCategoryDecl *CategoryList;
+
+ /// IvarList - List of all ivars defined by this class; including class
+ /// extensions and implementation. This list is built lazily.
+ ObjCIvarDecl *IvarList;
bool ForwardDecl:1; // declared with @class.
bool InternalInterface:1; // true - no @interface for @implementation
@@ -518,7 +522,10 @@
return std::distance(ivar_begin(), ivar_end());
}
bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
+
+ ObjCIvarDecl *all_declared_ivar_begin();
+ void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
+
/// setProtocolList - Set the list of protocols that this interface
/// implements.
void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
@@ -640,7 +647,7 @@
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
: FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
- DeclAccess(ac), Synthesized(synthesized) {}
+ NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
@@ -654,6 +661,9 @@
/// interface the ivar is conceptually a part of in the case of synthesized
/// ivars.
const ObjCInterfaceDecl *getContainingInterface() const;
+
+ ObjCIvarDecl *getNextIvar() { return NextIvar; }
+ void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
@@ -671,6 +681,10 @@
static bool classof(const ObjCIvarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCIvar; }
private:
+ /// NextIvar - Next Ivar in the list of ivars declared in class; class's
+ /// extensions and class's implementation
+ ObjCIvarDecl *NextIvar;
+
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
unsigned Synthesized : 1;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 20 16:21:08 2010
@@ -1754,7 +1754,7 @@
/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
/// initialization.
- void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+ void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Aug 20 16:21:08 2010
@@ -829,60 +829,37 @@
return ABIAlign;
}
-static void CollectLocalObjCIvars(ASTContext *Ctx,
- const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<FieldDecl*> &Fields) {
- for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
- E = OI->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *IVDecl = *I;
- if (!IVDecl->isInvalidDecl())
- Fields.push_back(cast<FieldDecl>(IVDecl));
- }
-}
-
-void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<FieldDecl*> &Fields) {
- if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
- CollectObjCIvars(SuperClass, Fields);
- CollectLocalObjCIvars(this, OI, Fields);
-}
-
/// ShallowCollectObjCIvars -
/// Collect all ivars, including those synthesized, in the current class.
///
void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
- for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
- E = OI->ivar_end(); I != E; ++I) {
- Ivars.push_back(*I);
- }
-
- CollectNonClassIvars(OI, Ivars);
+ // FIXME. This need be removed but there are two many places which
+ // assume const-ness of ObjCInterfaceDecl
+ ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
+ for (ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
+ Iv= Iv->getNextIvar())
+ Ivars.push_back(Iv);
}
-/// CollectNonClassIvars -
-/// This routine collects all other ivars which are not declared in the class.
-/// This includes synthesized ivars (via @synthesize) and those in
-// class's @implementation.
+/// DeepCollectObjCIvars -
+/// This routine first collects all declared, but not synthesized, ivars in
+/// super class and then collects all ivars, including those synthesized for
+/// current class. This routine is used for implementation of current class
+/// when all ivars, declared and synthesized are known.
///
-void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
+void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
+ bool leafClass,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
- // Find ivars declared in class extension.
- for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
- CDecl = CDecl->getNextClassExtension()) {
- for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
- E = CDecl->ivar_end(); I != E; ++I) {
- Ivars.push_back(*I);
- }
- }
-
- // Also add any ivar defined in this class's implementation. This
- // includes synthesized ivars.
- if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
- for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
- E = ImplDecl->ivar_end(); I != E; ++I)
+ if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
+ DeepCollectObjCIvars(SuperClass, false, Ivars);
+ if (!leafClass) {
+ for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
+ E = OI->ivar_end(); I != E; ++I)
Ivars.push_back(*I);
}
+ else
+ ShallowCollectObjCIvars(OI, Ivars);
}
/// CollectInheritedProtocols - Collect all protocols in current class and
@@ -3853,15 +3830,14 @@
const IdentifierInfo *II = OI->getIdentifier();
S += II->getName();
S += '=';
- llvm::SmallVector<FieldDecl*, 32> RecFields;
- CollectObjCIvars(OI, RecFields);
- for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
- if (RecFields[i]->isBitField())
- getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
- RecFields[i]);
+ llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+ DeepCollectObjCIvars(OI, true, Ivars);
+ for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
+ FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
+ if (Field->isBitField())
+ getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
else
- getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
- FD);
+ getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD);
}
S += '}';
return;
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Aug 20 16:21:08 2010
@@ -442,7 +442,8 @@
SourceLocation CLoc, bool FD, bool isInternal)
: ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
TypeForDecl(0), SuperClass(0),
- CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
+ CategoryList(0), IvarList(0),
+ ForwardDecl(FD), InternalInterface(isInternal),
ClassLoc(CLoc) {
}
@@ -455,6 +456,49 @@
getASTContext().setObjCImplementation(this, ImplD);
}
+/// all_declared_ivar_begin - return first ivar declared in this class,
+/// its extensions and its implementation. Lazily build the list on first
+/// access.
+ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
+ if (IvarList)
+ return IvarList;
+
+ ObjCIvarDecl *curIvar = 0;
+ if (!ivar_empty()) {
+ ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
+ IvarList = (*I); ++I;
+ for (curIvar = IvarList; I != E; curIvar = *I, ++I)
+ curIvar->setNextIvar(*I);
+ }
+
+ for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
+ CDecl = CDecl->getNextClassExtension()) {
+ if (!CDecl->ivar_empty()) {
+ ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+ E = CDecl->ivar_end();
+ if (!IvarList) {
+ IvarList = (*I); ++I;
+ curIvar = IvarList;
+ }
+ for ( ;I != E; curIvar = *I, ++I)
+ curIvar->setNextIvar(*I);
+ }
+ }
+
+ if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
+ if (!ImplDecl->ivar_empty()) {
+ ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+ E = ImplDecl->ivar_end();
+ if (!IvarList) {
+ IvarList = (*I); ++I;
+ curIvar = IvarList;
+ }
+ for ( ;I != E; curIvar = *I, ++I)
+ curIvar->setNextIvar(*I);
+ }
+ }
+ return IvarList;
+}
/// FindCategoryDeclaration - Finds category declaration in the list of
/// categories for this class and returns it. Name of the category is passed
@@ -556,6 +600,16 @@
assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
isa<ObjCCategoryDecl>(DC)) &&
"Invalid ivar decl context!");
+ // Once a new ivar is created in any of class/class-extension/implementation
+ // decl contexts, the previously built IvarList must be rebuilt.
+ ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
+ if (!ID) {
+ if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
+ ID = IM->getClassInterface();
+ else
+ ID = (cast<ObjCCategoryDecl>(DC))->getClassInterface();
+ }
+ ID->setIvarList(0);
}
return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized);
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Aug 20 16:21:08 2010
@@ -3871,13 +3871,11 @@
if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
return llvm::Constant::getNullValue(PtrTy);
- llvm::SmallVector<FieldDecl*, 32> RecFields;
+ llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
const ObjCInterfaceDecl *OI = OMD->getClassInterface();
- CGM.getContext().CollectObjCIvars(OI, RecFields);
+ CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
- // Add this implementations synthesized ivars.
- llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
- CGM.getContext().CollectNonClassIvars(OI, Ivars);
+ llvm::SmallVector<FieldDecl*, 32> RecFields;
for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
RecFields.push_back(cast<FieldDecl>(Ivars[k]));
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Aug 20 16:21:08 2010
@@ -6921,7 +6921,7 @@
void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
if (!getLangOptions().CPlusPlus)
return;
- if (const ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
+ if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
llvm::SmallVector<ObjCIvarDecl*, 8> ivars;
CollectIvarsToConstructOrDestruct(OID, ivars);
if (ivars.empty())
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Aug 20 16:21:08 2010
@@ -1395,6 +1395,7 @@
DefaultSynthesizeProperties(S, IC, IDecl);
ImplMethodsVsClassMethods(S, IC, IDecl);
AtomicPropertySetterGetterRules(IC, IDecl);
+
if (LangOpts.ObjCNonFragileABI2)
while (IDecl->getSuperClass()) {
DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
@@ -1651,11 +1652,11 @@
}
// Collect the instance variables
- llvm::SmallVector<FieldDecl*, 32> RecFields;
- Context.CollectObjCIvars(Class, RecFields);
+ llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+ Context.DeepCollectObjCIvars(Class, true, Ivars);
// For each ivar, create a fresh ObjCAtDefsFieldDecl.
- for (unsigned i = 0; i < RecFields.size(); i++) {
- FieldDecl* ID = RecFields[i];
+ for (unsigned i = 0; i < Ivars.size(); i++) {
+ FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>());
Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
ID->getIdentifier(), ID->getType(),
@@ -1770,38 +1771,13 @@
/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
/// initialization.
-void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
- for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
- E = OI->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Iv = (*I);
+ for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv;
+ Iv= Iv->getNextIvar()) {
QualType QT = Context.getBaseElementType(Iv->getType());
if (QT->isRecordType())
- Ivars.push_back(*I);
- }
-
- // Find ivars to construct/destruct in class extension.
- for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
- CDecl = CDecl->getNextClassExtension()) {
- for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
- E = CDecl->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Iv = (*I);
- QualType QT = Context.getBaseElementType(Iv->getType());
- if (QT->isRecordType())
- Ivars.push_back(*I);
- }
- }
-
- // Also add any ivar defined in this class's implementation. This
- // includes synthesized ivars.
- if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
- for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
- E = ImplDecl->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Iv = (*I);
- QualType QT = Context.getBaseElementType(Iv->getType());
- if (QT->isRecordType())
- Ivars.push_back(*I);
- }
+ Ivars.push_back(Iv);
}
}
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=111679&r1=111678&r2=111679&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Aug 20 16:21:08 2010
@@ -392,6 +392,8 @@
IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
ID->setCategoryList(
cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+ // We will rebuild this list lazily.
+ ID->setIvarList(0);
ID->setForwardDecl(Record[Idx++]);
ID->setImplicitInterfaceDecl(Record[Idx++]);
ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -402,6 +404,8 @@
void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
VisitFieldDecl(IVD);
IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
+ // This field will be built lazily.
+ IVD->setNextIvar(0);
bool synth = Record[Idx++];
IVD->setSynthesize(synth);
}
More information about the cfe-commits
mailing list