// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s // RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -ast-dump -ast-dump-filter test %s | FileCheck %s #pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(objc_interface, objc_protocol, objc_property, field, objc_method, variable)) #pragma clang attribute push (__attribute__((objc_subclassing_restricted)), apply_to = objc_interface) @interface testInterface1 // CHECK-LABEL: ObjCInterfaceDecl{{.*}}testInterface1 // CHECK-NEXT: ObjCImplementation // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NEXT: ObjCSubclassingRestrictedAttr{{.*}} // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr { int testIvar1; // CHECK-LABEL: ObjCIvarDecl{{.*}} testIvar1 // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr } @property int testProp1; // CHECK-LABEL: ObjCPropertyDecl{{.*}} testProp1 // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr - (void)testIm:(int) x; // CHECK-LABEL: ObjCMethodDecl{{.*}}testIm // CHECK-NEXT: ParmVarDecl{{.*}} x // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr + (void)testCm; // CHECK-LABEL: ObjCMethodDecl{{.*}}testCm // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr // Implicit getters/setters shouldn't receive the attributes. // CHECK-LABEL: ObjCMethodDecl{{.*}}testProp1 // CHECK-NOT: AnnotateAttr // CHECK-LABEL: ObjCMethodDecl{{.*}}setTestProp1 // CHECK-NOT: AnnotateAttr @end // @implementation can't receive explicit attributes, so don't add the pragma // attributes to them. @implementation testInterface1 // CHECK-LABEL: ObjCImplementationDecl{{.*}}testInterface1 // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr { int testIvar2; // CHECK-LABEL: ObjCIvarDecl{{.*}} testIvar2 // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr } // Don't add attributes to implicit parameters! - (void)testIm:(int) x { // CHECK-LABEL: ObjCMethodDecl{{.*}}testIm // CHECK-NEXT: ImplicitParamDecl // CHECK-NEXT: ImplicitParamDecl // CHECK-NEXT: ParmVarDecl{{.*}} x // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NEXT: CompoundStmt // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr } + (void)testCm { // CHECK-LABEL: ObjCMethodDecl{{.*}}testCm // CHECK: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr // CHECK-NOT: AnnotateAttr _Pragma("clang attribute push (__attribute__((annotate(\"applied at container start\"))), apply_to=objc_interface)"); } // Implicit ivars shouldn't receive the attributes. // CHECK-LABEL: ObjCIvarDecl{{.*}}_testProp1 // CHECK-NOT: AnnotateAttr @end @implementation testImplWithoutInterface // expected-warning {{cannot find interface declaration for 'testImplWithoutInterface'}} // CHECK-LABEL: ObjCInterfaceDecl{{.*}}testImplWithoutInterface // CHECK-NEXT: ObjCImplementation // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NEXT: ObjCSubclassingRestrictedAttr // CHECK-NEXT: AnnotateAttr{{.*}} "applied at container start" // CHECK-LABEL: ObjCImplementationDecl{{.*}}testImplWithoutInterface // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr @end #pragma clang attribute pop @protocol testProtocol // CHECK-LABEL: ObjCProtocolDecl{{.*}}testProtocol // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr // CHECK-NOT: AnnotateAttr - (void)testProtIm; // CHECK-LABEL: ObjCMethodDecl{{.*}}testProtIm // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr @end @protocol testForwardProtocol; // CHECK-LABEL: ObjCProtocolDecl{{.*}}testForwardProtocol // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr // Categories can't receive explicit attributes, so don't add pragma attributes // to them. @interface testInterface1(testCat) // CHECK-LABEL: ObjCCategoryDecl{{.*}}testCat // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr @end @implementation testInterface1(testCat) // CHECK-LABEL: ObjCCategoryImplDecl{{.*}}testCat // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr @end // @class/@compatibility_alias declarations can't receive explicit attributes, // so don't add pragma attributes to them. @class testClass; // CHECK-LABEL: ObjCInterfaceDecl{{.*}}testClass // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr @compatibility_alias testCompat testInterface1; // CHECK-LABEL: ObjCCompatibleAliasDecl{{.*}}testCompat // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr #pragma clang attribute pop // objc_subclassing_restricted @interface testInterface3 // CHECK-LABEL: ObjCInterfaceDecl{{.*}}testInterface3 // CHECK-NEXT: AnnotateAttr{{.*}} "test" // CHECK-NOT: ObjCSubclassingRestrictedAttr @end #pragma clang attribute pop // annotate("test") @interface testInterface4 // CHECK-LABEL: ObjCInterfaceDecl{{.*}}testInterface4 // CHECK-NOT: AnnotateAttr // CHECK-NOT: ObjCSubclassingRestrictedAttr @end