Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit aa59bd4

Browse files
committed
Support attributes for Objective-C categories
rdar://31095315 Differential Revision: https://reviews.llvm.org/D31179 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@298589 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 50a5909 commit aa59bd4

File tree

8 files changed

+57
-26
lines changed

8 files changed

+57
-26
lines changed

include/clang/Basic/DiagnosticParseKinds.td

-2
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,6 @@ def ext_decomp_decl_empty : ExtWarn<
364364
/// Objective-C parser diagnostics
365365
def err_expected_minus_or_plus : Error<
366366
"method type specifier must start with '-' or '+'">;
367-
def err_objc_no_attributes_on_category : Error<
368-
"attributes may not be specified on a category">;
369367
def err_objc_missing_end : Error<"missing '@end'">;
370368
def note_objc_container_start : Note<
371369
"%select{class|protocol|category|class extension|implementation"

include/clang/Sema/Sema.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -7666,7 +7666,8 @@ class Sema {
76667666
Decl * const *ProtoRefs,
76677667
unsigned NumProtoRefs,
76687668
const SourceLocation *ProtoLocs,
7669-
SourceLocation EndProtoLoc);
7669+
SourceLocation EndProtoLoc,
7670+
AttributeList *AttrList);
76707671

76717672
Decl *ActOnStartClassImplementation(
76727673
SourceLocation AtClassImplLoc,

lib/Parse/ParseObjc.cpp

+5-15
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,6 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
278278
T.consumeClose();
279279
if (T.getCloseLocation().isInvalid())
280280
return nullptr;
281-
282-
if (!attrs.empty()) { // categories don't support attributes.
283-
Diag(nameLoc, diag::err_objc_no_attributes_on_category);
284-
attrs.clear();
285-
}
286281

287282
// Next, we need to check for any protocol references.
288283
assert(LAngleLoc.isInvalid() && "Cannot have already parsed protocols");
@@ -294,16 +289,11 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
294289
/*consumeLastToken=*/true))
295290
return nullptr;
296291

297-
Decl *CategoryType =
298-
Actions.ActOnStartCategoryInterface(AtLoc,
299-
nameId, nameLoc,
300-
typeParameterList,
301-
categoryId, categoryLoc,
302-
ProtocolRefs.data(),
303-
ProtocolRefs.size(),
304-
ProtocolLocs.data(),
305-
EndProtoLoc);
306-
292+
Decl *CategoryType = Actions.ActOnStartCategoryInterface(
293+
AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
294+
ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
295+
EndProtoLoc, attrs.getList());
296+
307297
if (Tok.is(tok::l_brace))
308298
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
309299

lib/Sema/SemaDeclObjC.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S,
258258
S.Diag(ND->getLocation(), diag::note_method_declared_at)
259259
<< ND->getDeclName();
260260
else
261-
S.Diag(ND->getLocation(), diag::note_previous_decl) << "class";
261+
S.Diag(ND->getLocation(), diag::note_previous_decl)
262+
<< (isa<ObjCCategoryDecl>(ND) ? "category" : "class");
262263
}
263264
}
264265

@@ -1724,7 +1725,8 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
17241725
Decl * const *ProtoRefs,
17251726
unsigned NumProtoRefs,
17261727
const SourceLocation *ProtoLocs,
1727-
SourceLocation EndProtoLoc) {
1728+
SourceLocation EndProtoLoc,
1729+
AttributeList *AttrList) {
17281730
ObjCCategoryDecl *CDecl;
17291731
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
17301732

@@ -1801,6 +1803,9 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
18011803
NumProtoRefs, Context);
18021804
}
18031805

1806+
if (AttrList)
1807+
ProcessDeclAttributeList(TUScope, CDecl, AttrList);
1808+
18041809
CheckObjCDeclScope(CDecl);
18051810
return ActOnObjCContainerStartDefinition(CDecl);
18061811
}
@@ -1865,9 +1870,10 @@ Decl *Sema::ActOnStartCategoryImplementation(
18651870
CatIDecl->setImplementation(CDecl);
18661871
// Warn on implementating category of deprecated class under
18671872
// -Wdeprecated-implementations flag.
1868-
DiagnoseObjCImplementedDeprecations(*this,
1869-
dyn_cast<NamedDecl>(IDecl),
1870-
CDecl->getLocation(), 2);
1873+
DiagnoseObjCImplementedDeprecations(
1874+
*this,
1875+
CatIDecl->isDeprecated() ? CatIDecl : dyn_cast<NamedDecl>(IDecl),
1876+
CDecl->getLocation(), 2);
18711877
}
18721878
}
18731879

test/SemaObjC/attr-deprecated.m

+7-1
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,15 @@ void test(Test2 *foo) {
121121
}
122122

123123
__attribute__((deprecated))
124-
@interface A(Blah) // expected-error{{attributes may not be specified on a category}}
124+
@interface A(Blah) // no warning
125+
- (A*)getA;
125126
@end
126127

128+
@implementation A(Blah) // Don't warn by default
129+
- (A*)getA {
130+
return self;
131+
}
132+
@end
127133

128134
typedef struct {
129135
int x;

test/SemaObjC/category-attribute.m

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
3+
// expected-no-diagnostics
4+
5+
__attribute__ ((external_source_symbol(language= "Swift", defined_in="A")))
6+
@interface TestInterface
7+
@end
8+
// CHECK: ObjCInterfaceDecl {{.*}} TestInterface
9+
// CHECK-NEXT: ExternalSourceSymbolAttr
10+
11+
__attribute__ ((external_source_symbol(language= "Swift", defined_in="B")))
12+
@interface TestInterface ()
13+
@end
14+
// CHECK: ObjCCategoryDecl
15+
// CHECK-NEXT: ObjCInterface
16+
// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "B"
17+
18+
__attribute__ ((external_source_symbol(language= "Swift", defined_in="C")))
19+
@interface TestInterface (Category)
20+
@end
21+
// CHECK: ObjCCategoryDecl
22+
// CHECK-NEXT: ObjCInterface
23+
// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "C"

test/SemaObjC/default-synthesize-3.m

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ @implementation Deep // expected-warning {{property 'DeepMustSynthProperty' requ
3333
- (id) DeepMustSynthProperty { return 0; }
3434
@end
3535

36-
__attribute ((objc_requires_property_definitions))
37-
@interface Deep(CAT) // expected-error {{attributes may not be specified on a category}}
36+
__attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}}
37+
@interface Deep(CAT)
3838
@end
3939

4040
__attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}}

test/SemaObjC/warn-deprecated-implementations.m

+7
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,10 @@ - (id)initSpecialInPrivateHeader {
6565
return (void *)0;
6666
}
6767
@end
68+
69+
__attribute__((deprecated))
70+
@interface Test(DeprecatedCategory) // expected-note {{category declared here}}
71+
@end
72+
73+
@implementation Test(DeprecatedCategory) // expected-warning {{Implementing deprecated category}}
74+
@end

0 commit comments

Comments
 (0)