]> granicus.if.org Git - clang/commitdiff
fix the two xfails I added with a previous patch by making ObjC interface
authorChris Lattner <sabre@nondot.org>
Wed, 1 Apr 2009 02:36:43 +0000 (02:36 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 1 Apr 2009 02:36:43 +0000 (02:36 +0000)
types get completed when their definition is seen if previously laid out by
the code generator.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68177 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/CodeGen/CodeGenTypes.h
test/CodeGenObjC/class-type.m
test/CodeGenObjC/forward-class-impl-metadata.m

index 59876516aa82a92a307cf4a794e25a20c5f49b27..101b2e58b7f581f1a5a99a4c9ddf0aedbc855b15 100644 (file)
@@ -1242,9 +1242,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
   case Decl::ObjCClass:
   case Decl::ObjCForwardProtocol:
   case Decl::ObjCCategory:
+    break;
   case Decl::ObjCInterface:
+    // If we already laid out this interface due to an @class, and if we
+    // codegen'd a reference it, update the 'opaque' type to be a real type now.
+    Types.UpdateCompletedType(cast<ObjCInterfaceDecl>(D));
     break;
-      
+
   case Decl::ObjCProtocol:
     Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
     break;
@@ -1252,7 +1256,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
   case Decl::ObjCCategoryImpl:
     // Categories have properties but don't support synthesize so we
     // can ignore them here.
-
     Runtime->GenerateCategory(cast<ObjCCategoryImplDecl>(D));
     break;
 
index ff4b80f3b455ed29b777e40fa46157d04f5489a1..e13a4bc65d265ccf1a99e1b3d344b418548c74cc 100644 (file)
@@ -197,6 +197,40 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
   }
 }
 
+void CodeGenTypes::UpdateCompletedType(const ObjCInterfaceDecl *OID) {
+  // Check to see if we have already laid this type out, if not, just return.
+  QualType OIDTy = 
+    Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl*>(OID));
+  llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator TCI =
+    TypeCache.find(OIDTy.getTypePtr());
+  if (TCI == TypeCache.end()) return;
+
+  // Remember the opaque LLVM type for this interface.
+  llvm::PATypeHolder OpaqueHolder = TCI->second;
+  assert(isa<llvm::OpaqueType>(OpaqueHolder.get()) &&
+         "Updating compilation of an already non-opaque type?");
+  
+  // Remove it from TagDeclTypes so that it will be regenerated.
+  TypeCache.erase(TCI);
+
+  // Update the "shadow" struct that is laid out.
+  // FIXME: REMOVE THIS.
+  const RecordDecl *RD = Context.addRecordToClass(OID);
+  UpdateCompletedType(RD);
+  
+  // Generate the new type.
+  const llvm::Type *NT = ConvertType(OIDTy);
+  assert(!isa<llvm::OpaqueType>(NT) && "Didn't do layout!");
+
+  // FIXME: Remove this check when shadow structs go away.
+  if (isa<llvm::OpaqueType>(OpaqueHolder)) {
+  
+  // Refine the old opaque type to its new definition.
+  cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT);
+  }
+}
+
+
 static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) {
   if (&format == &llvm::APFloat::IEEEsingle)
     return llvm::Type::FloatTy;
index b408ff66a6a84f106f3decc5b3d5a18d77f8acf7..813ff8b2a2c0151866269d2632ca273c2d46a6af 100644 (file)
@@ -161,6 +161,8 @@ public:
   /// UpdateCompletedType - When we find the full definition for a TagDecl,
   /// replace the 'opaque' type we previously made for it if applicable.
   void UpdateCompletedType(const TagDecl *TD);
+  /// Likewise for an ObjC Interface.
+  void UpdateCompletedType(const ObjCInterfaceDecl *OID);
 
   /// getFunctionInfo - Get the CGFunctionInfo for this function signature.
   const CGFunctionInfo &getFunctionInfo(QualType RetTy, 
index 456a6370b34d0736a64c456e4fbdf954088796ad..c8a1c18b9c926d50f0497eb027c391e977f7dc11 100644 (file)
@@ -1,5 +1,4 @@
 // RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s
-// XFAIL: *
 
 @interface I0 {
   struct { int a; } a;
index 3f8a5a4bc20ae334aa01e86c719aa0c8d0e3f8db..b3976d6458444bc8687303da1d834e68e68ae60f 100644 (file)
@@ -1,5 +1,4 @@
 // RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s
-// XFAIL: *
 
 @interface BASE  {
 @private