summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2008-11-26 20:01:34 +0000
committerFariborz Jahanian <fjahanian@apple.com>2008-11-26 20:01:34 +0000
commitf8ef9f3dc9e8ceadd3772052624a455bbbfb0ffb (patch)
treef69c3e204f3a473e2ae4bd47a23103df2819a44c /clang
parent6e41adddabbd28bb6d0f7baeef1eade960237b9f (diff)
downloadbcm5719-llvm-f8ef9f3dc9e8ceadd3772052624a455bbbfb0ffb.tar.gz
bcm5719-llvm-f8ef9f3dc9e8ceadd3772052624a455bbbfb0ffb.zip
Set default property attributes on each property.
Implemented anonymous category (also know as continuation class) used to override main class's property attribute. This is work in propgress. llvm-svn: 60114
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclObjC.h5
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def6
-rw-r--r--clang/include/clang/Parse/Action.h2
-rw-r--r--clang/lib/Parse/ParseObjc.cpp6
-rw-r--r--clang/lib/Sema/Sema.h1
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp79
-rw-r--r--clang/test/CodeGenObjC/continuation-class.m35
-rw-r--r--clang/test/SemaObjC/property-9-impl-method.m1
8 files changed, 129 insertions, 6 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index b52400ab9f6..eda3e6db7df 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1228,6 +1228,11 @@ public:
PropertyAttributes |= PRVal;
}
+ void makeitReadWriteAttribute(void) {
+ PropertyAttributes &= ~OBJC_PR_readonly;
+ PropertyAttributes |= OBJC_PR_readwrite;
+ }
+
// Helper methods for accessing attributes.
/// isReadOnly - Return true iff the property has a setter.
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
index 6e7e58e61d2..a9694fa608a 100644
--- a/clang/include/clang/Basic/DiagnosticKinds.def
+++ b/clang/include/clang/Basic/DiagnosticKinds.def
@@ -563,6 +563,12 @@ DIAG(warn_property_attribute, WARNING,
"property %0 '%1' attribute does not match the property inherited from %2")
DIAG(warn_property_type, WARNING,
"property type %0 does not match property type inherited from %1")
+DIAG(err_continuation_class, ERROR,
+ "continuation class has no primary class")
+DIAG(err_use_continuation_class, ERROR,
+ "use contination class to override 'readonly' property with 'readwrite'")
+DIAG(warn_property_attr_mismatch, WARNING,
+ "property attribute in continuation class does not match the primary class")
/// C++ parser diagnostics
DIAG(err_expected_unqualified_id, ERROR,
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h
index 3058ce3aba4..e32dc388fc7 100644
--- a/clang/include/clang/Parse/Action.h
+++ b/clang/include/clang/Parse/Action.h
@@ -963,6 +963,8 @@ public:
virtual DeclTy *ActOnProperty (Scope *S, SourceLocation AtLoc,
FieldDeclarator &FD, ObjCDeclSpec &ODS,
Selector GetterSel, Selector SetterSel,
+ DeclTy *ClassCategory,
+ bool *OverridingProperty,
tok::ObjCKeywordKind MethodImplKind) {
return 0;
}
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 9fe4c1ec12e..f937ef1d9c0 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -332,10 +332,14 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
FD.D.getIdentifier());
Selector SetterSel =
PP.getSelectorTable().getUnarySelector(SetterName);
+ bool isOverridingProperty = false;
DeclTy *Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS,
GetterSel, SetterSel,
+ interfaceDecl,
+ &isOverridingProperty,
MethodImplKind);
- allProperties.push_back(Property);
+ if (!isOverridingProperty)
+ allProperties.push_back(Property);
}
break;
}
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index c8352172f9a..614e4873bac 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -1051,6 +1051,7 @@ public:
virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
FieldDeclarator &FD, ObjCDeclSpec &ODS,
Selector GetterSel, Selector SetterSel,
+ DeclTy *ClassCategory, bool *OverridingProperty,
tok::ObjCKeywordKind MethodImplKind);
virtual DeclTy *ActOnPropertyImplDecl(SourceLocation AtLoc,
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 95737af18ac..9f37e900cdf 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -1186,12 +1186,81 @@ Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
ObjCDeclSpec &ODS,
Selector GetterSel,
Selector SetterSel,
+ DeclTy *ClassCategory,
+ bool *isOverridingProperty,
tok::ObjCKeywordKind MethodImplKind) {
- QualType T = GetTypeForDeclarator(FD.D, S);
unsigned Attributes = ODS.getPropertyAttributes();
+ bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
+ // default is readwrite!
+ !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
+ // property is defaulted to 'assign' if it is readwrite and is
+ // not retain or copy
+ bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
+ (isReadWrite &&
+ !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
+ !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
+ QualType T = GetTypeForDeclarator(FD.D, S);
+ Decl *ClassDecl = static_cast<Decl *>(ClassCategory);
// May modify Attributes.
CheckObjCPropertyAttributes(T, AtLoc, Attributes);
+
+ if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
+ if (!CDecl->getIdentifier()) {
+ // This is an anonymous category. property requires special
+ // handling.
+ if (ObjCInterfaceDecl *ICDecl = CDecl->getClassInterface()) {
+ if (ObjCPropertyDecl *PIDecl =
+ ICDecl->FindPropertyDeclaration(FD.D.getIdentifier())) {
+ // property 'PIDecl's readonly attribute will be over-ridden
+ // with anonymous category's readwrite property attribute!
+ unsigned PIkind = PIDecl->getPropertyAttributes();
+ if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
+ if ((Attributes & ObjCPropertyDecl::OBJC_PR_retain) !=
+ (PIkind & ObjCPropertyDecl::OBJC_PR_retain) ||
+ (Attributes & ObjCPropertyDecl::OBJC_PR_copy) !=
+ (PIkind & ObjCPropertyDecl::OBJC_PR_copy) ||
+ (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) !=
+ (PIkind & ObjCPropertyDecl::OBJC_PR_nonatomic))
+ Diag(AtLoc, diag::warn_property_attr_mismatch);
+ PIDecl->makeitReadWriteAttribute();
+ if (Attributes & ObjCDeclSpec::DQ_PR_retain)
+ PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
+ if (Attributes & ObjCDeclSpec::DQ_PR_copy)
+ PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
+ PIDecl->setSetterName(SetterSel);
+ // FIXME: use a common routine with addPropertyMethods.
+ ObjCMethodDecl *SetterDecl =
+ ObjCMethodDecl::Create(Context, AtLoc, AtLoc, SetterSel,
+ Context.VoidTy,
+ ICDecl,
+ true, false, true,
+ ObjCMethodDecl::Required);
+ ParmVarDecl *Argument = ParmVarDecl::Create(Context,
+ SetterDecl,
+ SourceLocation(),
+ FD.D.getIdentifier(),
+ T,
+ VarDecl::None,
+ 0, 0);
+ SetterDecl->setMethodParams(&Argument, 1);
+ PIDecl->setSetterMethodDecl(SetterDecl);
+ }
+ else
+ Diag(AtLoc, diag::err_use_continuation_class);
+ *isOverridingProperty = true;
+ return 0;
+ }
+ // else
+ // FIXME:
+ // no matching property found in the main class. Must simply
+ // add this property to the main class's property list.
+ } else {
+ Diag(CDecl->getLocation(), diag::err_continuation_class);
+ *isOverridingProperty = true;
+ return 0;
+ }
+ }
ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, AtLoc,
FD.D.getIdentifier(), T);
@@ -1209,10 +1278,7 @@ Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
if (Attributes & ObjCDeclSpec::DQ_PR_setter)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
- if (Attributes & ObjCDeclSpec::DQ_PR_assign)
- PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
-
- if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
+ if (isReadWrite)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
if (Attributes & ObjCDeclSpec::DQ_PR_retain)
@@ -1221,6 +1287,9 @@ Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
if (Attributes & ObjCDeclSpec::DQ_PR_copy)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
+ if (isAssign)
+ PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
+
if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
diff --git a/clang/test/CodeGenObjC/continuation-class.m b/clang/test/CodeGenObjC/continuation-class.m
new file mode 100644
index 00000000000..9ac51c70bf0
--- /dev/null
+++ b/clang/test/CodeGenObjC/continuation-class.m
@@ -0,0 +1,35 @@
+// RUN: clang -fnext-runtime --emit-llvm -o %t %s
+
+@interface Object
+- (id)new;
+@end
+
+@interface ReadOnly : Object
+{
+ int _object;
+ int _Anotherobject;
+}
+@property(readonly) int object;
+@property(readonly) int Anotherobject;
+@end
+
+@interface ReadOnly ()
+@property(readwrite) int object;
+@property(readwrite, setter = myAnotherobjectSetter:) int Anotherobject;
+@end
+
+@implementation ReadOnly
+@synthesize object = _object;
+@synthesize Anotherobject = _Anotherobject;
+- (void) myAnotherobjectSetter : (int)val {
+ _Anotherobject = val;
+}
+@end
+
+int main(int argc, char **argv) {
+ ReadOnly *test = [ReadOnly new];
+ test.object = 12345;
+ test.Anotherobject = 200;
+ return test.object - 12345 + test.Anotherobject - 200;
+}
+
diff --git a/clang/test/SemaObjC/property-9-impl-method.m b/clang/test/SemaObjC/property-9-impl-method.m
index bb13d01b74a..e9e81bd55f5 100644
--- a/clang/test/SemaObjC/property-9-impl-method.m
+++ b/clang/test/SemaObjC/property-9-impl-method.m
@@ -60,4 +60,5 @@ NSSize minimumSize;
NSRect dummy, result = {};
NSDivideRect(self.bounds, &result, &dummy, self.tabAreaThickness, self.rectEdgeForTabs);
}
+@end
OpenPOWER on IntegriCloud