diff options
author | Charles Davis <cdavis@mines.edu> | 2010-02-16 18:27:26 +0000 |
---|---|---|
committer | Charles Davis <cdavis@mines.edu> | 2010-02-16 18:27:26 +0000 |
commit | f0122fe49329cb439d55a6712bfcaad9a6570428 (patch) | |
tree | c74f0b052f1938aa107038decb4e41ad21ccf52d /lib/Sema/TargetAttributesSema.cpp | |
parent | ef5ebf60c86813151e3a29768546d25927183021 (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.cpp | 88 |
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; |