[cfe-commits] r61043 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CGObjCGNU.cpp lib/CodeGen/CGObjCMac.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/CodeGenTypes.h

Fariborz Jahanian fjahanian at apple.com
Mon Dec 15 12:35:08 PST 2008


Author: fjahanian
Date: Mon Dec 15 14:35:07 2008
New Revision: 61043

URL: http://llvm.org/viewvc/llvm-project?rev=61043&view=rev
Log:
Code gen. for ivar references; including bitfield
ivars.

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.h

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Dec 15 14:35:07 2008
@@ -384,7 +384,8 @@
    
   void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
                                    SourceLocation RBracLoc);
-  FieldDecl *lookupFieldDeclForIvar(ASTContext &Context, ObjCIvarDecl *ivar);
+  FieldDecl *lookupFieldDeclForIvar(ASTContext &Context, 
+                                    const ObjCIvarDecl *ivar);
   void addLayoutToClass(ASTContext &Context);
 
   void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Mon Dec 15 14:35:07 2008
@@ -367,7 +367,7 @@
 /// storage which matches this 'ivar'.
 ///
 FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, 
-                                                     ObjCIvarDecl *ivar) {
+                                                     const ObjCIvarDecl *ivar) {
   assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
   DeclarationName Member = ivar->getDeclName();
   DeclContext::lookup_result Lookup = RecordForDecl->lookup(Context, Member);
@@ -392,7 +392,8 @@
   for (unsigned int i = 0; i != RecFields.size(); i++) {
     FieldDecl *Field =  FieldDecl::Create(Context, RD, SourceLocation(), 
                                           RecFields[i]->getIdentifier(),
-                                          RecFields[i]->getType(), 0, false, 0);
+                                          RecFields[i]->getType(), 
+                                          RecFields[i]->getBitWidth(), false, 0);
     RD->addDecl(Context, Field);
   }
   RD->completeDefinition(Context);

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Dec 15 14:35:07 2008
@@ -788,36 +788,41 @@
   return MemExpLV;
 }
 
+LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
+                                              FieldDecl* Field,
+                                              unsigned CVRQualifiers,
+                                              unsigned idx) {
+  // FIXME: CodeGenTypes should expose a method to get the appropriate
+  // type for FieldTy (the appropriate type is ABI-dependent).
+  const llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(Field->getType());
+  const llvm::PointerType *BaseTy =
+  cast<llvm::PointerType>(BaseValue->getType());
+  unsigned AS = BaseTy->getAddressSpace();
+  BaseValue = Builder.CreateBitCast(BaseValue,
+                                    llvm::PointerType::get(FieldTy, AS),
+                                    "tmp");
+  llvm::Value *V = Builder.CreateGEP(BaseValue,
+                              llvm::ConstantInt::get(llvm::Type::Int32Ty, idx),
+                              "tmp");
+  
+  CodeGenTypes::BitFieldInfo bitFieldInfo = 
+    CGM.getTypes().getBitFieldInfo(Field);
+  return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
+                              Field->getType()->isSignedIntegerType(),
+                            Field->getType().getCVRQualifiers()|CVRQualifiers);
+}
+
 LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
                                            FieldDecl* Field,
                                            bool isUnion,
                                            unsigned CVRQualifiers)
 {
-  llvm::Value *V;
   unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
 
-  if (Field->isBitField()) {
-    // FIXME: CodeGenTypes should expose a method to get the appropriate
-    // type for FieldTy (the appropriate type is ABI-dependent).
-    const llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(Field->getType());
-    const llvm::PointerType *BaseTy =
-      cast<llvm::PointerType>(BaseValue->getType());
-    unsigned AS = BaseTy->getAddressSpace();
-    BaseValue = Builder.CreateBitCast(BaseValue,
-                                      llvm::PointerType::get(FieldTy, AS),
-                                      "tmp");
-    V = Builder.CreateGEP(BaseValue,
-                          llvm::ConstantInt::get(llvm::Type::Int32Ty, idx),
-                          "tmp");
-
-    CodeGenTypes::BitFieldInfo bitFieldInfo =
-      CGM.getTypes().getBitFieldInfo(Field);
-    return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
-                                Field->getType()->isSignedIntegerType(),
-                            Field->getType().getCVRQualifiers()|CVRQualifiers);
-  }
+  if (Field->isBitField())
+    return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers, idx);
   
