[PATCH] Implement __declspec(selectany) under -fms-extensions

Reid Kleckner rnk at google.com
Fri May 17 11:18:08 PDT 2013


The MSDN page says they can be discarded if you turn on the linker option
/OPT:REF.  My intrepretation is that yes, they can be discarded, but only
at link time.


On Fri, May 17, 2013 at 1:38 PM, Rafael EspĂ­ndola <
rafael.espindola at gmail.com> wrote:

> Can they be discarded? If so, please add a comment saying that they
> can. If not, you need no use weak_odr.
>
> On 17 May 2013 13:22, Reid Kleckner <rnk at google.com> wrote:
> > selectany only applies to externally visible global variables.  It has
> > the effect of making the data linkonce.  MSDN doesn't seem to require
> > that all definitions be the same, which means clang shouldn't use
> > linkonceodr.
> >
> > http://llvm-reviews.chandlerc.com/D814
> >
> > Files:
> >   include/clang/Basic/Attr.td
> >   include/clang/Basic/DiagnosticSemaKinds.td
> >   lib/CodeGen/CodeGenModule.cpp
> >   lib/Sema/SemaDecl.cpp
> >   lib/Sema/SemaDeclAttr.cpp
> >   test/CodeGen/ms-declspecs.c
> >   test/SemaCXX/attr-selectany.cpp
> >
> > Index: include/clang/Basic/Attr.td
> > ===================================================================
> > --- include/clang/Basic/Attr.td
> > +++ include/clang/Basic/Attr.td
> > @@ -948,6 +948,10 @@
> >    let Spellings = [Keyword<"__forceinline">];
> >  }
> >
> > +def SelectAny : InheritableAttr {
> > +  let Spellings = [Declspec<"selectany">];
> > +}
> > +
> >  def Win64 : InheritableAttr {
> >    let Spellings = [Keyword<"__w64">];
> >  }
> > Index: include/clang/Basic/DiagnosticSemaKinds.td
> > ===================================================================
> > --- include/clang/Basic/DiagnosticSemaKinds.td
> > +++ include/clang/Basic/DiagnosticSemaKinds.td
> > @@ -1950,6 +1950,8 @@
> >    "weak identifier %0 never declared">;
> >  def err_attribute_weak_static : Error<
> >    "weak declaration cannot have internal linkage">;
> > +def err_attribute_selectany_non_extern_data : Error<
> > +  "'selectany' can only be applied to data items with external
> linkage">;
> >  def warn_attribute_weak_import_invalid_on_definition : Warning<
> >    "'weak_import' attribute cannot be specified on a definition">,
> >    InGroup<IgnoredAttributes>;
> > Index: lib/CodeGen/CodeGenModule.cpp
> > ===================================================================
> > --- lib/CodeGen/CodeGenModule.cpp
> > +++ lib/CodeGen/CodeGenModule.cpp
> > @@ -1937,7 +1937,12 @@
> >      return llvm::Function::DLLImportLinkage;
> >    else if (D->hasAttr<DLLExportAttr>())
> >      return llvm::Function::DLLExportLinkage;
> > -  else if (D->hasAttr<WeakAttr>()) {
> > +  else if (D->hasAttr<SelectAnyAttr>()) {
> > +    // MSDN does not say that selectany globals all have to have the
> same
> > +    // definition, so we use linkonce instead of linkonceodr here to be
> > +    // conservative.
> > +    return llvm::GlobalVariable::LinkOnceAnyLinkage;
> > +  } else if (D->hasAttr<WeakAttr>()) {
> >      if (GV->isConstant())
> >        return llvm::GlobalVariable::WeakODRLinkage;
> >      else
> > Index: lib/Sema/SemaDecl.cpp
> > ===================================================================
> > --- lib/Sema/SemaDecl.cpp
> > +++ lib/Sema/SemaDecl.cpp
> > @@ -4636,6 +4636,15 @@
> >        ND.dropAttr<WeakRefAttr>();
> >      }
> >    }
> > +
> > +  // 'selectany' only applies to externally visible varable
> declarations.
> > +  // It does not apply to functions.
> > +  if (SelectAnyAttr *Attr = ND.getAttr<SelectAnyAttr>()) {
> > +    if (isa<FunctionDecl>(ND) || !ND.isExternallyVisible()) {
> > +      S.Diag(Attr->getLocation(),
> diag::err_attribute_selectany_non_extern_data);
> > +      ND.dropAttr<SelectAnyAttr>();
> > +    }
> > +  }
> >  }
> >
> >  /// Given that we are within the definition of the given function,
> > Index: lib/Sema/SemaDeclAttr.cpp
> > ===================================================================
> > --- lib/Sema/SemaDeclAttr.cpp
> > +++ lib/Sema/SemaDeclAttr.cpp
> > @@ -4690,6 +4690,16 @@
> >                               Attr.getAttributeSpellingListIndex()));
> >  }
> >
> > +static void handleSelectAnyAttr(Sema &S, Decl *D, const AttributeList
> &Attr) {
> > +  if (!checkMicrosoftExt(S, Attr))
> > +    return;
> > +  // Check linkage after possibly merging declaratinos.  See
> > +  // checkAttributesAfterMerging().
> > +  D->addAttr(::new (S.Context)
> > +             SelectAnyAttr(Attr.getRange(), S.Context,
> > +                           Attr.getAttributeSpellingListIndex()));
> > +}
> > +
> >
>  //===----------------------------------------------------------------------===//
> >  // Top Level Sema Entry Points
> >
>  //===----------------------------------------------------------------------===//
> > @@ -4916,6 +4926,9 @@
> >    case AttributeList::AT_ForceInline:
> >      handleForceInlineAttr(S, D, Attr);
> >      break;
> > +  case AttributeList::AT_SelectAny:
> > +    handleSelectAnyAttr(S, D, Attr);
> > +    break;
> >
> >    // Thread safety attributes:
> >    case AttributeList::AT_GuardedVar:
> > Index: test/CodeGen/ms-declspecs.c
> > ===================================================================
> > --- test/CodeGen/ms-declspecs.c
> > +++ test/CodeGen/ms-declspecs.c
> > @@ -1,5 +1,10 @@
> >  // RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm
> -fms-compatibility -o - | FileCheck %s
> >
> > +__declspec(selectany) int x1 = 1;
> > +const __declspec(selectany) int x2 = 2;
> > +// CHECK: @x1 = linkonce global i32 1, align 4
> > +// CHECK: @x2 = linkonce constant i32 2, align 4
> > +
> >  struct __declspec(align(16)) S {
> >    char x;
> >  };
> > Index: test/SemaCXX/attr-selectany.cpp
> > ===================================================================
> > --- /dev/null
> > +++ test/SemaCXX/attr-selectany.cpp
> > @@ -0,0 +1,26 @@
> > +// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
> > +// MSVC produces similar diagnostics.
> > +
> > +__declspec(selectany) void foo() { } // expected-error{{'selectany' can
> only be applied to data items with external linkage}}
> > +
> > +__declspec(selectany) int x1 = 1;
> > +
> > +const __declspec(selectany) int x2 = 2; // expected-error{{'selectany'
> can only be applied to data items with external linkage}}
> > +
> > +extern const __declspec(selectany) int x3 = 3;
> > +
> > +extern const int x4;
> > +const __declspec(selectany) int x4 = 4;
> > +
> > +// MSDN says this is incorrect, but MSVC doesn't diagnose it.
> > +extern __declspec(selectany) int x5;
> > +
> > +static __declspec(selectany) int x6 = 2; // expected-error{{'selectany'
> can only be applied to data items with external linkage}}
> > +
> > +class X {
> > + public:
> > +  X(int i) { i++; };
> > +  int i;
> > +};
> > +
> > +__declspec(selectany) X x(1);
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130517/172bbc8d/attachment.html>


More information about the cfe-commits mailing list