forked from OSchip/llvm-project
dllimport and dllexport are declspec attributes, too. They're also
Win32-specific. Also, fix a test to use FileCheck instead of grepping LLVM IR. llvm-svn: 96364
This commit is contained in:
parent
e983eae273
commit
163855f46d
|
@ -813,82 +813,6 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
|
|||
D->addAttr(::new (S.Context) WeakImportAttr());
|
||||
}
|
||||
|
||||
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||
// check the attribute arguments.
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attribute can be applied only to functions or variables.
|
||||
if (isa<VarDecl>(D)) {
|
||||
D->addAttr(::new (S.Context) DLLImportAttr());
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 2 /*variable and function*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// Currently, the dllimport attribute is ignored for inlined functions.
|
||||
// Warning is emitted.
|
||||
if (FD->isInlineSpecified()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
|
||||
return;
|
||||
}
|
||||
|
||||
// The attribute is also overridden by a subsequent declaration as dllexport.
|
||||
// Warning is emitted.
|
||||
for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
|
||||
nextAttr = nextAttr->getNext()) {
|
||||
if (nextAttr->getKind() == AttributeList::AT_dllexport) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (D->getAttr<DLLExportAttr>()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
|
||||
return;
|
||||
}
|
||||
|
||||
D->addAttr(::new (S.Context) DLLImportAttr());
|
||||
}
|
||||
|
||||
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||
// check the attribute arguments.
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attribute can be applied only to functions or variables.
|
||||
if (isa<VarDecl>(D)) {
|
||||
D->addAttr(::new (S.Context) DLLExportAttr());
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 2 /*variable and function*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// Currently, the dllexport attribute is ignored for inlined functions, unless
|
||||
// the -fkeep-inline-functions flag has been used. Warning is emitted;
|
||||
if (FD->isInlineSpecified()) {
|
||||
// FIXME: ... unless the -fkeep-inline-functions flag has been used.
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
|
||||
return;
|
||||
}
|
||||
|
||||
D->addAttr(::new (S.Context) DLLExportAttr());
|
||||
}
|
||||
|
||||
static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
|
||||
Sema &S) {
|
||||
// Attribute has 3 arguments.
|
||||
|
@ -1786,6 +1710,11 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
|
|||
};
|
||||
}
|
||||
|
||||
static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
|
||||
return Attr.getKind() == AttributeList::AT_dllimport ||
|
||||
Attr.getKind() == AttributeList::AT_dllexport;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Top Level Sema Entry Points
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1796,8 +1725,8 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
|
|||
/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
|
||||
static void ProcessDeclAttribute(Scope *scope, Decl *D,
|
||||
const AttributeList &Attr, Sema &S) {
|
||||
if (Attr.isDeclspecAttribute())
|
||||
// FIXME: Try to deal with __declspec attributes!
|
||||
if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
|
||||
// FIXME: Try to deal with other __declspec attributes!
|
||||
return;
|
||||
switch (Attr.getKind()) {
|
||||
case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break;
|
||||
|
@ -1820,8 +1749,6 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
|
|||
case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_ext_vector_type:
|
||||
HandleExtVectorTypeAttr(scope, D, Attr, S);
|
||||
break;
|
||||
|
|
|
@ -97,12 +97,100 @@ static void HandleX86ForceAlignArgPointerAttr(Decl *D,
|
|||
D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
|
||||
}
|
||||
|
||||
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||
// check the attribute arguments.
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attribute can be applied only to functions or variables.
|
||||
if (isa<VarDecl>(D)) {
|
||||
D->addAttr(::new (S.Context) DLLImportAttr());
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 2 /*variable and function*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// Currently, the dllimport attribute is ignored for inlined functions.
|
||||
// Warning is emitted.
|
||||
if (FD->isInlineSpecified()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
|
||||
return;
|
||||
}
|
||||
|
||||
// The attribute is also overridden by a subsequent declaration as dllexport.
|
||||
// Warning is emitted.
|
||||
for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
|
||||
nextAttr = nextAttr->getNext()) {
|
||||
if (nextAttr->getKind() == AttributeList::AT_dllexport) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (D->getAttr<DLLExportAttr>()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
|
||||
return;
|
||||
}
|
||||
|
||||
D->addAttr(::new (S.Context) DLLImportAttr());
|
||||
}
|
||||
|
||||
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||
// check the attribute arguments.
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attribute can be applied only to functions or variables.
|
||||
if (isa<VarDecl>(D)) {
|
||||
D->addAttr(::new (S.Context) DLLExportAttr());
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (!FD) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 2 /*variable and function*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// Currently, the dllexport attribute is ignored for inlined functions, unless
|
||||
// the -fkeep-inline-functions flag has been used. Warning is emitted;
|
||||
if (FD->isInlineSpecified()) {
|
||||
// FIXME: ... unless the -fkeep-inline-functions flag has been used.
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
|
||||
return;
|
||||
}
|
||||
|
||||
D->addAttr(::new (S.Context) DLLExportAttr());
|
||||
}
|
||||
|
||||
namespace {
|
||||
class X86AttributesSema : public TargetAttributesSema {
|
||||
public:
|
||||
X86AttributesSema() { }
|
||||
bool ProcessDeclAttribute(Scope *scope, Decl *D,
|
||||
const AttributeList &Attr, Sema &S) const {
|
||||
const llvm::Triple &Triple(S.Context.Target.getTriple());
|
||||
if (Triple.getOS() == llvm::Triple::Win32 ||
|
||||
Triple.getOS() == llvm::Triple::MinGW32 ||
|
||||
Triple.getOS() == llvm::Triple::MinGW64) {
|
||||
switch (Attr.getKind()) {
|
||||
case AttributeList::AT_dllimport: HandleDLLImportAttr(D, Attr, S);
|
||||
return true;
|
||||
case AttributeList::AT_dllexport: HandleDLLExportAttr(D, Attr, S);
|
||||
return true;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (Attr.getName()->getName() == "force_align_arg_pointer") {
|
||||
HandleX86ForceAlignArgPointerAttr(D, Attr, S);
|
||||
return true;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
// RUN: %clang_cc1 -emit-llvm < %s -o %t
|
||||
// RUN: grep 'dllexport' %t | count 1
|
||||
// RUN: not grep 'dllimport' %t
|
||||
// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s
|
||||
|
||||
void __attribute__((dllimport)) foo1();
|
||||
void __attribute__((dllexport)) foo1(){}
|
||||
// CHECK: define dllexport void @foo1
|
||||
void __attribute__((dllexport)) foo2();
|
||||
|
||||
// PR6269
|
||||
__declspec(dllimport) void foo3();
|
||||
__declspec(dllexport) void foo3(){}
|
||||
// CHECK: define dllexport void @foo3
|
||||
__declspec(dllexport) void foo4();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -x objective-c++ %s
|
||||
// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -x objective-c++ %s
|
||||
__stdcall int func0();
|
||||
int __stdcall func();
|
||||
typedef int (__cdecl *tptr)();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify %s
|
||||
|
||||
inline void __attribute__((dllexport)) foo1(){} // expected-warning{{dllexport attribute ignored}}
|
||||
inline void __attribute__((dllimport)) foo2(){} // expected-warning{{dllimport attribute ignored}}
|
||||
|
@ -16,3 +16,21 @@ typedef int __attribute__((dllimport)) type7; // expected-warning{{'dllimport' a
|
|||
|
||||
void __attribute__((dllimport)) foo6();
|
||||
void foo6(){} // expected-warning {{'foo6' redeclared without dllimport attribute: previous dllimport ignored}}
|
||||
|
||||
// PR6269
|
||||
inline void __declspec(dllexport) foo7(){} // expected-warning{{dllexport attribute ignored}}
|
||||
inline void __declspec(dllimport) foo8(){} // expected-warning{{dllimport attribute ignored}}
|
||||
|
||||
void __declspec(dllimport) foo9(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
|
||||
|
||||
void __declspec(dllimport) __declspec(dllexport) foo10(); // expected-warning{{dllimport attribute ignored}}
|
||||
|
||||
void __declspec(dllexport) foo11();
|
||||
void __declspec(dllimport) foo11(); // expected-warning{{dllimport attribute ignored}}
|
||||
|
||||
typedef int __declspec(dllexport) type1; // expected-warning{{'dllexport' attribute only applies to variable and function types}}
|
||||
|
||||
typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attribute only applies to variable and function}}
|
||||
|
||||
void __declspec(dllimport) foo12();
|
||||
void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}}
|
||||
|
|
Loading…
Reference in New Issue