[cfe-commits] r70756 - in /cfe/trunk/lib: AST/ASTContext.cpp CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Sun May 3 06:15:51 PDT 2009
Author: ddunbar
Date: Sun May 3 08:15:50 2009
New Revision: 70756
URL: http://llvm.org/viewvc/llvm-project?rev=70756&view=rev
Log:
Use ASTRecordLayout for computing ivar offsets instead of shadow
struct.
- We still need to do more lookup than necessary because ivars don't
live in a reasonable DeclContext.
- The only remaining client of the interface shadow struct is the
ivar layout bitmap.
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=70756&r1=70755&r2=70756&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun May 3 08:15:50 2009
@@ -744,6 +744,8 @@
const ASTRecordLayout &
ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) {
+ assert(!D->isForwardDecl() && "Invalid interface decl!");
+
// Look up this layout, if already laid out, return what we have.
ObjCContainerDecl *Key =
Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D;
@@ -768,6 +770,9 @@
ASTRecordLayout *NewEntry = NULL;
if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
+ // FIXME: This increment of FieldCount is wrong, we don't actually
+ // count the super class as a member (see the field index passed
+ // to LayoutField below).
FieldCount++;
const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD);
unsigned Alignment = SL.getAlignment();
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=70756&r1=70755&r2=70756&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sun May 3 08:15:50 2009
@@ -43,57 +43,59 @@
return cast<llvm::StructType>(CGM.getTypes().ConvertTagDeclType(RD));
}
-
-/// LookupFieldDeclForIvar - looks up a field decl in the laid out
-/// storage which matches this 'ivar'.
+/// FindIvarInterface - Find the interface containing the ivar.
///
-static const FieldDecl *LookupFieldDeclForIvar(ASTContext &Context,
- const ObjCInterfaceDecl *OID,
- const ObjCIvarDecl *OIVD,
- const ObjCInterfaceDecl *&Found) {
- assert(!OID->isForwardDecl() && "Invalid interface decl!");
- const RecordDecl *RecordForDecl = Context.addRecordToClass(OID);
- assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
- DeclContext::lookup_const_result Lookup =
- RecordForDecl->lookup(Context, OIVD->getDeclName());
-
- if (Lookup.first != Lookup.second) {
- Found = OID;
- return cast<FieldDecl>(*Lookup.first);
+/// FIXME: We shouldn't need to do this, the containing context should
+/// be fixed.
+static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
+ const ObjCInterfaceDecl *OID,
+ const ObjCIvarDecl *OIVD,
+ unsigned &Index) {
+ const ObjCInterfaceDecl *Super = OID->getSuperClass();
+
+ // FIXME: The index here is closely tied to how
+ // ASTContext::getObjCLayout is implemented. This should be fixed to
+ // get the information from the layout directly.
+ Index = 0;
+ for (ObjCInterfaceDecl::ivar_iterator IVI = OID->ivar_begin(),
+ IVE = OID->ivar_end(); IVI != IVE; ++IVI, ++Index)
+ if (OIVD == *IVI)
+ return OID;
+
+ // Also look in synthesized ivars.
+ for (ObjCInterfaceDecl::prop_iterator I = OID->prop_begin(Context),
+ E = OID->prop_end(Context); I != E; ++I) {
+ if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) {
+ if (OIVD == Ivar)
+ return OID;
+ ++Index;
+ }
}
- // If lookup failed, try the superclass.
- //
- // FIXME: This is slow, we shouldn't need to do this.
- const ObjCInterfaceDecl *Super = OID->getSuperClass();
- assert(Super && "field decl not found!");
- return LookupFieldDeclForIvar(Context, Super, OIVD, Found);
+ // Otherwise check in the super class.
+ if (Super)
+ return FindIvarInterface(Context, Super, OIVD, Index);
+
+ return 0;
}
static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) {
- assert(!OID->isForwardDecl() && "Invalid interface decl!");
- const ObjCInterfaceDecl *Container;
- const FieldDecl *Field =
- LookupFieldDeclForIvar(CGM.getContext(), OID, Ivar, Container);
- const llvm::StructType *STy =
- GetConcreteClassStruct(CGM, Container);
- const llvm::StructLayout *Layout =
- CGM.getTargetData().getStructLayout(STy);
- if (!Field->isBitField())
- return Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)) * 8;
-
- // FIXME. Must be a better way of getting a bitfield base offset.
- CodeGenTypes::BitFieldInfo BFI = CGM.getTypes().getBitFieldInfo(Field);
- // FIXME: The "field no" for bitfields is something completely
- // different; it is the offset in multiples of the base type size!
- uint64_t Offset = CGM.getTypes().getLLVMFieldNo(Field);
- const llvm::Type *Ty =
- CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
- Offset *= CGM.getTypes().getTargetData().getTypePaddedSizeInBits(Ty);
- return Offset + BFI.Begin;
+ unsigned Index;
+ const ObjCInterfaceDecl *Container =
+ FindIvarInterface(CGM.getContext(), OID, Ivar, Index);
+ assert(Container && "Unable to find ivar container");
+
+ // If we know have an implementation (and the ivar is in it) then
+ // look up in the implementation layout.
+ const ASTRecordLayout *RL;
+ if (ID && ID->getClassInterface() == Container)
+ RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
+ else
+ RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
+ return RL->getFieldOffset(Index);
}
uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
More information about the cfe-commits
mailing list