[cfe-commits] r66615 - in /cfe/trunk: include/clang/AST/Type.h lib/CodeGen/CGObjCMac.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Mar 10 17:07:05 PDT 2009
Author: fjahanian
Date: Tue Mar 10 19:07:04 2009
New Revision: 66615
URL: http://llvm.org/viewvc/llvm-project?rev=66615&view=rev
Log:
More Next objc2's gc ivar layout bitmap work.
Work in progress.
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=66615&r1=66614&r2=66615&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Mar 10 19:07:04 2009
@@ -369,6 +369,10 @@
/// interface types.
bool hasPointerRepresentation() const;
+ /// hasObjCPointerRepresentation - Whether this type can represent
+ /// an objective pointer type for the purpose of GC'ability
+ bool hasObjCPointerRepresentation() const;
+
// Type Checking Functions: Check to see if this type is structurally the
// specified type, ignoring typedefs and qualifiers, and return a pointer to
// the best type we can.
@@ -1866,6 +1870,11 @@
isObjCQualifiedInterfaceType());
}
+inline bool Type::hasObjCPointerRepresentation() const {
+ return (isObjCInterfaceType() || isObjCQualifiedIdType() ||
+ isObjCQualifiedInterfaceType());
+}
+
/// Insertion operator for diagnostics. This allows sending QualType's into a
/// diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=66615&r1=66614&r2=66615&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Mar 10 19:07:04 2009
@@ -308,6 +308,7 @@
class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
class GC_IVAR {
+ public:
unsigned int ivar_bytepos;
unsigned int ivar_size;
GC_IVAR() : ivar_bytepos(0), ivar_size(0) {}
@@ -2461,11 +2462,15 @@
const std::vector<FieldDecl*>& RecFields,
unsigned int BytePos, bool ForStrongLayout,
int &Index, int &SkIndex, bool &HasUnion) {
- bool is_union = (RD && RD->isUnion());
+ bool IsUnion = (RD && RD->isUnion());
+ uint64_t MaxUnionIvarSize = 0;
+ uint64_t MaxSkippedUnionIvarSize = 0;
+ FieldDecl *MaxField = 0;
+ FieldDecl *MaxSkippedField = 0;
unsigned int base = 0;
if (RecFields.empty())
return;
- if (is_union)
+ if (IsUnion)
base = BytePos + GetIvarBaseOffset(Layout, RecFields[0]);
for (unsigned i = 0; i < RecFields.size(); i++) {
@@ -2478,6 +2483,10 @@
std::vector<FieldDecl*> NestedRecFields;
if (FQT->isUnionType())
HasUnion = true;
+ else
+ assert(FQT->isRecordType() &&
+ "only union/record is supported for ivar layout bitmap");
+
const RecordType *RT = FQT->getAsRecordType();
const RecordDecl *RD = RT->getDecl();
// FIXME - Find a more efficiant way of passing records down.
@@ -2493,8 +2502,124 @@
continue;
}
else if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
- FQT = Array->getElementType();
+ const ConstantArrayType *CArray =
+ dyn_cast_or_null<ConstantArrayType>(Array);
+ assert(CArray && "only array with know element size is supported");
+ FQT = CArray->getElementType();
+ assert(!FQT->isUnionType() &&
+ "layout for array of unions not supported");
+ if (FQT->isRecordType()) {
+ uint64_t ElCount = CArray->getSize().getZExtValue();
+ int OldIndex = Index;
+ int OldSkIndex = SkIndex;
+
+ std::vector<FieldDecl*> ElementRecFields;
+ // FIXME - Use a common routine with the above!
+ const RecordType *RT = FQT->getAsRecordType();
+ const RecordDecl *RD = RT->getDecl();
+ // FIXME - Find a more efficiant way of passing records down.
+ unsigned j = 0;
+ for (RecordDecl::field_iterator i = RD->field_begin(),
+ e = RD->field_end(); i != e; ++i)
+ ElementRecFields[j++] = (*i);
+ BuildAggrIvarLayout(Layout, RD,
+ ElementRecFields,
+ BytePos + GetIvarBaseOffset(Layout, Field),
+ ForStrongLayout, Index, SkIndex,
+ HasUnion);
+ // Replicate layout information for each array element. Note that
+ // one element is already done.
+ uint64_t ElIx = 1;
+ for (int FirstIndex = Index, FirstSkIndex = SkIndex;
+ ElIx < ElCount; ElIx++) {
+ uint64_t Size = CGM.getContext().getTypeSize(RT);
+ for (int i = OldIndex+1; i <= FirstIndex; ++i)
+ {
+ IvarsInfo[++Index].ivar_bytepos =
+ IvarsInfo[i].ivar_bytepos + Size*ElIx;
+ IvarsInfo[Index].ivar_size = IvarsInfo[i].ivar_size;
+ }
+
+ for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
+ {
+ SkipIvars[++SkIndex].ivar_bytepos =
+ SkipIvars[i].ivar_bytepos + Size*ElIx;
+ SkipIvars[SkIndex].ivar_size = SkipIvars[i].ivar_size;
+ }
+ }
+ continue;
+ }
}
+ // At this point, we are done with Record/Union and array there of.
+ // For other arrays we are down to its element type.
+ QualType::GCAttrTypes GCAttr = QualType::GCNone;
+ do {
+ if (FQT.isObjCGCStrong() || FQT.isObjCGCWeak()) {
+ GCAttr = FQT.isObjCGCStrong() ? QualType::Strong : QualType::Weak;
+ break;
+ }
+ else if (FQT->hasObjCPointerRepresentation()) {
+ GCAttr = QualType::Strong;
+ break;
+ }
+ else if (const PointerType *PT = FQT->getAsPointerType()) {
+ FQT = PT->getPointeeType();
+ }
+ else {
+ break;
+ }
+ } while (true);
+ if ((ForStrongLayout && GCAttr == QualType::Strong)
+ || (!ForStrongLayout && GCAttr == QualType::Weak)) {
+ if (IsUnion)
+ {
+ uint64_t UnionIvarSize = CGM.getContext().getTypeSize(Field->getType());
+ if (UnionIvarSize > MaxUnionIvarSize)
+ {
+ MaxUnionIvarSize = UnionIvarSize;
+ MaxField = Field;
+ }
+ }
+ else
+ {
+ IvarsInfo[++Index].ivar_bytepos =
+ BytePos + GetIvarBaseOffset(Layout, Field);
+ IvarsInfo[Index].ivar_size =
+ CGM.getContext().getTypeSize(Field->getType());
+ }
+ }
+ else if ((ForStrongLayout &&
+ (GCAttr == QualType::GCNone || GCAttr == QualType::Weak))
+ || (!ForStrongLayout && GCAttr != QualType::Weak)) {
+ if (IsUnion)
+ {
+ uint64_t UnionIvarSize = CGM.getContext().getTypeSize(Field->getType());
+ if (UnionIvarSize > MaxSkippedUnionIvarSize)
+ {
+ MaxSkippedUnionIvarSize = UnionIvarSize;
+ MaxSkippedField = Field;
+ }
+ }
+ else
+ {
+ SkipIvars[++SkIndex].ivar_bytepos =
+ BytePos + GetIvarBaseOffset(Layout, Field);
+ SkipIvars[SkIndex].ivar_size =
+ CGM.getContext().getTypeSize(Field->getType());
+ }
+ }
+ }
+ if (MaxField)
+ {
+ IvarsInfo[++Index].ivar_bytepos =
+ BytePos + GetIvarBaseOffset(Layout, MaxField);
+ IvarsInfo[Index].ivar_size = MaxUnionIvarSize;
+ }
+ if (MaxSkippedField)
+ {
+ SkipIvars[++SkIndex].ivar_bytepos =
+ BytePos + GetIvarBaseOffset(Layout, MaxSkippedField);
+ SkipIvars[SkIndex].ivar_size = MaxSkippedUnionIvarSize;
}
return;
}
More information about the cfe-commits
mailing list