summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2016-07-15 20:41:10 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2016-07-15 20:41:10 +0000
commit511f2e5a8955c90d6b9c176c31af2ec3add395fa (patch)
treec598856565811c6447e5ad46de909aa5f57b4519
parent4278047f64c9a364a5af61fbed785db3bdcee206 (diff)
downloadbcm5719-llvm-511f2e5a8955c90d6b9c176c31af2ec3add395fa.tar.gz
bcm5719-llvm-511f2e5a8955c90d6b9c176c31af2ec3add395fa.zip
Sema: support __declspec(dll*) on ObjC interfaces
Extend the __declspec(dll*) attribute to cover ObjC interfaces. This was requested by Microsoft for their ObjC support. Cover both import and export. This only adds the semantic analysis portion of the support, code-generation still remains outstanding. Add some basic initial documentation on the attributes that were previously empty. Tweak the previous tests to use the relative expected-warnings to make the tests easier to read. llvm-svn: 275610
-rw-r--r--clang/include/clang/Basic/Attr.td8
-rw-r--r--clang/include/clang/Basic/AttrDocs.td28
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td8
-rw-r--r--clang/include/clang/Sema/AttributeList.h2
-rw-r--r--clang/test/Sema/dllexport.c18
-rw-r--r--clang/test/Sema/dllimport.c18
-rw-r--r--clang/test/SemaCXX/dllexport.cpp18
-rw-r--r--clang/test/SemaCXX/dllimport.cpp18
-rw-r--r--clang/test/SemaObjC/dllexport.m30
-rw-r--r--clang/test/SemaObjC/dllimport.m30
-rw-r--r--clang/test/SemaObjCXX/dllexport.mm33
-rw-r--r--clang/test/SemaObjCXX/dllimport.mm32
-rw-r--r--clang/utils/TableGen/ClangAttrEmitter.cpp9
13 files changed, 222 insertions, 30 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 7305c746ce7..7da1efe5ff4 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2087,14 +2087,14 @@ def MSStruct : InheritableAttr {
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
- let Subjects = SubjectList<[Function, Var, CXXRecord]>;
- let Documentation = [Undocumented];
+ let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
+ let Documentation = [DLLExportDocs];
}
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
- let Subjects = SubjectList<[Function, Var, CXXRecord]>;
- let Documentation = [Undocumented];
+ let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
+ let Documentation = [DLLImportDocs];
}
def SelectAny : InheritableAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index c7bddaacbaf..d0342bc6038 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -67,6 +67,34 @@ TLS models are mutually exclusive.
}];
}
+def DLLExportDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``__declspec(dllexport)`` attribute declares a variable, function, or
+Objective-C interface to be exported from the module. It is available under the
+``-fdeclspec`` flag for compatibility with various compilers. The primary use
+is for COFF object files which explicitly specify what interfaces are available
+for external use. See the dllexport_ documentation on MSDN for more
+information.
+
+.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
+ }];
+}
+
+def DLLImportDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``__declspec(dllimport)`` attribute declares a variable, function, or
+Objective-C interface to be imported from an external module. It is available
+under the ``-fdeclspec`` flag for compatibility with various compilers. The
+primary use is for COFF object files which explicitly specify what interfaces
+are imported from external modules. See the dllimport_ documentation on MSDN
+for more information.
+
+.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
+ }];
+}
+
def ThreadDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 664853baebc..45e77d84d49 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2503,7 +2503,9 @@ def err_ifunc_resolver_params : Error<
"ifunc resolver function must have no parameters">;
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{functions|unions|"
- "variables and functions|functions and methods|parameters|"
+ "variables and functions|"
+ "functions, variables, and Objective-C interfaces|"
+ "functions and methods|parameters|"
"functions, methods and blocks|functions, methods, and classes|"
"functions, methods, and parameters|classes|enums|variables|methods|"
"fields and global variables|structs|parameters and typedefs|variables and typedefs|"
@@ -2511,7 +2513,9 @@ def warn_attribute_wrong_decl_type : Warning<
"types and namespaces|Objective-C interfaces|methods and properties|"
"struct or union|struct, union or class|types|"
"Objective-C instance methods|init methods of interface or class extension declarations|"
- "variables, functions and classes|Objective-C protocols|"
+ "variables, functions and classes|"
+ "functions, variables, classes, and Objective-C interfaces|"
+ "Objective-C protocols|"
"functions and global variables|structs, unions, and typedefs|structs and typedefs|"
"interface or protocol declarations|kernel functions|non-K&R-style functions|"
"variables, enums, fields and typedefs|functions, methods, enums, and classes|"
diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h
index 5b838d35071..fcddbecc029 100644
--- a/clang/include/clang/Sema/AttributeList.h
+++ b/clang/include/clang/Sema/AttributeList.h
@@ -869,6 +869,7 @@ enum AttributeDeclKind {
ExpectedFunction,
ExpectedUnion,
ExpectedVariableOrFunction,
+ ExpectedFunctionVariableOrObjCInterface,
ExpectedFunctionOrMethod,
ExpectedParameter,
ExpectedFunctionMethodOrBlock,
@@ -894,6 +895,7 @@ enum AttributeDeclKind {
ExpectedObjCInstanceMethod,
ExpectedObjCInterfaceDeclInitMethod,
ExpectedFunctionVariableOrClass,
+ ExpectedFunctionVariableClassOrObjCInterface,
ExpectedObjectiveCProtocol,
ExpectedFunctionGlobalVarMethodOrProperty,
ExpectedStructOrUnionOrTypedef,
diff --git a/clang/test/Sema/dllexport.c b/clang/test/Sema/dllexport.c
index 56c9e74225f..7991a455b4d 100644
--- a/clang/test/Sema/dllexport.c
+++ b/clang/test/Sema/dllexport.c
@@ -4,12 +4,18 @@
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 %s
// Invalid usage.
-__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-enum __declspec(dllexport) Enum { EnumVal }; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-struct __declspec(dllexport) Record {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+__declspec(dllexport) typedef int typedef1;
+// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) int typedef2;
+// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+typedef int __declspec(dllexport) typedef3;
+// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) void (*FunTy)();
+// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+enum __declspec(dllexport) Enum { EnumVal };
+// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+struct __declspec(dllexport) Record {};
+// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
diff --git a/clang/test/Sema/dllimport.c b/clang/test/Sema/dllimport.c
index 2da5dd8b40c..0728cf14a8e 100644
--- a/clang/test/Sema/dllimport.c
+++ b/clang/test/Sema/dllimport.c
@@ -4,12 +4,18 @@
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 -DGNU %s
// Invalid usage.
-__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-enum __declspec(dllimport) Enum { EnumVal }; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-struct __declspec(dllimport) Record {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+__declspec(dllimport) typedef int typedef1;
+// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) int typedef2;
+// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+typedef int __declspec(dllimport) typedef3;
+// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) void (*FunTy)();
+// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+enum __declspec(dllimport) Enum { EnumVal };
+// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+struct __declspec(dllimport) Record {};
+// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
diff --git a/clang/test/SemaCXX/dllexport.cpp b/clang/test/SemaCXX/dllexport.cpp
index 0bbf9b370b4..b4850fc03d9 100644
--- a/clang/test/SemaCXX/dllexport.cpp
+++ b/clang/test/SemaCXX/dllexport.cpp
@@ -16,13 +16,19 @@ struct External { int v; };
// Invalid usage.
-__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
-typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
-typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
-typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
-enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+__declspec(dllexport) typedef int typedef1;
+// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) int typedef2;
+// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllexport) typedef3;
+// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) void (*FunTy)();
+// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllexport) Enum {};
+// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
#if __has_feature(cxx_strong_enums)
- enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+enum class __declspec(dllexport) EnumClass {};
+// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
#endif
diff --git a/clang/test/SemaCXX/dllimport.cpp b/clang/test/SemaCXX/dllimport.cpp
index 3448e69bab5..36a8ac625ac 100644
--- a/clang/test/SemaCXX/dllimport.cpp
+++ b/clang/test/SemaCXX/dllimport.cpp
@@ -15,13 +15,19 @@ namespace { struct Internal {}; }
// Invalid usage.
-__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
-typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
-typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
-typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
-enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+__declspec(dllimport) typedef int typedef1;
+// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) int typedef2;
+// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllimport) typedef3;
+// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) void (*FunTy)();
+// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllimport) Enum {};
+// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
#if __has_feature(cxx_strong_enums)
- enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+enum class __declspec(dllimport) EnumClass {};
+// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
#endif
diff --git a/clang/test/SemaObjC/dllexport.m b/clang/test/SemaObjC/dllexport.m
new file mode 100644
index 00000000000..e90b982c15c
--- /dev/null
+++ b/clang/test/SemaObjC/dllexport.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
+
+__declspec(dllexport) typedef int typedef1;
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+typedef __declspec(dllexport) int typedef2;
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+typedef int __declspec(dllexport) typedef3;
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+typedef __declspec(dllexport) void (*FunTy)();
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+enum __declspec(dllexport) E { Val };
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+struct __declspec(dllexport) Record {};
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+
+__declspec(dllexport)
+__attribute__((__objc_root_class__))
+@interface NSObject
+@end
+
+__declspec(dllexport)
+@interface I : NSObject
+- (void)method;
+@end
+
+@implementation I
+- (void)method {
+}
+@end
+
diff --git a/clang/test/SemaObjC/dllimport.m b/clang/test/SemaObjC/dllimport.m
new file mode 100644
index 00000000000..b8360773c69
--- /dev/null
+++ b/clang/test/SemaObjC/dllimport.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
+
+__declspec(dllimport) typedef int typedef1;
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+typedef __declspec(dllimport) int typedef2;
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+typedef int __declspec(dllimport) typedef3;
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+typedef __declspec(dllimport) void (*FunTy)();
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+enum __declspec(dllimport) E { Val };
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+struct __declspec(dllimport) Record {};
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+
+__declspec(dllimport)
+__attribute__((__objc_root_class__))
+@interface NSObject
+@end
+
+__declspec(dllimport)
+@interface I : NSObject
+- (void)method;
+@end
+
+@implementation I
+- (void)method {
+}
+@end
+
diff --git a/clang/test/SemaObjCXX/dllexport.mm b/clang/test/SemaObjCXX/dllexport.mm
new file mode 100644
index 00000000000..739749f6419
--- /dev/null
+++ b/clang/test/SemaObjCXX/dllexport.mm
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
+
+__declspec(dllexport) typedef int typedef1;
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+typedef __declspec(dllexport) int typedef2;
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+typedef int __declspec(dllexport) typedef3;
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+typedef __declspec(dllexport) void (*FunTy)();
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+enum __declspec(dllexport) E { };
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+#if __has_feature(cxx_strong_enums)
+enum class __declspec(dllexport) F { };
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+#endif
+
+__declspec(dllexport)
+__attribute__((__objc_root_class__))
+@interface NSObject
+@end
+
+__declspec(dllexport)
+@interface I : NSObject
+- (void)method;
+@end
+
+@implementation I
+- (void)method {
+}
+@end
+
+
diff --git a/clang/test/SemaObjCXX/dllimport.mm b/clang/test/SemaObjCXX/dllimport.mm
new file mode 100644
index 00000000000..4c348c48418
--- /dev/null
+++ b/clang/test/SemaObjCXX/dllimport.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
+
+__declspec(dllimport) typedef int typedef1;
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+typedef __declspec(dllimport) int typedef2;
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+typedef int __declspec(dllimport) typedef3;
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+typedef __declspec(dllimport) void (*FunTy)();
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+enum __declspec(dllimport) E { };
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+#if __has_feature(cxx_strong_enums)
+enum class __declspec(dllimport) F { };
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
+#endif
+
+__declspec(dllimport)
+__attribute__((__objc_root_class__))
+@interface NSObject
+@end
+
+__declspec(dllimport)
+@interface I : NSObject
+- (void)method;
+@end
+
+@implementation I
+- (void)method {
+}
+@end
+
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 1186d16ba27..50102af33a5 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2653,6 +2653,15 @@ static std::string CalculateDiagnostic(const Record &S) {
return "(S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : "
"ExpectedVariableOrFunction)";
+ case Func | Var | Class | ObjCInterface:
+ return "(S.getLangOpts().CPlusPlus"
+ " ? ((S.getLangOpts().ObjC1 || S.getLangOpts().ObjC2)"
+ " ? ExpectedFunctionVariableClassOrObjCInterface"
+ " : ExpectedFunctionVariableOrClass)"
+ " : ((S.getLangOpts().ObjC1 || S.getLangOpts().ObjC2)"
+ " ? ExpectedFunctionVariableOrObjCInterface"
+ " : ExpectedVariableOrFunction))";
+
case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
case ObjCProtocol | ObjCInterface:
return "ExpectedObjectiveCInterfaceOrProtocol";
OpenPOWER on IntegriCloud