-  V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
+  llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
 
   // Match union field type.
   if (isUnion) {
@@ -944,8 +949,9 @@
     CGM.getTypes().ConvertType(getContext().getObjCInterfaceType(Interface));
   const llvm::StructLayout *Layout =
     CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceLTy));
+  FieldDecl *Field = Interface->lookupFieldDeclForIvar(getContext(), Ivar);
   uint64_t Offset = 
-    Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Ivar));
+    Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
   
   return llvm::ConstantInt::get(CGM.getTypes().ConvertType(getContext().LongTy),
                                 Offset);                                                             
@@ -953,17 +959,18 @@
 
 LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue,
                                           const ObjCIvarDecl *Ivar,
+                                          const FieldDecl *Field,
                                           unsigned CVRQualifiers) {
   // See comment in EmitIvarOffset.
   if (CGM.getObjCRuntime().LateBoundIVars())
     assert(0 && "late-bound ivars are unsupported");
-
-  if (Ivar->isBitField())
-    assert(0 && "ivar bitfields are unsupported");
-  
   // TODO:  Add a special case for isa (index 0)
-  unsigned Index = CGM.getTypes().getLLVMFieldNo(Ivar);
+  unsigned Index = CGM.getTypes().getLLVMFieldNo(Field);
   
+  if (Ivar->isBitField()) {
+    return EmitLValueForBitfield(BaseValue, const_cast<FieldDecl *>(Field), 
+                                 CVRQualifiers, Index);
+  }
   llvm::Value *V = Builder.CreateStructGEP(BaseValue, Index, "tmp");
   LValue LV = LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers);
   SetVarDeclObjCAttribute(getContext(), Ivar, Ivar->getType(), LV);
@@ -988,7 +995,8 @@
     CVRQualifiers = BaseExpr->getType().getCVRQualifiers();
   }
 
-  return EmitLValueForIvar(BaseValue, E->getDecl(), CVRQualifiers);
+  return EmitLValueForIvar(BaseValue, E->getDecl(), E->getFieldDecl(), 
+                           CVRQualifiers);
 }
 
 LValue 

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Dec 15 14:35:07 2008
@@ -190,7 +190,9 @@
                                            Types.ConvertType(PD->getType())));
     EmitReturnOfRValue(RV, PD->getType());
   } else {
-    LValue LV = EmitLValueForIvar(LoadObjCSelf(), Ivar, 0);
+    FieldDecl *Field = 
+      IMP->getClassInterface()->lookupFieldDeclForIvar(getContext(), Ivar);
+    LValue LV = EmitLValueForIvar(LoadObjCSelf(), Ivar, Field, 0);
     if (hasAggregateLLVMType(Ivar->getType())) {
       EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
     }

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Mon Dec 15 14:35:07 2008
@@ -720,8 +720,9 @@
       Context.getObjCEncodingForType((*iter)->getType(), TypeStr);
       IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
       // Get the offset
+      FieldDecl *Field = ClassDecl->lookupFieldDeclForIvar(Context, (*iter));
       int offset =
-        (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(*iter));
+        (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
       IvarOffsets.push_back(
           llvm::ConstantInt::get(llvm::Type::Int32Ty, offset));
   }

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Mon Dec 15 14:35:07 2008
@@ -1328,9 +1328,12 @@
   for (ObjCInterfaceDecl::ivar_iterator 
          i = ID->getClassInterface()->ivar_begin(),
          e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
-    ObjCIvarDecl *V = *i;
+    const ObjCIvarDecl *V = *i;
+    ObjCInterfaceDecl *OID = 
+      const_cast<ObjCInterfaceDecl *>(ID->getClassInterface());
+    FieldDecl *Field = OID->lookupFieldDeclForIvar(CGM.getContext(), V);
     unsigned Offset = 
-      Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
+      Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
     std::string TypeStr;
     Ivar[0] = GetMethodVarName(V->getIdentifier());
     CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, true);

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Dec 15 14:35:07 2008
@@ -497,8 +497,12 @@
   LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field,
                             bool isUnion, unsigned CVRQualifiers);
   LValue EmitLValueForIvar(llvm::Value* Base, const ObjCIvarDecl *Ivar,
+                           const FieldDecl *Field,
                            unsigned CVRQualifiers);
 
+  LValue EmitLValueForBitfield(llvm::Value* Base, FieldDecl* Field,
+                                unsigned CVRQualifiers, unsigned idx);
+
   LValue EmitCXXConditionDeclLValue(const CXXConditionDeclExpr *E);
 
   LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Dec 15 14:35:07 2008
