Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit db8264e

Browse files
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135741 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 527eec8 commit db8264e

10 files changed

+50
-72
lines changed

include/clang/AST/ASTContext.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -1163,13 +1163,9 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
11631163
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
11641164

11651165
MangleContext *createMangleContext();
1166-
1167-
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
1168-
SmallVectorImpl<ObjCIvarDecl*> &Ivars)
1169-
const;
11701166

11711167
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
1172-
SmallVectorImpl<ObjCIvarDecl*> &Ivars) const;
1168+
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
11731169

11741170
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
11751171
void CollectInheritedProtocols(const Decl *CDecl,

include/clang/AST/DeclObjC.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
576576

577577
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
578578

579-
ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
579+
ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
580580
ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
581581

582582
unsigned ivar_size() const {
@@ -585,7 +585,12 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
585585

586586
bool ivar_empty() const { return ivar_begin() == ivar_end(); }
587587

588-
ObjCIvarDecl *all_declared_ivar_begin();
588+
ObjCIvarDecl *all_declared_ivar_begin();
589+
const ObjCIvarDecl *all_declared_ivar_begin() const {
590+
// Even though this modifies IvarList, it's conceptually const:
591+
// the ivar chain is essentially a cached property of ObjCInterfaceDecl.
592+
return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
593+
}
589594
void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
590595

591596
/// setProtocolList - Set the list of protocols that this interface
@@ -754,6 +759,7 @@ class ObjCIvarDecl : public FieldDecl {
754759
const ObjCInterfaceDecl *getContainingInterface() const;
755760

756761
ObjCIvarDecl *getNextIvar() { return NextIvar; }
762+
const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
757763
void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
758764

759765
void setAccessControl(AccessControl ac) { DeclAccess = ac; }

lib/AST/ASTContext.cpp

+4-17
Original file line numberDiff line numberDiff line change
@@ -1063,19 +1063,6 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
10631063
return ABIAlign;
10641064
}
10651065

1066-
/// ShallowCollectObjCIvars -
1067-
/// Collect all ivars, including those synthesized, in the current class.
1068-
///
1069-
void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
1070-
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) const {
1071-
// FIXME. This need be removed but there are two many places which
1072-
// assume const-ness of ObjCInterfaceDecl
1073-
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
1074-
for (ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
1075-
Iv= Iv->getNextIvar())
1076-
Ivars.push_back(Iv);
1077-
}
1078-
10791066
/// DeepCollectObjCIvars -
10801067
/// This routine first collects all declared, but not synthesized, ivars in
10811068
/// super class and then collects all ivars, including those synthesized for
@@ -1084,7 +1071,7 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
10841071
///
10851072
void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
10861073
bool leafClass,
1087-
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) const {
1074+
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const {
10881075
if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
10891076
DeepCollectObjCIvars(SuperClass, false, Ivars);
10901077
if (!leafClass) {
@@ -1094,7 +1081,7 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
10941081
}
10951082
else {
10961083
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
1097-
for (ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
1084+
for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
10981085
Iv= Iv->getNextIvar())
10991086
Ivars.push_back(Iv);
11001087
}
@@ -4487,10 +4474,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
44874474
const IdentifierInfo *II = OI->getIdentifier();
44884475
S += II->getName();
44894476
S += '=';
4490-
llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
4477+
SmallVector<const ObjCIvarDecl*, 32> Ivars;
44914478
DeepCollectObjCIvars(OI, true, Ivars);
44924479
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
4493-
FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
4480+
const FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
44944481
if (Field->isBitField())
44954482
getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
44964483
else

lib/AST/RecordLayoutBuilder.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -1242,10 +1242,9 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
12421242
}
12431243

12441244
InitializeLayout(D);
1245-
ObjCInterfaceDecl *OI = const_cast<ObjCInterfaceDecl*>(D);
12461245
// Layout each ivar sequentially.
1247-
for (ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
1248-
IVD; IVD = IVD->getNextIvar())
1246+
for (const ObjCIvarDecl *IVD = D->all_declared_ivar_begin(); IVD;
1247+
IVD = IVD->getNextIvar())
12491248
LayoutField(IVD);
12501249

12511250
// Finally, round the size of the total struct up to the alignment of the

lib/CodeGen/CGObjC.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,8 @@ static void emitCXXDestructMethod(CodeGenFunction &CGF,
716716

717717
llvm::Value *self = CGF.LoadObjCSelf();
718718

719-
ObjCInterfaceDecl *iface
720-
= const_cast<ObjCInterfaceDecl*>(impl->getClassInterface());
721-
for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
719+
const ObjCInterfaceDecl *iface = impl->getClassInterface();
720+
for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
722721
ivar; ivar = ivar->getNextIvar()) {
723722
QualType type = ivar->getType();
724723

lib/CodeGen/CGObjCGNU.cpp

+10-14
Original file line numberDiff line numberDiff line change
@@ -1859,12 +1859,8 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
18591859
instanceSize = 0 - (instanceSize - superInstanceSize);
18601860
}
18611861

1862-
// Collect declared and synthesized ivars.
1863-
llvm::SmallVector<ObjCIvarDecl*, 16> OIvars;
1864-
CGM.getContext().ShallowCollectObjCIvars(ClassDecl, OIvars);
1865-
1866-
for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
1867-
ObjCIvarDecl *IVD = OIvars[i];
1862+
for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD;
1863+
IVD = IVD->getNextIvar()) {
18681864
// Store the name
18691865
IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
18701866
// Get the type encoding for this ivar
@@ -1968,12 +1964,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
19681964
llvm::ConstantInt::get(IndexTy, 1), 0,
19691965
llvm::ConstantInt::get(IndexTy, 2) };
19701966

