diff options
-rw-r--r-- | include/clang/Basic/Attr.td | 6 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | include/clang/Sema/AttributeList.h | 1 | ||||
-rw-r--r-- | lib/Sema/AttributeList.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 34 | ||||
-rw-r--r-- | test/SemaObjC/attr-ns-bridged.m | 15 |
6 files changed, 60 insertions, 1 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 4d9aa5b9a3..be43bca9fd 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -362,6 +362,12 @@ def NoThrow : InheritableAttr { let Spellings = ["nothrow"]; } +def NSBridged : InheritableAttr { + let Spellings = ["ns_bridged"]; + let Subjects = [Record]; + let Args = [IdentifierArgument<"BridgedType">]; +} + def NSReturnsRetained : InheritableAttr { let Spellings = ["ns_returns_retained"]; let Subjects = [ObjCMethod, Function]; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6ef027441b..cbae5be61f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1331,7 +1331,7 @@ def err_attribute_wrong_decl_type : Error< "variables and functions|functions and methods|parameters|" "parameters and methods|functions, methods and blocks|" "classes and virtual methods|functions, methods, and parameters|" - "classes|virtual methods|class members|variables|methods}1">; + "classes|virtual methods|class members|variables|methods|structs}1">; def warn_function_attribute_wrong_type : Warning< "'%0' only applies to function types; type here is %1">; def warn_pointer_attribute_wrong_type : Warning< @@ -1573,6 +1573,8 @@ def warn_ns_attribute_wrong_return_type : Warning< def warn_ns_attribute_wrong_parameter_type : Warning< "%0 attribute only applies to %select{Objective-C object|pointer}1 " "parameters">; +def err_ns_bridged_not_interface : Error< + "parameter of 'ns_bridged' attribute does not name an Objective-C class">; // Function Parameter Semantic Analysis. def err_param_with_void_type : Error<"argument may not have 'void' type">; diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index a44f6fae33..b0012e7c93 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -215,6 +215,7 @@ public: AT_nonnull, AT_noreturn, AT_nothrow, + AT_ns_bridged, // Clang-specific. AT_ns_consumed, // Clang-specific. AT_ns_consumes_self, // Clang-specific. AT_ns_returns_autoreleased, // Clang-specific. diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index d9f17b42da..5cd21a645d 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -171,6 +171,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { .Case("analyzer_noreturn", AT_analyzer_noreturn) .Case("warn_unused_result", AT_warn_unused_result) .Case("carries_dependency", AT_carries_dependency) + .Case("ns_bridged", AT_ns_bridged) .Case("ns_consumed", AT_ns_consumed) .Case("ns_consumes_self", AT_ns_consumes_self) .Case("ns_returns_autoreleased", AT_ns_returns_autoreleased) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 435507f9d7..eca6874b36 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -22,6 +22,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/DelayedDiagnostic.h" +#include "clang/Sema/Lookup.h" #include "llvm/ADT/StringExtras.h" using namespace clang; using namespace sema; @@ -3262,6 +3263,36 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); } +static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, + const AttributeList &Attr) { + RecordDecl *RD = dyn_cast<RecordDecl>(D); + if (!RD || RD->isUnion()) { + S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) + << Attr.getRange() << Attr.getName() << 14 /*struct */; + } + + IdentifierInfo *ParmName = Attr.getParameterName(); + + // In Objective-C, verify that the type names an Objective-C type. + // We don't want to check this outside of ObjC because people sometimes + // do crazy C declarations of Objective-C types. + if (ParmName && S.getLangOptions().ObjC1) { + // Check for an existing type with this name. + LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), + Sema::LookupOrdinaryName); + if (S.LookupName(R, Sc)) { + NamedDecl *Target = R.getFoundDecl(); + if (Target && !isa<ObjCInterfaceDecl>(Target)) { + S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); + S.Diag(Target->getLocStart(), diag::note_declared_at); + } + } + } + + D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, + ParmName)); +} + static void handleObjCOwnershipAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (hasDeclarator(D)) return; @@ -3465,6 +3496,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_objc_returns_inner_pointer: handleObjCReturnsInnerPointerAttr(S, D, Attr); break; + case AttributeList::AT_ns_bridged: + handleNSBridgedAttr(S, scope, D, Attr); break; + // Checker-specific. case AttributeList::AT_cf_consumed: case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; diff --git a/test/SemaObjC/attr-ns-bridged.m b/test/SemaObjC/attr-ns-bridged.m new file mode 100644 index 0000000000..1ab60a2b0d --- /dev/null +++ b/test/SemaObjC/attr-ns-bridged.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef struct __attribute__((ns_bridged)) test0s *test0ref; + +void test0func(void) __attribute__((ns_bridged)); // expected-error {{'ns_bridged' attribute only applies to structs}} + +union __attribute__((ns_bridged)) test0u; // expected-error {{'ns_bridged' attribute only applies to structs}} + +struct __attribute__((ns_bridged(Test1))) test1s; + +@class Test2; +struct __attribute__((ns_bridged(Test2))) test2s; + +void Test3(void); // expected-note {{declared here}} +struct __attribute__((ns_bridged(Test3))) test3s; // expected-error {{parameter of 'ns_bridged' attribute does not name an Objective-C class}} |