diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-05-21 00:06:11 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-05-21 00:06:11 +0000 |
commit | 1cac0481166dd383a5d685fd53154661fbac5896 (patch) | |
tree | 053bffe7753ef4be0649a497b87ea5cb863f1371 /lib | |
parent | 424aa2e72ee59d51914201ce184b585410e1a5fa (diff) |
Merging r182266:
------------------------------------------------------------------------
r182266 | rnk | 2013-05-20 07:02:37 -0700 (Mon, 20 May 2013) | 13 lines
Implement __declspec(selectany) under -fms-extensions
selectany only applies to externally visible global variables. It has
the effect of making the data weak_odr.
The MSDN docs suggest that unused definitions can only be dropped at
linktime, so Clang uses weak instead of linkonce. MSVC optimizes away
references to constant selectany data, so it must assume that there is
only one definition, hence weak_odr.
Reviewers: espindola
Differential Revision: http://llvm-reviews.chandlerc.com/D814
------------------------------------------------------------------------
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_33@182337 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 13 |
3 files changed, 29 insertions, 1 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 0b03a3c4b6..b3b05199a5 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1900,7 +1900,13 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, return llvm::Function::DLLImportLinkage; else if (D->hasAttr<DLLExportAttr>()) return llvm::Function::DLLExportLinkage; - else if (D->hasAttr<WeakAttr>()) { + else if (D->hasAttr<SelectAnyAttr>()) { + // selectany symbols are externally visible, so use weak instead of + // linkonce. MSVC optimizes away references to const selectany globals, so + // all definitions should be the same and ODR linkage should be used. + // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx + return llvm::GlobalVariable::WeakODRLinkage; + } else if (D->hasAttr<WeakAttr>()) { if (GV->isConstant()) return llvm::GlobalVariable::WeakODRLinkage; else diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e0e8bd646b..03e9afc002 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4638,6 +4638,15 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { 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, diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 7b3345a332..ddcbafc30a 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -4683,6 +4683,16 @@ static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); } +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 //===----------------------------------------------------------------------===// @@ -4909,6 +4919,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 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: |