Add a const overload for ObjCInterfaceDecl::all_declared_ivar_begin.

This was previously not-const only because it has to lazily construct a chain
of ivars the first time it is called (and after the chain is invalidated).
In practice, all the clients were just const_casting their const Decls;
all those now-unnecessary const_casts have been removed.

llvm-svn: 135741
This commit is contained in:
Jordy Rose 2011-07-22 02:08:32 +00:00
parent dff8de77a6
commit a91768e569
10 changed files with 50 additions and 72 deletions

View File

@ -1163,13 +1163,9 @@ public:
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
MangleContext *createMangleContext();
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
SmallVectorImpl<ObjCIvarDecl*> &Ivars)
const;
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
SmallVectorImpl<ObjCIvarDecl*> &Ivars) const;
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
void CollectInheritedProtocols(const Decl *CDecl,

View File

@ -576,7 +576,7 @@ public:
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
unsigned ivar_size() const {
@ -585,7 +585,12 @@ public:
bool ivar_empty() const { return ivar_begin() == ivar_end(); }
ObjCIvarDecl *all_declared_ivar_begin();
ObjCIvarDecl *all_declared_ivar_begin();
const ObjCIvarDecl *all_declared_ivar_begin() const {
// Even though this modifies IvarList, it's conceptually const:
// the ivar chain is essentially a cached property of ObjCInterfaceDecl.
return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
}
void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
/// setProtocolList - Set the list of protocols that this interface
@ -754,6 +759,7 @@ public:
const ObjCInterfaceDecl *getContainingInterface() const;
ObjCIvarDecl *getNextIvar() { return NextIvar; }
const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
void setAccessControl(AccessControl ac) { DeclAccess = ac; }

View File

@ -1063,19 +1063,6 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
return ABIAlign;
}
/// ShallowCollectObjCIvars -
/// Collect all ivars, including those synthesized, in the current class.
///
void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) const {
// 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);
}
/// DeepCollectObjCIvars -
/// This routine first collects all declared, but not synthesized, ivars in
/// super class and then collects all ivars, including those synthesized for
@ -1084,7 +1071,7 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
///
void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
bool leafClass,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) const {
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const {
if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
DeepCollectObjCIvars(SuperClass, false, Ivars);
if (!leafClass) {
@ -1094,7 +1081,7 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
}
else {
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
for (ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
Iv= Iv->getNextIvar())
Ivars.push_back(Iv);
}
@ -4487,10 +4474,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
const IdentifierInfo *II = OI->getIdentifier();
S += II->getName();
S += '=';
llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
const FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
if (Field->isBitField())
getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
else

View File

@ -1242,10 +1242,9 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
}
InitializeLayout(D);
ObjCInterfaceDecl *OI = const_cast<ObjCInterfaceDecl*>(D);
// Layout each ivar sequentially.
for (ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar())
for (const ObjCIvarDecl *IVD = D->all_declared_ivar_begin(); IVD;
IVD = IVD->getNextIvar())
LayoutField(IVD);
// Finally, round the size of the total struct up to the alignment of the

View File

@ -716,9 +716,8 @@ static void emitCXXDestructMethod(CodeGenFunction &CGF,
llvm::Value *self = CGF.LoadObjCSelf();
ObjCInterfaceDecl *iface
= const_cast<ObjCInterfaceDecl*>(impl->getClassInterface());
for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
const ObjCInterfaceDecl *iface = impl->getClassInterface();
for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
ivar; ivar = ivar->getNextIvar()) {
QualType type = ivar->getType();

View File

@ -1859,12 +1859,8 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
instanceSize = 0 - (instanceSize - superInstanceSize);
}
// Collect declared and synthesized ivars.
llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
CGM.getContext().ShallowCollectObjCIvars(ClassDecl, OIvars);
for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
ObjCIvarDecl *IVD = OIvars[i];
for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD;
IVD = IVD->getNextIvar()) {
// Store the name
IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
// Get the type encoding for this ivar
@ -1968,12 +1964,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
llvm::ConstantInt::get(IndexTy, 1), 0,
llvm::ConstantInt::get(IndexTy, 2) };
for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
ObjCIvarDecl *IVD = OIvars[i];
unsigned ivarIndex = 0;
for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD;
IVD = IVD->getNextIvar()) {
const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
+ IVD->getNameAsString();
offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i);
offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
// Get the correct ivar field
llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
IvarList, offsetPointerIndexes);
@ -1990,6 +1986,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
}
++ivarIndex;
}
//Generate metaclass for class methods
llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
@ -2432,10 +2429,9 @@ LValue CGObjCGNU::EmitObjCValueForIvar(CodeGenFunction &CGF,
static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
const ObjCInterfaceDecl *OID,
const ObjCIvarDecl *OIVD) {
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
Context.ShallowCollectObjCIvars(OID, Ivars);
for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
if (OIVD == Ivars[k])
for (const ObjCIvarDecl *next = OID->all_declared_ivar_begin(); next;
next = next->getNextIvar()) {
if (OIVD == next)
return OID;
}

View File

@ -775,7 +775,7 @@ protected:
void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
const llvm::StructLayout *Layout,
const RecordDecl *RD,
const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
const SmallVectorImpl<const FieldDecl*> &RecFields,
unsigned int BytePos, bool ForStrongLayout,
bool &HasUnion);
@ -2407,10 +2407,9 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
if (ForClass)
return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
ObjCInterfaceDecl *OID =
const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
const ObjCInterfaceDecl *OID = ID->getClassInterface();
for (ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar()) {
// Ignore unnamed bit-fields.
if (!IVD->getDeclName())
@ -3574,7 +3573,7 @@ void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
bool &HasUnion) {
const RecordDecl *RD = RT->getDecl();
// FIXME - Use iterator.
llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
SmallVector<const FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
const llvm::StructLayout *RecLayout =
CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
@ -3586,15 +3585,15 @@ void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
const llvm::StructLayout *Layout,
const RecordDecl *RD,
const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
const SmallVectorImpl<const FieldDecl*> &RecFields,
unsigned int BytePos, bool ForStrongLayout,
bool &HasUnion) {
bool IsUnion = (RD && RD->isUnion());
uint64_t MaxUnionIvarSize = 0;
uint64_t MaxSkippedUnionIvarSize = 0;
FieldDecl *MaxField = 0;
FieldDecl *MaxSkippedField = 0;
FieldDecl *LastFieldBitfieldOrUnnamed = 0;
const FieldDecl *MaxField = 0;
const FieldDecl *MaxSkippedField = 0;
const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
uint64_t MaxFieldOffset = 0;
uint64_t MaxSkippedFieldOffset = 0;
uint64_t LastBitfieldOrUnnamedOffset = 0;
@ -3605,13 +3604,13 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
if (!RD && CGM.getLangOptions().ObjCAutoRefCount) {
FieldDecl *FirstField = RecFields[0];
const FieldDecl *FirstField = RecFields[0];
FirstFieldDelta =
ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
}
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
FieldDecl *Field = RecFields[i];
const FieldDecl *Field = RecFields[i];
uint64_t FieldOffset;
if (RD) {
// Note that 'i' here is actually the field index inside RD of Field,
@ -3903,20 +3902,19 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
!CGM.getLangOptions().ObjCAutoRefCount)
return llvm::Constant::getNullValue(PtrTy);
ObjCInterfaceDecl *OI =
const_cast<ObjCInterfaceDecl*>(OMD->getClassInterface());
llvm::SmallVector<FieldDecl*, 32> RecFields;
const ObjCInterfaceDecl *OI = OMD->getClassInterface();
SmallVector<const FieldDecl*, 32> RecFields;
if (CGM.getLangOptions().ObjCAutoRefCount) {
for (ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar())
RecFields.push_back(cast<FieldDecl>(IVD));
}
else {
llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
SmallVector<const ObjCIvarDecl*, 32> Ivars;
CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
RecFields.push_back(cast<FieldDecl>(Ivars[k]));
// FIXME: This is not ideal; we shouldn't have to do this copy.
RecFields.append(Ivars.begin(), Ivars.end());
}
if (RecFields.empty())
@ -5258,13 +5256,12 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
std::vector<llvm::Constant*> Ivars, Ivar(5);
ObjCInterfaceDecl *OID =
const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
const ObjCInterfaceDecl *OID = ID->getClassInterface();
assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
// FIXME. Consolidate this with similar code in GenerateClass.
for (ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar()) {
// Ignore unnamed bit-fields.
if (!IVD->getDeclName())

View File

@ -52,9 +52,8 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
// implemented. This should be fixed to get the information from the layout
// directly.
unsigned Index = 0;
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl*>(Container);
for (ObjCIvarDecl *IVD = IDecl->all_declared_ivar_begin();
for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar()) {
if (Ivar == IVD)
break;

View File

@ -2001,9 +2001,8 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
}
static bool needsDestructMethod(ObjCImplementationDecl *impl) {
ObjCInterfaceDecl *iface
= const_cast<ObjCInterfaceDecl*>(impl->getClassInterface());
for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
const ObjCInterfaceDecl *iface = impl->getClassInterface();
for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
ivar; ivar = ivar->getNextIvar())
if (ivar->getType().isDestructedType())
return true;

View File

@ -2533,11 +2533,11 @@ void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
}
// Collect the instance variables
llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
SmallVector<const ObjCIvarDecl*, 32> Ivars;
Context.DeepCollectObjCIvars(Class, true, Ivars);
// For each ivar, create a fresh ObjCAtDefsFieldDecl.
for (unsigned i = 0; i < Ivars.size(); i++) {
FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
const FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record,
/*FIXME: StartL=*/ID->getLocation(),