aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/TargetAttributesSema.cpp
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2010-02-16 18:27:26 +0000
committerCharles Davis <cdavis@mines.edu>2010-02-16 18:27:26 +0000
commitf0122fe49329cb439d55a6712bfcaad9a6570428 (patch)
treec74f0b052f1938aa107038decb4e41ad21ccf52d /lib/Sema/TargetAttributesSema.cpp
parentef5ebf60c86813151e3a29768546d25927183021 (diff)
dllimport and dllexport are declspec attributes, too. They're also
Win32-specific. Also, fix a test to use FileCheck instead of grepping LLVM IR. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96364 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/TargetAttributesSema.cpp')
-rw-r--r--lib/Sema/TargetAttributesSema.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index d45d0106ff..597a027696 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -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;