diff options
| author | Chris Lattner <sabre@nondot.org> | 2008-03-30 23:03:07 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2008-03-30 23:03:07 +0000 |
| commit | 391d77a26382dddf25da73e29fc1fa5aaaea4c6f (patch) | |
| tree | b842c678fe95a0feed12419eb419e091d22fff49 /lib/CodeGen/CodeGenTypes.cpp | |
| parent | a7b402dc258bf38ab5e206dbf4916a69d3ee3cc8 (diff) | |
Add initial support for objc codegen for methods, ivars, and the
etoile runtime, patch by David Chisnall!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48969 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenTypes.cpp')
| -rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 65c5757edb..afa20e4110 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -144,7 +144,22 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) { 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 ivar=ObjCClass->ivar_begin() ; + ivar != ObjCClass->ivar_end() ; + ivar++) { + IvarTypes.push_back(ConvertType((*ivar)->getType())); + ObjCIvarInfo[*ivar] = IvarTypes.size() - 1; + } +} const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { const clang::Type &Ty = *T.getCanonicalType(); @@ -263,9 +278,21 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { 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)); + CollectObjCIvarTypes(OIT.getDecl(), IvarTypes); + return llvm::StructType::get(IvarTypes); + } case Type::ObjCQualifiedInterface: assert(0 && "FIXME: add missing functionality here"); @@ -399,6 +426,13 @@ unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) { 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; |
