diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-01 02:36:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-01 02:36:43 +0000 |
commit | d18136a644dc1da8b9c1eba27596f36c622f7f89 (patch) | |
tree | e8d5f182738f68a96f521efe7aa62ddebbb6acc7 | |
parent | 648390895746f497cd48a34d1f833c69ce3693cd (diff) | |
download | bcm5719-llvm-d18136a644dc1da8b9c1eba27596f36c622f7f89.tar.gz bcm5719-llvm-d18136a644dc1da8b9c1eba27596f36c622f7f89.zip |
fix the two xfails I added with a previous patch by making ObjC interface
types get completed when their definition is seen if previously laid out by
the code generator.
llvm-svn: 68177
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 34 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 2 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/class-type.m | 1 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/forward-class-impl-metadata.m | 1 |
5 files changed, 41 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 59876516aa8..101b2e58b7f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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; diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index ff4b80f3b45..e13a4bc65d2 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -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; diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index b408ff66a6a..813ff8b2a2c 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -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, diff --git a/clang/test/CodeGenObjC/class-type.m b/clang/test/CodeGenObjC/class-type.m index 456a6370b34..c8a1c18b9c9 100644 --- a/clang/test/CodeGenObjC/class-type.m +++ b/clang/test/CodeGenObjC/class-type.m @@ -1,5 +1,4 @@ // RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s -// XFAIL: * @interface I0 { struct { int a; } a; diff --git a/clang/test/CodeGenObjC/forward-class-impl-metadata.m b/clang/test/CodeGenObjC/forward-class-impl-metadata.m index 3f8a5a4bc20..b3976d64584 100644 --- a/clang/test/CodeGenObjC/forward-class-impl-metadata.m +++ b/clang/test/CodeGenObjC/forward-class-impl-metadata.m @@ -1,5 +1,4 @@ // RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s -// XFAIL: * @interface BASE { @private |