@@ -155,21 +155,6 @@
   cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT);
 }
 
-/// Produces a vector containing the all of the instance variables in an
-/// Objective-C object, in the order that they appear.  Used to create LLVM
-/// structures corresponding to Objective-C objects.
-void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
-                                    std::vector<const llvm::Type*> &IvarTypes) {
-  ObjCInterfaceDecl *SuperClass = ObjCClass->getSuperClass();
-  if (SuperClass)
-    CollectObjCIvarTypes(SuperClass, IvarTypes);
-  for (ObjCInterfaceDecl::ivar_iterator I = ObjCClass->ivar_begin(),
-       E = ObjCClass->ivar_end(); I != E; ++I) {
-    IvarTypes.push_back(ConvertType((*I)->getType()));
-    ObjCIvarInfo[*I] = IvarTypes.size() - 1;
-  }
-}
-
 static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) {
   if (&format == &llvm::APFloat::IEEEsingle)
     return llvm::Type::FloatTy;
@@ -280,21 +265,22 @@
       ConvertTypeRecursive(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
 
   case Type::ObjCInterface: {
-    // FIXME: This comment is broken. Either the code should check for
-    // the flag it is referring to or it should do the right thing in
-    // the presence of it.
-    
     // Warning: Use of this is strongly discouraged.  Late binding of instance
     // variables is supported on some runtimes and so using static binding can
     // break code when libraries are updated.  Only use this if you have
     // previously checked that the ObjCRuntime subclass in use does not support
     // late-bound ivars.
+    // We are issuing warnings elsewhere!
     ObjCInterfaceType OIT = cast<ObjCInterfaceType>(Ty);
-    std::vector<const llvm::Type*> IvarTypes;
-    CollectObjCIvarTypes(OIT.getDecl(), IvarTypes);
-    llvm::Type *T = llvm::StructType::get(IvarTypes);
-    TheModule.addTypeName("struct." + OIT.getDecl()->getNameAsString(), T);
-    return T;
+    ObjCInterfaceDecl *ID = OIT.getDecl();
+    RecordDecl *RD = ID->getRecordForDecl();
+    if(!RD) {
+      // Sometimes, class type is being directly generated in code gen for
+      // built-in class types.
+      ID->addLayoutToClass(Context);
+      RD = ID->getRecordForDecl();
+    }
+    return ConvertTagDeclType(cast<TagDecl>(RD));
   }
       
   case Type::ObjCQualifiedInterface: {
@@ -427,13 +413,6 @@
   return I->second;
 }
 
-unsigned CodeGenTypes::getLLVMFieldNo(const ObjCIvarDecl *OID) {
-  llvm::DenseMap<const ObjCIvarDecl*, unsigned>::iterator
-    I = ObjCIvarInfo.find(OID);
-  assert(I != ObjCIvarInfo.end() && "Unable to find field info");
-  return I->second;
-}
-
 /// addFieldInfo - Assign field number to field FD.
 void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) {
   FieldInfo[FD] = No;

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=61043&r1=61042&r2=61043&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Mon Dec 15 14:35:07 2008
@@ -99,7 +99,6 @@
   /// FieldInfo - This maps struct field with corresponding llvm struct type
   /// field no. This info is populated by record organizer.
   llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
-  llvm::DenseMap<const ObjCIvarDecl *, unsigned> ObjCIvarInfo;
 
 public:
   class BitFieldInfo {
@@ -158,9 +157,6 @@
                                             ArgTypeIterator end,
                                             bool IsVariadic);
   
-  void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
-                            std::vector<const llvm::Type*> &IvarTypes);
-  
   const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
   /// Returns a StructType representing an Objective-C object
   const llvm::Type *ConvertObjCInterfaceToStruct(const ObjCInterfaceDecl *OID);
@@ -168,8 +164,6 @@
   /// getLLVMFieldNo - Return llvm::StructType element number
   /// that corresponds to the field FD.
   unsigned getLLVMFieldNo(const FieldDecl *FD);
-  unsigned getLLVMFieldNo(const ObjCIvarDecl *OID);
-    
   
   /// UpdateCompletedType - When we find the full definition for a TagDecl,
   /// replace the 'opaque' type we previously made for it if applicable.





More information about the cfe-commits mailing list