diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 7b7c2fbd0516..a80274a6909b 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -37,8 +37,8 @@ const llvm::StructType * CGObjCRuntime::GetConcreteClassStruct(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID) { assert(!OID->isForwardDecl() && "Invalid interface decl!"); - QualType T = CGM.getContext().getObjCInterfaceType(OID); - return cast(CGM.getTypes().ConvertType(T)); + const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); + return cast(CGM.getTypes().ConvertTagDeclType(RD)); } uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, @@ -71,6 +71,11 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers, llvm::Value *Offset) { + // Force generation of the codegen information for this structure. + // + // FIXME: Remove once we don't use the bit-field lookup map. + (void) GetConcreteClassStruct(CGF.CGM, OID); + // FIXME: For now, we use an implementation based on just computing // the offset and calculating things directly. For optimization // purposes, it would be cleaner to use a GEP on the proper type diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ba0b28ac975d..0247b693faff 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1369,11 +1369,7 @@ 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(D)); break; case Decl::ObjCProtocol: diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index f8d6436cc43d..94853b2e867d 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -197,39 +197,6 @@ 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(OID); - llvm::DenseMap::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(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(NT) && "Didn't do layout!"); - - // FIXME: Remove this check when shadow structs go away. - if (isa(OpaqueHolder)) { - - // Refine the old opaque type to its new definition. - cast(OpaqueHolder.get())->refineAbstractTypeTo(NT); - } -} - - static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) { if (&format == &llvm::APFloat::IEEEsingle) return llvm::Type::FloatTy; @@ -373,8 +340,13 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { } case Type::ObjCInterface: { - ObjCInterfaceDecl *ID = cast(Ty).getDecl(); - return ConvertTagDeclType(Context.addRecordToClass(ID)); + // Objective-C interfaces are always opaque (outside of the + // runtime, which can do whatever it likes); we never refine + // these. + const llvm::Type *&T = InterfaceTypes[cast(&Ty)]; + if (!T) + T = llvm::OpaqueType::get(); + return T; } case Type::ObjCQualifiedId: diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index a23b8f651a8c..b72d8e92013a 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -92,6 +92,12 @@ class CodeGenTypes { llvm::DenseMap FunctionTypes; + /// The opaque type map for Objective-C interfaces. All direct + /// manipulation is done by the runtime interfaces, which are + /// responsible for coercing to the appropriate type; these opaque + /// types are never refined. + llvm::DenseMap InterfaceTypes; + /// CGRecordLayouts - This maps llvm struct type with corresponding /// record layout info. /// FIXME : If CGRecordLayout is less than 16 bytes then use @@ -162,8 +168,6 @@ 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,