aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2008-11-20 00:15:42 +0000
committerFariborz Jahanian <fjahanian@apple.com>2008-11-20 00:15:42 +0000
commit2682d8b3a0415d521d5ca11afb13a8bc5c559a31 (patch)
tree3b7fed35f05db16b71b1d20356820801d3f59285
parent9ebae31a97f862771dc5f6bd4923dd97131fed71 (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--lib/CodeGen/CGExpr.cpp62
-rw-r--r--lib/CodeGen/CodeGenFunction.h3
-rw-r--r--lib/Sema/SemaDeclAttr.cpp5
4 files changed, 53 insertions, 19 deletions
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>()) {
+ 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)
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<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 {