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
This commit is contained in:
parent
4278047f64
commit
511f2e5a89
|
@ -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 {
|
||||
|
|
|
@ -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 = [{
|
||||
|
|
|
@ -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|"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
30
clang/test/SemaObjC/dllexport.m
Normal file
30
clang/test/SemaObjC/dllexport.m
Normal file
|
@ -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
|
||||
|
30
clang/test/SemaObjC/dllimport.m
Normal file
30
clang/test/SemaObjC/dllimport.m
Normal file
|
@ -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
|
||||
|
33
clang/test/SemaObjCXX/dllexport.mm
Normal file
33
clang/test/SemaObjCXX/dllexport.mm
Normal file
|
@ -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
|
||||
|
||||
|
32
clang/test/SemaObjCXX/dllimport.mm
Normal file
32
clang/test/SemaObjCXX/dllimport.mm
Normal file
|
@ -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
|
||||
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue
Block a user