diff options
Diffstat (limited to 'lib/Sema/TargetAttributesSema.cpp')
| -rw-r--r-- | lib/Sema/TargetAttributesSema.cpp | 63 | 
1 files changed, 33 insertions, 30 deletions
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp index 8b19be74dd43..25ace950e077 100644 --- a/lib/Sema/TargetAttributesSema.cpp +++ b/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;          }  | 
