From: Fariborz Jahanian Date: Thu, 20 Nov 2008 00:15:42 +0000 (+0000) Subject: More objc gc stuff. Read/Write barriers for local static/extern, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2682d8b3a0415d521d5ca11afb13a8bc5c559a31;p=clang More objc gc stuff. Read/Write barriers for local static/extern, diagnostics on use of __weak attribute on fields, Early support for read/write barriers for objc fields. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59682 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 2b15f5d1f5..0f7282799f 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -790,6 +790,8 @@ DIAG(err_attribute_annotate_no_string, ERROR, "argument to annotate attribute was not a string literal") DIAG(warn_attribute_ignored, WARNING, "'%0' attribute ignored") +DIAG(warn_attribute_weak_on_field, WARNING, + "__weak attribute cannot be specified on a field declaration") DIAG(warn_attribute_wrong_decl_type, WARNING, "'%0' attribute only applies to %1 types") DIAG(warn_attribute_ignored_for_field_of_type, WARNING, diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 9e4d66a947..4228bc22b6 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -521,33 +521,48 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src, Builder.CreateStore(Vec, Dst.getExtVectorAddr(), Dst.isVolatileQualified()); } +/// SetVarDeclObjCAttribute - Set __weak/__strong attributes into the LValue +/// object. +void CodeGenFunction::SetVarDeclObjCAttribute(const VarDecl *VD, + const QualType &Ty, + LValue &LV) +{ + if (const ObjCGCAttr *A = VD->getAttr()) { + ObjCGCAttr::GCAttrTypes attrType = A->getType(); + LValue::SetObjCType(attrType == ObjCGCAttr::Weak, + attrType == ObjCGCAttr::Strong, LV); + } + else if (CGM.getLangOptions().ObjC1 && + CGM.getLangOptions().getGCMode() != LangOptions::NonGC) { + if (getContext().isObjCObjectPointerType(Ty)) + LValue::SetObjCType(false, true, LV); + } +} LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { const VarDecl *VD = dyn_cast(E->getDecl()); if (VD && (VD->isBlockVarDecl() || isa(VD) || isa(VD))) { - if (VD->getStorageClass() == VarDecl::Extern) - return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), - E->getType().getCVRQualifiers()); + LValue LV; + if (VD->getStorageClass() == VarDecl::Extern) { + LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), + E->getType().getCVRQualifiers()); + } else { llvm::Value *V = LocalDeclMap[VD]; assert(V && "BlockVarDecl not entered in LocalDeclMap?"); - return LValue::MakeAddr(V, E->getType().getCVRQualifiers()); + LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers()); } + if (VD->isBlockVarDecl() && + (VD->getStorageClass() == VarDecl::Static || + VD->getStorageClass() == VarDecl::Extern)) + SetVarDeclObjCAttribute(VD, E->getType(), LV); + return LV; } else if (VD && VD->isFileVarDecl()) { LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), E->getType().getCVRQualifiers()); - if (const ObjCGCAttr *A = VD->getAttr()) { - ObjCGCAttr::GCAttrTypes attrType = A->getType(); - LValue::SetObjCType(attrType == ObjCGCAttr::Weak, attrType == ObjCGCAttr::Strong, LV); - } - else if (CGM.getLangOptions().ObjC1 && - CGM.getLangOptions().getGCMode() != LangOptions::NonGC) { - QualType ExprTy = E->getType(); - if (getContext().isObjCObjectPointerType(ExprTy)) - LValue::SetObjCType(false, true, LV); - } + SetVarDeclObjCAttribute(VD, E->getType(), LV); return LV; } else if (const FunctionDecl *FD = dyn_cast(E->getDecl())) { return LValue::MakeAddr(CGM.GetAddrOfFunction(FD), @@ -767,7 +782,7 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, Field->getType()->isSignedIntegerType(), Field->getType().getCVRQualifiers()|CVRQualifiers); } - + V = Builder.CreateStructGEP(BaseValue, idx, "tmp"); // Match union field type. @@ -782,8 +797,21 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, "tmp"); } - return LValue::MakeAddr(V, - Field->getType().getCVRQualifiers()|CVRQualifiers); + LValue LV = + LValue::MakeAddr(V, + Field->getType().getCVRQualifiers()|CVRQualifiers); + if (const ObjCGCAttr *A = Field->getAttr()) { + ObjCGCAttr::GCAttrTypes attrType = A->getType(); + // __weak attribute on a field is ignored. + LValue::SetObjCType(false, attrType == ObjCGCAttr::Strong, LV); + } + else if (CGM.getLangOptions().ObjC1 && + CGM.getLangOptions().getGCMode() != LangOptions::NonGC) { + QualType ExprTy = Field->getType(); + if (getContext().isObjCObjectPointerType(ExprTy)) + LValue::SetObjCType(false, true, LV); + } + return LV; } LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E) diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 05b2793456..1da4e195ba 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -462,7 +462,8 @@ public: LValue EmitBinaryOperatorLValue(const BinaryOperator *E); // Note: only availabe for agg return types LValue EmitCallExprLValue(const CallExpr *E); - + void SetVarDeclObjCAttribute(const VarDecl *VD, const QualType &Ty, + LValue &LV); LValue EmitDeclRefLValue(const DeclRefExpr *E); LValue EmitStringLiteralLValue(const StringLiteral *E); LValue EmitPredefinedFunctionName(unsigned Type); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 4bf55dd7f0..57d1cc7fa0 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -555,8 +555,11 @@ static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { ObjCGCAttr::GCAttrTypes type; - if (Attr.getParameterName()->isName("weak")) + if (Attr.getParameterName()->isName("weak")) { + if (isa(d)) + S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field); type = ObjCGCAttr::Weak; + } else if (Attr.getParameterName()->isName("strong")) type = ObjCGCAttr::Strong; else {