1971-
1972-
for (unsigned i = 0, e = OIvars.size(); i != e; ++i) {
1973-
ObjCIvarDecl *IVD = OIvars[i];
1967+
unsigned ivarIndex = 0;
1968+
for (const ObjCIvarDecl *IVD = ClassDecl->all_declared_ivar_begin(); IVD;
1969+
IVD = IVD->getNextIvar()) {
19741970
const std::string Name = "__objc_ivar_offset_" + ClassName + '.'
19751971
+ IVD->getNameAsString();
1976-
offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i);
1972+
offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
19771973
// Get the correct ivar field
19781974
llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
19791975
IvarList, offsetPointerIndexes);
@@ -1990,6 +1986,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
19901986
offset = new llvm::GlobalVariable(TheModule, offsetValue->getType(),
19911987
false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
19921988
}
1989+
++ivarIndex;
19931990
}
19941991
//Generate metaclass for class methods
19951992
llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
@@ -2432,10 +2429,9 @@ LValue CGObjCGNU::EmitObjCValueForIvar(CodeGenFunction &CGF,
24322429
static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
24332430
const ObjCInterfaceDecl *OID,
24342431
const ObjCIvarDecl *OIVD) {
2435-
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
2436-
Context.ShallowCollectObjCIvars(OID, Ivars);
2437-
for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
2438-
if (OIVD == Ivars[k])
2432+
for (const ObjCIvarDecl *next = OID->all_declared_ivar_begin(); next;
2433+
next = next->getNextIvar()) {
2434+
if (OIVD == next)
24392435
return OID;
24402436
}
24412437

lib/CodeGen/CGObjCMac.cpp

+18-21
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
775775
void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
776776
const llvm::StructLayout *Layout,
777777
const RecordDecl *RD,
778-
const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
778+
const SmallVectorImpl<const FieldDecl*> &RecFields,
779779
unsigned int BytePos, bool ForStrongLayout,
780780
bool &HasUnion);
781781

@@ -2407,10 +2407,9 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
24072407
if (ForClass)
24082408
return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
24092409

2410-
ObjCInterfaceDecl *OID =
2411-
const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
2410+
const ObjCInterfaceDecl *OID = ID->getClassInterface();
24122411

