Thank you for indulging me. :-) ~Aaron
On Thu, Sep 19, 2013 at 1:22 PM, jahanian <[email protected]> wrote: > > On Sep 19, 2013, at 9:46 AM, Aaron Ballman <[email protected]> wrote: > > On Thu, Sep 19, 2013 at 12:37 PM, Fariborz Jahanian <[email protected]> > wrote: > > Author: fjahanian > Date: Thu Sep 19 11:37:20 2013 > New Revision: 191009 > > URL: http://llvm.org/viewvc/llvm-project?rev=191009&view=rev > Log: > ObjectiveC: Allow NS_RETURNS_INNER_POINTER annotation > of ObjectiveC properties to mean annotation of > NS_RETURNS_INNER_POINTER on its synthesized getter. > This also facilitates more migration to properties when > methods are annotated with NS_RETURNS_INNER_POINTER. > // rdar://14990439 > > Modified: > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/Sema/SemaDeclAttr.cpp > cfe/trunk/lib/Sema/SemaObjCProperty.cpp > cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m > cfe/trunk/test/SemaObjC/arc-property-lifetime.m > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=191009&r1=191008&r2=191009&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 19 11:37:20 > 2013 > @@ -2027,7 +2027,8 @@ def err_attribute_wrong_decl_type : Erro > "variables, functions and labels|fields and global variables|structs|" > "variables, functions and tag types|thread-local variables|" > "variables and fields|variables, data members and tag types|" > - "types and namespaces|Objective-C interfaces}1">; > + "types and namespaces|Objective-C interfaces|" > + "methods and properties}1">; > def warn_type_attribute_wrong_type : Warning< > "'%0' only applies to %select{function|pointer|" > "Objective-C object or block pointer}1 types; type here is %2">, > @@ -2395,7 +2396,7 @@ def note_attribute_overloadable_prev_ove > def err_attribute_overloadable_no_prototype : Error< > "'overloadable' function %0 must have a prototype">; > def warn_ns_attribute_wrong_return_type : Warning< > - "%0 attribute only applies to %select{functions|methods}1 that " > + "%0 attribute only applies to %select{functions|methods|properties}1 that > " > "return %select{an Objective-C object|a pointer|a non-retainable > pointer}2">, > InGroup<IgnoredAttributes>; > def warn_ns_attribute_wrong_parameter_type : Warning< > > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=191009&r1=191008&r2=191009&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Sep 19 11:37:20 2013 > @@ -54,7 +54,8 @@ enum AttributeDeclKind { > ExpectedVariableOrField, > ExpectedVariableFieldOrTag, > ExpectedTypeOrNamespace, > - ExpectedObjectiveCInterface > + ExpectedObjectiveCInterface, > + ExpectedMethodOrProperty > }; > > //===----------------------------------------------------------------------===// > @@ -1476,7 +1477,7 @@ static void handleOwnershipAttr(Sema &S, > break; > } > if (-1 != Err) { > - S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err > + S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err > << Ex->getSourceRange(); > return; > } > @@ -4145,29 +4146,34 @@ static void handleNSReturnsRetainedAttr( > static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, > const AttributeList &attr) { > SourceLocation loc = attr.getLoc(); > - > + QualType resultType; > + > ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); > > if (!method) { > - S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) > - << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; > - return; > + ObjCPropertyDecl *property = dyn_cast<ObjCPropertyDecl>(D); > + if (!property) { > + S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) > + << SourceRange(loc, loc) << attr.getName() << > ExpectedMethodOrProperty; > + return; > + } > + resultType = property->getType(); > > > Please update the subjects in Attr.td for this attribute so it stays > in sync with what the semantics are checking for. > > } > + else > + // Check that the method returns a normal pointer. > + resultType = method->getResultType(); > > - // Check that the method returns a normal pointer. > - QualType resultType = method->getResultType(); > - > if (!resultType->isReferenceType() && > (!resultType->isPointerType() || resultType->isObjCRetainableType())) > { > - S.Diag(method->getLocStart(), > diag::warn_ns_attribute_wrong_return_type) > + S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) > << SourceRange(loc) > - << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; > + << attr.getName() << (method ? /*method*/ 1 : /*property*/ 2) << > /*non-retainable pointer*/ 2; > > > A local enumeration would be better than comments, but meh. > > > // Drop the attribute. > return; > } > > - method->addAttr(::new (S.Context) > + D->addAttr(::new (S.Context) > ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context, > > attr.getAttributeSpellingListIndex())); > } > > Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=191009&r1=191008&r2=191009&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original) > +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Thu Sep 19 11:37:20 2013 > @@ -1943,6 +1943,10 @@ void Sema::ProcessPropertyDecl(ObjCPrope > if (property->hasAttr<NSReturnsNotRetainedAttr>()) > GetterMethod->addAttr( > ::new (Context) NSReturnsNotRetainedAttr(Loc, Context)); > + > + if (property->hasAttr<ObjCReturnsInnerPointerAttr>()) > + GetterMethod->addAttr( > + ::new (Context) ObjCReturnsInnerPointerAttr(Loc, Context)); > > if (getLangOpts().ObjCAutoRefCount) > CheckARCMethodDecl(GetterMethod); > > Modified: cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m?rev=191009&r1=191008&r2=191009&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m (original) > +++ cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m Thu Sep 19 11:37:20 > 2013 > @@ -25,7 +25,8 @@ void test0() { > // rdar://problem/9821110 > @interface Test1 > - (char*) interior __attribute__((objc_returns_inner_pointer)); > -// Should we allow this on properties? > +// Should we allow this on properties? Yes! see // rdar://14990439 > +@property (nonatomic, readonly) char * PropertyReturnsInnerPointer > __attribute__((objc_returns_inner_pointer)); > @end > extern Test1 *test1_helper(void); > > @@ -73,6 +74,50 @@ void test1b(void) { > char *c = [ptr interior]; > } > > +void test1c(void) { > + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() > + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* > + // CHECK-NEXT: [[T2:%.*]] = call i8* > @objc_retainAutoreleasedReturnValue(i8* [[T1]]) > + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* > + // CHECK-NEXT: store [[TEST1]]* [[T3]] > + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** > + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* > + // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) > + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* > + // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ > + // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* > + // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast > + // CHECK-NEXT: store i8* [[T6]], i8** > + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** > + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* > + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], > !clang.imprecise_release > + // CHECK-NEXT: ret void > + Test1 *ptr = test1_helper(); > + char *pc = ptr.PropertyReturnsInnerPointer; > +} > + > +void test1d(void) { > + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() > + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* > + // CHECK-NEXT: [[T2:%.*]] = call i8* > @objc_retainAutoreleasedReturnValue(i8* [[T1]]) > + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* > + // CHECK-NEXT: store [[TEST1]]* [[T3]] > + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** > + // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* > + // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease > + // CHECK-NEXT: [[SIX:%.*]] = bitcast i8* [[T3]] to [[TEST1]]* > + // CHECK-NEXT: [[SEVEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ > + // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[SIX]] to i8* > + // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* > @objc_msgSend to i8* (i8*, i8*)*)(i8* [[EIGHT]], i8* [[SEVEN]]) > + // CHECK-NEXT: store i8* [[CALL1]], i8** > + // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]** > + // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8* > + // CHECK-NEXT: call void @objc_release(i8* [[TEN]]) > + // CHECK-NEXT: ret void > + __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper(); > + char *pc = ptr.PropertyReturnsInnerPointer; > +} > + > @interface Test2 { > @public > id ivar; > > Modified: cfe/trunk/test/SemaObjC/arc-property-lifetime.m > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-property-lifetime.m?rev=191009&r1=191008&r2=191009&view=diff > ============================================================================== > --- cfe/trunk/test/SemaObjC/arc-property-lifetime.m (original) > +++ cfe/trunk/test/SemaObjC/arc-property-lifetime.m Thu Sep 19 11:37:20 2013 > @@ -171,7 +171,10 @@ void foo(Baz *f) { > > // rdar://11253688 > @interface Boom > -@property (readonly) const void * innerPointer > __attribute__((objc_returns_inner_pointer)); // expected-error > {{'objc_returns_inner_pointer' attribute only applies to methods}} > +{ > + const void * innerPointerIvar > __attribute__((objc_returns_inner_pointer)); // expected-error > {{'objc_returns_inner_pointer' attribute only applies to methods and > properties}} > +} > +@property (readonly) const void * innerPointer > __attribute__((objc_returns_inner_pointer)); > @end > > @interface Foo2 { > > > Missing test cases for the changes in SemaDeclAttr.cpp; please add. > > > Sure. In r191016. > - Fariborz > > > Thanks! > > ~Aaron > > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
