]> granicus.if.org Git - clang/commitdiff
Allow the NS, CF, and ObjC attributes to be used with -fdouble-square-bracket-attribu...
authorAaron Ballman <aaron@aaronballman.com>
Mon, 12 Feb 2018 13:38:25 +0000 (13:38 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Mon, 12 Feb 2018 13:38:25 +0000 (13:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324890 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
include/clang/Parse/Parser.h
lib/Parse/ParseObjc.cpp
lib/Parse/Parser.cpp
test/Misc/ast-dump-attr.m [new file with mode: 0644]
test/Parser/objc-attr.m [new file with mode: 0644]

index 651132a86d6121b2e15625ce0fecb1f98e2cfdf7..c3a4d4b058bfcc920ad7963d0e6bdaff90fa3170 100644 (file)
@@ -754,7 +754,7 @@ def CDecl : InheritableAttr {
 // cf_returns_retained attributes.  It is generally applied by
 // '#pragma clang arc_cf_code_audited' rather than explicitly.
 def CFAuditedTransfer : InheritableAttr {
-  let Spellings = [Clang<"cf_audited_transfer">];
+  let Spellings = [Clang<"cf_audited_transfer", 1>];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [Undocumented];
 }
@@ -763,25 +763,25 @@ def CFAuditedTransfer : InheritableAttr {
 // It indicates that the function has unknown or unautomatable
 // transfer semantics.
 def CFUnknownTransfer : InheritableAttr {
-  let Spellings = [Clang<"cf_unknown_transfer">];
+  let Spellings = [Clang<"cf_unknown_transfer", 1>];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def CFReturnsRetained : InheritableAttr {
-  let Spellings = [Clang<"cf_returns_retained">];
+  let Spellings = [Clang<"cf_returns_retained", 1>];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
   let Documentation = [Undocumented];
 }
 
 def CFReturnsNotRetained : InheritableAttr {
-  let Spellings = [Clang<"cf_returns_not_retained">];
+  let Spellings = [Clang<"cf_returns_not_retained", 1>];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
   let Documentation = [Undocumented];
 }
 
 def CFConsumed : InheritableParamAttr {
-  let Spellings = [Clang<"cf_consumed">];
+  let Spellings = [Clang<"cf_consumed", 1>];
   let Subjects = SubjectList<[ParmVar]>;
   let Documentation = [Undocumented];
 }
@@ -1118,7 +1118,7 @@ def Hot : InheritableAttr {
 }
 
 def IBAction : InheritableAttr {
-  let Spellings = [Clang<"ibaction">];
+  let Spellings = [Clang<"ibaction", 1>];
   let Subjects = SubjectList<[ObjCInstanceMethod]>;
   // An AST node is created for this attribute, but is not used by other parts
   // of the compiler. However, this node needs to exist in the AST because
@@ -1127,13 +1127,13 @@ def IBAction : InheritableAttr {
 }
 
 def IBOutlet : InheritableAttr {
-  let Spellings = [Clang<"iboutlet">];
+  let Spellings = [Clang<"iboutlet", 1>];
 //  let Subjects = [ObjCIvar, ObjCProperty];
   let Documentation = [Undocumented];
 }
 
 def IBOutletCollection : InheritableAttr {
-  let Spellings = [Clang<"iboutletcollection">];
+  let Spellings = [Clang<"iboutletcollection", 1>];
   let Args = [TypeArgument<"Interface", 1>];
 //  let Subjects = [ObjCIvar, ObjCProperty];
   let Documentation = [Undocumented];
@@ -1428,7 +1428,7 @@ def ObjCKindOf : TypeAttr {
 }
 
 def NoEscape : Attr {
-  let Spellings = [Clang<"noescape">];
+  let Spellings = [Clang<"noescape", 1>];
   let Subjects = SubjectList<[ParmVar]>;
   let Documentation = [NoEscapeDocs];
 }
@@ -1480,14 +1480,14 @@ def NvWeak : IgnoredAttr {
 }
 
 def ObjCBridge : InheritableAttr {
-  let Spellings = [Clang<"objc_bridge">];
+  let Spellings = [Clang<"objc_bridge", 1>];
   let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>;
   let Args = [IdentifierArgument<"BridgedType">];
   let Documentation = [Undocumented];
 }
 
 def ObjCBridgeMutable : InheritableAttr {
-  let Spellings = [Clang<"objc_bridge_mutable">];
+  let Spellings = [Clang<"objc_bridge_mutable", 1>];
   let Subjects = SubjectList<[Record], ErrorDiag>;
   let Args = [IdentifierArgument<"BridgedType">];
   let Documentation = [Undocumented];
@@ -1506,43 +1506,43 @@ def ObjCBridgeRelated : InheritableAttr {
 }
 
 def NSReturnsRetained : InheritableAttr {
-  let Spellings = [Clang<"ns_returns_retained">];
+  let Spellings = [Clang<"ns_returns_retained", 1>];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
   let Documentation = [Undocumented];
 }
 
 def NSReturnsNotRetained : InheritableAttr {
-  let Spellings = [Clang<"ns_returns_not_retained">];
+  let Spellings = [Clang<"ns_returns_not_retained", 1>];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
   let Documentation = [Undocumented];
 }
 
 def NSReturnsAutoreleased : InheritableAttr {
-  let Spellings = [Clang<"ns_returns_autoreleased">];
+  let Spellings = [Clang<"ns_returns_autoreleased", 1>];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
   let Documentation = [Undocumented];
 }
 
 def NSConsumesSelf : InheritableAttr {
-  let Spellings = [Clang<"ns_consumes_self">];
+  let Spellings = [Clang<"ns_consumes_self", 1>];
   let Subjects = SubjectList<[ObjCMethod]>;
   let Documentation = [Undocumented];
 }
 
 def NSConsumed : InheritableParamAttr {
-  let Spellings = [Clang<"ns_consumed">];
+  let Spellings = [Clang<"ns_consumed", 1>];
   let Subjects = SubjectList<[ParmVar]>;
   let Documentation = [Undocumented];
 }
 
 def ObjCException : InheritableAttr {
-  let Spellings = [Clang<"objc_exception">];
+  let Spellings = [Clang<"objc_exception", 1>];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCMethodFamily : InheritableAttr {
-  let Spellings = [Clang<"objc_method_family">];
+  let Spellings = [Clang<"objc_method_family", 1>];
   let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
   let Args = [EnumArgument<"Family", "FamilyKind",
                ["none", "alloc", "copy", "init", "mutableCopy", "new"],
@@ -1552,72 +1552,72 @@ def ObjCMethodFamily : InheritableAttr {
 }
 
 def ObjCNSObject : InheritableAttr {
-  let Spellings = [Clang<"NSObject">];
+  let Spellings = [Clang<"NSObject", 1>];
   let Documentation = [Undocumented];
 }
 
 def ObjCIndependentClass : InheritableAttr {
-  let Spellings = [Clang<"objc_independent_class">];
+  let Spellings = [Clang<"objc_independent_class", 1>];
   let Documentation = [Undocumented];
 }
 
 def ObjCPreciseLifetime : InheritableAttr {
-  let Spellings = [Clang<"objc_precise_lifetime">];
+  let Spellings = [Clang<"objc_precise_lifetime", 1>];
   let Subjects = SubjectList<[Var], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCReturnsInnerPointer : InheritableAttr {
-  let Spellings = [Clang<"objc_returns_inner_pointer">];
+  let Spellings = [Clang<"objc_returns_inner_pointer", 1>];
   let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCRequiresSuper : InheritableAttr {
-  let Spellings = [Clang<"objc_requires_super">];
+  let Spellings = [Clang<"objc_requires_super", 1>];
   let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
   let Documentation = [ObjCRequiresSuperDocs];
 }
 
 def ObjCRootClass : InheritableAttr {
-  let Spellings = [Clang<"objc_root_class">];
+  let Spellings = [Clang<"objc_root_class", 1>];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCSubclassingRestricted : InheritableAttr {
-  let Spellings = [Clang<"objc_subclassing_restricted">];
+  let Spellings = [Clang<"objc_subclassing_restricted", 1>];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
   let Documentation = [ObjCSubclassingRestrictedDocs];
 }
 
 def ObjCExplicitProtocolImpl : InheritableAttr {
-  let Spellings = [Clang<"objc_protocol_requires_explicit_implementation">];
+  let Spellings = [Clang<"objc_protocol_requires_explicit_implementation", 1>];
   let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCDesignatedInitializer : Attr {
-  let Spellings = [Clang<"objc_designated_initializer">];
+  let Spellings = [Clang<"objc_designated_initializer", 1>];
   let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCRuntimeName : Attr {
-  let Spellings = [Clang<"objc_runtime_name">];
+  let Spellings = [Clang<"objc_runtime_name", 1>];
   let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
   let Args = [StringArgument<"MetadataName">];
   let Documentation = [ObjCRuntimeNameDocs];
 }
 
 def ObjCRuntimeVisible : Attr {
-  let Spellings = [Clang<"objc_runtime_visible">];
+  let Spellings = [Clang<"objc_runtime_visible", 1>];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
   let Documentation = [ObjCRuntimeVisibleDocs];
 }
 
 def ObjCBoxable : Attr {
-  let Spellings = [Clang<"objc_boxable">];
+  let Spellings = [Clang<"objc_boxable", 1>];
   let Subjects = SubjectList<[Record], ErrorDiag>;
   let Documentation = [ObjCBoxableDocs];
 }
@@ -1950,26 +1950,26 @@ def DiagnoseIf : InheritableAttr {
 }
 
 def ArcWeakrefUnavailable : InheritableAttr {
-  let Spellings = [Clang<"objc_arc_weak_reference_unavailable">];
+  let Spellings = [Clang<"objc_arc_weak_reference_unavailable", 1>];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
   let Documentation = [Undocumented];
 }
 
 def ObjCGC : TypeAttr {
-  let Spellings = [Clang<"objc_gc">];
+  let Spellings = [Clang<"objc_gc", 1>];
   let Args = [IdentifierArgument<"Kind">];
   let Documentation = [Undocumented];
 }
 
 def ObjCOwnership : InheritableAttr {
-  let Spellings = [Clang<"objc_ownership">];
+  let Spellings = [Clang<"objc_ownership", 1>];
   let Args = [IdentifierArgument<"Kind">];
   let ASTNode = 0;
   let Documentation = [Undocumented];
 }
 
 def ObjCRequiresPropertyDefs : InheritableAttr {
-  let Spellings = [Clang<"objc_requires_property_definitions">];
+  let Spellings = [Clang<"objc_requires_property_definitions", 1>];
   let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
   let Documentation = [Undocumented];
 }
index 93b9356e3a643eb378d0078161a66667de468ff5..ec8e60815a67f6ce310e8684cdafbabd96101a5b 100644 (file)
@@ -1340,7 +1340,7 @@ private:
 
   // Objective-C External Declarations
   void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
-  DeclGroupPtrTy ParseObjCAtDirectives();
+  DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs);
   DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
   Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                         ParsedAttributes &prefixAttrs);
index 688376ca28e69f92c6336cbb91f0644b132e11d7..13f968fa5ec17ebf2265b06ad39a24a3aee58987 100644 (file)
@@ -45,7 +45,8 @@ void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
 /// [OBJC]  objc-protocol-definition
 /// [OBJC]  objc-method-definition
 /// [OBJC]  '@' 'end'
-Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
+Parser::DeclGroupPtrTy
+Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
   SourceLocation AtLoc = ConsumeToken(); // the "@"
 
   if (Tok.is(tok::code_completion)) {
@@ -58,15 +59,11 @@ Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
   switch (Tok.getObjCKeywordID()) {
   case tok::objc_class:
     return ParseObjCAtClassDeclaration(AtLoc);
-  case tok::objc_interface: {
-    ParsedAttributes attrs(AttrFactory);
-    SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
+  case tok::objc_interface:
+    SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, Attrs);
     break;
-  }
-  case tok::objc_protocol: {
-    ParsedAttributes attrs(AttrFactory);
-    return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
-  }
+  case tok::objc_protocol:
+    return ParseObjCAtProtocolDeclaration(AtLoc, Attrs);
   case tok::objc_implementation:
     return ParseObjCAtImplementationDeclaration(AtLoc);
   case tok::objc_end:
@@ -1359,6 +1356,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
   ParsedAttributes methodAttrs(AttrFactory);
   if (getLangOpts().ObjC2)
     MaybeParseGNUAttributes(methodAttrs);
+  MaybeParseCXX11Attributes(methodAttrs);
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
@@ -1385,6 +1383,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
     // If attributes exist after the method, parse them.
     if (getLangOpts().ObjC2)
       MaybeParseGNUAttributes(methodAttrs);
+    MaybeParseCXX11Attributes(methodAttrs);
 
     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
     Decl *Result
@@ -1421,11 +1420,10 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
 
     // If attributes exist before the argument name, parse them.
     // Regardless, collect all the attributes we've parsed so far.
-    ArgInfo.ArgAttrs = nullptr;
-    if (getLangOpts().ObjC2) {
+    if (getLangOpts().ObjC2)
       MaybeParseGNUAttributes(paramAttrs);
-      ArgInfo.ArgAttrs = paramAttrs.getList();
-    }
+    MaybeParseCXX11Attributes(paramAttrs);
+    ArgInfo.ArgAttrs = paramAttrs.getList();
 
     // Code completion for the next piece of the selector.
     if (Tok.is(tok::code_completion)) {
@@ -1508,7 +1506,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
   // If attributes exist after the method, parse them.
   if (getLangOpts().ObjC2)
     MaybeParseGNUAttributes(methodAttrs);
-  
+  MaybeParseCXX11Attributes(methodAttrs);
+
   if (KeyIdents.size() == 0)
     return nullptr;
 
index a6f966eda1b99e7af8d5596338c851b805bb34a3..ce5a479b4b3f7fbd35792de17bacfbc1af9907cd 100644 (file)
@@ -741,7 +741,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
     break;
   }
   case tok::at:
-    return ParseObjCAtDirectives();
+    return ParseObjCAtDirectives(attrs);
   case tok::minus:
   case tok::plus:
     if (!getLangOpts().ObjC1) {
diff --git a/test/Misc/ast-dump-attr.m b/test/Misc/ast-dump-attr.m
new file mode 100644 (file)
index 0000000..8775d40
--- /dev/null
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s\r
+\r
+@interface NSObject\r
+@end\r
+\r
+[[clang::objc_exception]]\r
+@interface Test1 {\r
+// CHECK: ObjCInterfaceDecl{{.*}} Test1\r
+// CHECK-NEXT: ObjCExceptionAttr{{.*}}\r
+  [[clang::iboutlet]] NSObject *Test2;\r
+// CHECK: ObjCIvarDecl{{.*}} Test2\r
+// CHECK-NEXT: IBOutletAttr\r
+}\r
+@property (readonly) [[clang::objc_returns_inner_pointer]] void *Test3, *Test4;\r
+// CHECK: ObjCPropertyDecl{{.*}} Test3 'void *' readonly\r
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr\r
+// CHECK-NEXT: ObjCPropertyDecl{{.*}} Test4 'void *' readonly\r
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr\r
+\r
+@property (readonly) [[clang::iboutlet]] NSObject *Test5;\r
+// CHECK: ObjCPropertyDecl{{.*}} Test5 'NSObject *' readonly\r
+// CHECK-NEXT: IBOutletAttr\r
+\r
+// CHECK: ObjCMethodDecl{{.*}} implicit{{.*}} Test3\r
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr\r
+// CHECK: ObjCMethodDecl{{.*}} implicit{{.*}} Test4\r
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr\r
+// CHECK: ObjCMethodDecl{{.*}} implicit{{.*}} Test5\r
+// CHECK-NOT: IBOutletAttr\r
+@end\r
+\r
+[[clang::objc_runtime_name("name")]] @protocol Test6;\r
+// CHECK: ObjCProtocolDecl{{.*}} Test6\r
+// CHECK-NEXT: ObjCRuntimeNameAttr{{.*}} "name"\r
+\r
+[[clang::objc_protocol_requires_explicit_implementation]]\r
+@protocol Test7\r
+// CHECK: ObjCProtocolDecl{{.*}} Test7\r
+// CHECK-NEXT: ObjCExplicitProtocolImplAttr\r
+@end\r
+\r
+@interface Test8\r
+// CHECK: ObjCInterfaceDecl{{.*}} Test8\r
+-(void)Test9 [[clang::ns_consumes_self]];\r
+// CHECK: ObjCMethodDecl{{.*}} Test9 'void'\r
+// CHECK-NEXT: NSConsumesSelfAttr\r
+-(void) [[clang::ns_consumes_self]] Test10: (int)Test11;\r
+// CHECK: ObjCMethodDecl{{.*}} Test10: 'void'\r
+// CHECK-NEXT: |-ParmVarDecl{{.*}} Test11 'int'\r
+// CHECK-NEXT: `-NSConsumesSelfAttr\r
+-(void)Test12: (int *) [[clang::noescape]] Test13  to:(int)Test14 [[clang::ns_consumes_self]];\r
+// CHECK: ObjCMethodDecl{{.*}} Test12:to: 'void'\r
+// CHECK-NEXT: |-ParmVarDecl{{.*}} Test13 'int *'\r
+// CHECK-NEXT: | `-NoEscapeAttr\r
+// CHECK-NEXT: |-ParmVarDecl{{.*}} Test14 'int'\r
+// CHECK-NEXT: `-NSConsumesSelfAttr\r
+@end\r
diff --git a/test/Parser/objc-attr.m b/test/Parser/objc-attr.m
new file mode 100644 (file)
index 0000000..7e65eff
--- /dev/null
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 -verify %s\r
+// expected-no-diagnostics\r
+\r
+@interface NSObject\r
+@end\r
+\r
+[[clang::objc_exception]]\r
+@interface Foo {\r
+  [[clang::iboutlet]] NSObject *h;\r
+}\r
+@property (readonly) [[clang::objc_returns_inner_pointer]] void *i, *j;\r
+@property (readonly) [[clang::iboutlet]] NSObject *k;\r
+@end\r
+\r
+[[clang::objc_runtime_name("name")]] @protocol Bar;\r
+\r
+[[clang::objc_protocol_requires_explicit_implementation]] \r
+@protocol Baz\r
+@end\r
+\r
+@interface Quux\r
+-(void)g1 [[clang::ns_consumes_self]];\r
+-(void)g2 __attribute__((ns_consumes_self));\r
+-(void)h1: (int)x [[clang::ns_consumes_self]];\r
+-(void)h2: (int)x __attribute__((ns_consumes_self));\r
+-(void) [[clang::ns_consumes_self]] i1;\r
+-(void) __attribute__((ns_consumes_self)) i2;\r
+@end\r