2413-
for (ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
2412+
for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
24142413
IVD; IVD = IVD->getNextIvar()) {
24152414
// Ignore unnamed bit-fields.
24162415
if (!IVD->getDeclName())
@@ -3574,7 +3573,7 @@ void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
35743573
bool &HasUnion) {
35753574
const RecordDecl *RD = RT->getDecl();
35763575
// FIXME - Use iterator.
3577-
llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
3576+
SmallVector<const FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
35783577
llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
35793578
const llvm::StructLayout *RecLayout =
35803579
CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
@@ -3586,15 +3585,15 @@ void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
35863585
void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
35873586
const llvm::StructLayout *Layout,
35883587
const RecordDecl *RD,
3589-
const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
3588+
const SmallVectorImpl<const FieldDecl*> &RecFields,
35903589
unsigned int BytePos, bool ForStrongLayout,
35913590
bool &HasUnion) {
35923591
bool IsUnion = (RD && RD->isUnion());
35933592
uint64_t MaxUnionIvarSize = 0;
35943593
uint64_t MaxSkippedUnionIvarSize = 0;
3595-
FieldDecl *MaxField = 0;
3596-
FieldDecl *MaxSkippedField = 0;
3597-
FieldDecl *LastFieldBitfieldOrUnnamed = 0;
3594+
const FieldDecl *MaxField = 0;
3595+
const FieldDecl *MaxSkippedField = 0;
3596+
const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
35983597
uint64_t MaxFieldOffset = 0;
35993598
uint64_t MaxSkippedFieldOffset = 0;
36003599
uint64_t LastBitfieldOrUnnamedOffset = 0;
@@ -3605,13 +3604,13 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
36053604
unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
36063605
unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
36073606
if (!RD && CGM.getLangOptions().ObjCAutoRefCount) {
3608-
FieldDecl *FirstField = RecFields[0];
3607+
const FieldDecl *FirstField = RecFields[0];
36093608
FirstFieldDelta =
36103609
ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
36113610
}
36123611

36133612
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3614-
FieldDecl *Field = RecFields[i];
3613+
const FieldDecl *Field = RecFields[i];
36153614
uint64_t FieldOffset;
36163615
if (RD) {
36173616
// Note that 'i' here is actually the field index inside RD of Field,
@@ -3903,20 +3902,19 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
39033902
!CGM.getLangOptions().ObjCAutoRefCount)
39043903
return llvm::Constant::getNullValue(PtrTy);
39053904

3906-
ObjCInterfaceDecl *OI =
3907-
const_cast<ObjCInterfaceDecl*>(OMD->getClassInterface());
3908-
llvm::SmallVector<FieldDecl*, 32> RecFields;
3905+
const ObjCInterfaceDecl *OI = OMD->getClassInterface();
3906+
SmallVector<const FieldDecl*, 32> RecFields;
39093907
if (CGM.getLangOptions().ObjCAutoRefCount) {
3910-
for (ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
3908+
for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
39113909
IVD; IVD = IVD->getNextIvar())
39123910
RecFields.push_back(cast<FieldDecl>(IVD));
39133911
}
39143912
else {
3915-
llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
3913+
SmallVector<const ObjCIvarDecl*, 32> Ivars;
39163914
CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
39173915

3918-
for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
3919-
RecFields.push_back(cast<FieldDecl>(Ivars[k]));
3916+
// FIXME: This is not ideal; we shouldn't have to do this copy.
3917+
RecFields.append(Ivars.begin(), Ivars.end());
39203918
}
39213919

39223920
if (RecFields.empty())
@@ -5258,13 +5256,12 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
52585256

52595257
std::vector<llvm::Constant*> Ivars, Ivar(5);
52605258

5261-
ObjCInterfaceDecl *OID =
5262-
const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
5259+
const ObjCInterfaceDecl *OID = ID->getClassInterface();
52635260
assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
52645261

52655262
// FIXME. Consolidate this with similar code in GenerateClass.
52665263

5267-
for (ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
5264+
for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
52685265
IVD; IVD = IVD->getNextIvar()) {
52695266
// Ignore unnamed bit-fields.
52705267
if (!IVD->getDeclName())

lib/CodeGen/CGObjCRuntime.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
5252
// implemented. This should be fixed to get the information from the layout
5353
// directly.
5454
unsigned Index = 0;
55-
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl*>(Container);
5655

57-
for (ObjCIvarDecl *IVD = IDecl->all_declared_ivar_begin();
56+
for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
5857
IVD; IVD = IVD->getNextIvar()) {
5958
if (Ivar == IVD)
6059
break;

lib/CodeGen/CodeGenModule.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -2001,9 +2001,8 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
20012001
}
20022002

20032003
static bool needsDestructMethod(ObjCImplementationDecl *impl) {
2004-
ObjCInterfaceDecl *iface
2005-
= const_cast<ObjCInterfaceDecl*>(impl->getClassInterface());
2006-
for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
2004+
const ObjCInterfaceDecl *iface = impl->getClassInterface();
2005+
for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
20072006
ivar; ivar = ivar->getNextIvar())
20082007
if (ivar->getType().isDestructedType())
20092008
return true;

lib/Sema/SemaDeclObjC.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2533,11 +2533,11 @@ void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
25332533
}
25342534

25352535
// Collect the instance variables
2536-
llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
2536+
SmallVector<const ObjCIvarDecl*, 32> Ivars;
25372537
Context.DeepCollectObjCIvars(Class, true, Ivars);
25382538
// For each ivar, create a fresh ObjCAtDefsFieldDecl.
25392539
for (unsigned i = 0; i < Ivars.size(); i++) {
2540-
FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
2540+
const FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
25412541
RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
25422542
Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record,
25432543
/*FIXME: StartL=*/ID->getLocation(),

0 commit comments

Comments
 (0)