From: Fariborz Jahanian Date: Tue, 18 Nov 2008 20:18:11 +0000 (+0000) Subject: Some basic support toward objective-c's GC code gen. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d657c4809d9128be88705d32768de007b988212;p=clang Some basic support toward objective-c's GC code gen. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59543 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 5f5001732c..993562592b 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -492,8 +492,14 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return LValue::MakeAddr(V, E->getType().getCVRQualifiers()); } } else if (VD && VD->isFileVarDecl()) { - return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), - E->getType().getCVRQualifiers()); + LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), + E->getType().getCVRQualifiers()); + if (VD->getAttr()) + { + ObjCGCAttr::GCAttrTypes attrType = (VD->getAttr())->getType(); + LValue::SetObjCGCAttrs(attrType == ObjCGCAttr::Weak, attrType == ObjCGCAttr::Strong, LV); + } + return LV; } else if (const FunctionDecl *FD = dyn_cast(E->getDecl())) { return LValue::MakeAddr(CGM.GetAddrOfFunction(FD), E->getType().getCVRQualifiers()); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index a8f6bbab9b..1591831458 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -51,6 +51,10 @@ public: /// ObjectPtrTy - LLVM type for object handles (typeof(id)) const llvm::Type *ObjectPtrTy; + + /// PtrObjectPtrTy - LLVM type for id * + const llvm::Type *PtrObjectPtrTy; + /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) const llvm::Type *SelectorPtrTy; /// ProtocolPtrTy - LLVM type for external protocol handles @@ -162,6 +166,18 @@ public: /// SyncExitFn - LLVM object_sync_exit function. llvm::Function *SyncExitFn; + /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. + llvm::Function *GcReadWeakFn; + + /// GcAssignWeakFn -- LLVM objc_assign_weak function. + llvm::Function *GcAssignWeakFn; + + /// GcAssignGlobalFn -- LLVM objc_assign_global function. + llvm::Function *GcAssignGlobalFn; + + /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. + llvm::Function *GcAssignStrongCastFn; + public: ObjCTypesHelper(CodeGen::CodeGenModule &cgm); ~ObjCTypesHelper(); @@ -2191,6 +2207,7 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); + PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); // FIXME: It would be nice to unify this with the opaque type, so @@ -2538,6 +2555,36 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) Params, false), "_setjmp"); + + // gc's API + // id objc_read_weak (id *) + Params.clear(); + Params.push_back(PtrObjectPtrTy); + GcReadWeakFn = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, + Params, + false), + "objc_read_weak"); + // id objc_assign_weak (id, id *) + Params.clear(); + Params.push_back(ObjectPtrTy); + Params.push_back(PtrObjectPtrTy); + GcAssignWeakFn = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, + Params, + false), + "objc_assign_weak"); + GcAssignGlobalFn = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, + Params, + false), + "objc_assign_global"); + GcAssignStrongCastFn = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, + Params, + false), + "objc_assign_strongCast"); + } ObjCTypesHelper::~ObjCTypesHelper() { diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index e601b04900..505381eb41 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -130,13 +130,16 @@ class LValue { bool Volatile:1; // FIXME: set but never used, what effect should it have? bool Restrict:1; + + bool ObjcWeak:1; + bool ObjcStrong:1; private: static void SetQualifiers(unsigned Qualifiers, LValue& R) { R.Volatile = (Qualifiers&QualType::Volatile)!=0; R.Restrict = (Qualifiers&QualType::Restrict)!=0; } - + public: bool isSimple() const { return LVType == Simple; } bool isVectorElt() const { return LVType == VectorElt; } @@ -146,7 +149,15 @@ public: bool isVolatileQualified() const { return Volatile; } bool isRestrictQualified() const { return Restrict; } - + + bool isObjcWeak() const { return ObjcWeak; } + bool isObjcStrong() const { return ObjcStrong; } + + static void SetObjCGCAttrs(unsigned Weak, unsigned Strong, LValue& R) { + R.ObjcWeak = Weak; + R.ObjcStrong = Strong; + } + // simple lvalue llvm::Value *getAddress() const { assert(isSimple()); return V; } // vector elt lvalue