aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/Attr.td6
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--include/clang/Sema/AttributeList.h1
-rw-r--r--lib/Sema/AttributeList.cpp1
-rw-r--r--lib/Sema/SemaDeclAttr.cpp34
-rw-r--r--test/SemaObjC/attr-ns-bridged.m15
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}}