]> granicus.if.org Git - clang/commitdiff
More objc gc stuff. Read/Write barriers for local static/extern,
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 20 Nov 2008 00:15:42 +0000 (00:15 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 20 Nov 2008 00:15:42 +0000 (00:15 +0000)
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

include/clang/Basic/DiagnosticKinds.def
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
lib/Sema/SemaDeclAttr.cpp

index 2b15f5d1f5fa9a4a9bf749569f33bac6bffd4d0a..0f7282799f8811afc2a5da7b9cf095a5ae81706a 100644 (file)
@@ -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,
index 9e4d66a9478145e142a39695b207cbba8b236d8c..4228bc22b6ff849ec4427fbfdc735eec4575828b 100644 (file)
@@ -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>()) {
+    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<VarDecl>(E->getDecl());
   
   if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD) ||
         isa<ImplicitParamDecl>(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>()) {
-      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<FunctionDecl>(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>()) {
+    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)
index 05b2793456bc7ac0b5f752148b9cf03b93978c1c..1da4e195ba80700fadd5a35c7b246519c50e3cd5 100644 (file)
@@ -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);
index 4bf55dd7f01440176592192d1c257c5c7f49c2f2..57d1cc7fa0b3b4999a14cd5b0fbe9c346896ac68 100644 (file)
@@ -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<FieldDecl>(d))
+      S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field);
     type = ObjCGCAttr::Weak;
+  }
   else if (Attr.getParameterName()->isName("strong"))
     type = ObjCGCAttr::Strong;
   else {