Index: lib/CodeGen/CodeGenTypes.h
===================================================================
--- lib/CodeGen/CodeGenTypes.h	(revision 48734)
+++ lib/CodeGen/CodeGenTypes.h	(working copy)
@@ -34,6 +34,8 @@
   class FunctionTypeProto;
   class FieldDecl;
   class RecordDecl;
+  class ObjCInterfaceDecl;
+  class ObjCIvarDecl;
 
 namespace CodeGen {
   class CodeGenTypes;
@@ -128,12 +130,15 @@
   /// memory representation is usually i8 or i32, depending on the target.
   const llvm::Type *ConvertTypeForMem(QualType T);
   
+  void CollectIvarTypes(ObjCInterfaceDecl *ObjCClass,
+      std::vector<const llvm::Type*> *IvarTypes);
   
   const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
   
   /// getLLVMFieldNo - Return llvm::StructType element number
   /// that corresponds to the field FD.
   unsigned getLLVMFieldNo(const FieldDecl *FD);
+  unsigned getLLVMFieldNo(QualType ObjectTy, const ObjCIvarDecl *Decl);
     
   
   /// UpdateCompletedType - When we find the full definition for a TagDecl,
Index: lib/CodeGen/CodeGenTypes.cpp
===================================================================
--- lib/CodeGen/CodeGenTypes.cpp	(revision 48734)
+++ lib/CodeGen/CodeGenTypes.cpp	(working copy)
@@ -144,8 +144,19 @@
   cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT);
 }
 
+void CodeGenTypes::CollectIvarTypes(ObjCInterfaceDecl *ObjCClass,
+    std::vector<const llvm::Type*> *IvarTypes) {
+  ObjCInterfaceDecl *SuperClass = ObjCClass->getSuperClass();
+  if(SuperClass) {
+    CollectIvarTypes(SuperClass, IvarTypes);
+  }
+  for(ObjCInterfaceDecl::ivar_iterator ivar=ObjCClass->ivar_begin() ;
+      ivar != ObjCClass->ivar_end() ;
+      ivar++) {
+    IvarTypes->push_back(ConvertType((*ivar)->getType()));
+  }
+}
 
-
 const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
   const clang::Type &Ty = *T.getCanonicalType();
   
@@ -263,9 +274,21 @@
   case Type::ASQual:
     return ConvertType(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
 
-  case Type::ObjCInterface:
-    assert(0 && "FIXME: add missing functionality here");
-    break;
+  case Type::ObjCInterface: {
+    // 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.
+    ObjCInterfaceType OIT = cast<ObjCInterfaceType>(Ty);
+    std::vector<const llvm::Type*> IvarTypes;
+    // Pointer to the class.  This is just a placeholder.  Operations that
+    // actually use the isa pointer should cast it to the Class type provided
+    // by the runtime.
+    IvarTypes.push_back(llvm::PointerType::getUnqual(llvm::Type::Int8Ty));
+    CollectIvarTypes(OIT.getDecl(), &IvarTypes);
+    return llvm::StructType::get(IvarTypes);
+  }
       
   case Type::ObjCQualifiedInterface:
     assert(0 && "FIXME: add missing functionality here");
@@ -399,6 +422,37 @@
   return I->second;
 }
 
+unsigned CodeGenTypes::getLLVMFieldNo(QualType ObjectTy, const ObjCIvarDecl *Decl) {
+  unsigned Index = 1;
+  bool found = false;
+  const clang::Type &Ty = *ObjectTy.getCanonicalType();
+  const QualType OTy = cast<PointerType>(Ty).getPointeeType();
+  ObjCInterfaceDecl * Class = cast<ObjCInterfaceType>(*OTy).getDecl();
+  // Find the Ivar:
+  while(Class) {
+    if(found) {
+      Index += Class->ivar_size();
+    }
+    else {
+      for(ObjCInterfaceDecl::ivar_iterator ivar = Class->ivar_end() ;
+          ivar != Class->ivar_begin() ;
+          ivar--) {
+        if(!found) {
+          if(*ivar == Decl) {
+            found = true;
+            Index++;
+          }
+        }
+        else {
+          Index++;
+        }
+      }
+    }
+    Class = Class->getSuperClass();
+  }
+  return Index;
+}
+
 /// addFieldInfo - Assign field number to field FD.
 void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) {
   FieldInfo[FD] = No;
