diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/TargetAttributesSema.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/TargetAttributesSema.cpp | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/TargetAttributesSema.cpp b/contrib/llvm/tools/clang/lib/Sema/TargetAttributesSema.cpp index 8b19be7..25ace95 100644 --- a/contrib/llvm/tools/clang/lib/Sema/TargetAttributesSema.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/TargetAttributesSema.cpp @@ -151,6 +151,18 @@ static void HandleX86ForceAlignArgPointerAttr(Decl *D, S.Context)); } +DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range) { + if (D->hasAttr<DLLExportAttr>()) { + Diag(Range.getBegin(), diag::warn_attribute_ignored) << "dllimport"; + return NULL; + } + + if (D->hasAttr<DLLImportAttr>()) + return NULL; + + return ::new (Context) DLLImportAttr(Range, Context); +} + static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 0) { @@ -159,13 +171,8 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { } // Attribute can be applied only to functions or variables. - if (isa<VarDecl>(D)) { - D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context)); - return; - } - FunctionDecl *FD = dyn_cast<FunctionDecl>(D); - if (!FD) { + if (!FD && !isa<VarDecl>(D)) { // Apparently Visual C++ thinks it is okay to not emit a warning // in this case, so only emit a warning when -fms-extensions is not // specified. @@ -177,27 +184,26 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // Currently, the dllimport attribute is ignored for inlined functions. // Warning is emitted. - if (FD->isInlineSpecified()) { + if (FD && 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; - } - } + DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange()); + if (NewAttr) + D->addAttr(NewAttr); +} - if (D->getAttr<DLLExportAttr>()) { - S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; - return; +DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range) { + if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) { + Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport"; + D->dropAttr<DLLImportAttr>(); } - D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context)); + if (D->hasAttr<DLLExportAttr>()) + return NULL; + + return ::new (Context) DLLExportAttr(Range, Context); } static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { @@ -208,13 +214,8 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { } // Attribute can be applied only to functions or variables. - if (isa<VarDecl>(D)) { - D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context)); - return; - } - FunctionDecl *FD = dyn_cast<FunctionDecl>(D); - if (!FD) { + if (!FD && !isa<VarDecl>(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << Attr.getName() << 2 /*variable and function*/; return; @@ -222,13 +223,15 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // Currently, the dllexport attribute is ignored for inlined functions, unless // the -fkeep-inline-functions flag has been used. Warning is emitted; - if (FD->isInlineSpecified()) { + if (FD && 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(Attr.getLoc(), S.Context)); + DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange()); + if (NewAttr) + D->addAttr(NewAttr); } namespace { @@ -241,9 +244,9 @@ namespace { if (Triple.getOS() == llvm::Triple::Win32 || Triple.getOS() == llvm::Triple::MinGW32) { switch (Attr.getKind()) { - case AttributeList::AT_dllimport: HandleDLLImportAttr(D, Attr, S); + case AttributeList::AT_DLLImport: HandleDLLImportAttr(D, Attr, S); return true; - case AttributeList::AT_dllexport: HandleDLLExportAttr(D, Attr, S); + case AttributeList::AT_DLLExport: HandleDLLExportAttr(D, Attr, S); return true; default: break; } |