summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-04-15 21:50:06 +0000
committerNico Weber <nicolasweber@gmx.de>2015-04-15 21:50:06 +0000
commitea7386d40c6026e36c8dd3a5ff911d7e921ae63d (patch)
treee54186260e6832254366ebd61ce25bf3bc44e2a8 /clang
parenta2ee3013e6c0c4f883a8dab6e3c8a529d2ca958d (diff)
downloadbcm5719-llvm-ea7386d40c6026e36c8dd3a5ff911d7e921ae63d.tar.gz
bcm5719-llvm-ea7386d40c6026e36c8dd3a5ff911d7e921ae63d.zip
Make __declspec(selectany) turn variable declartions into definitions.
Fixes PR23242. llvm-svn: 235046
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/Decl.cpp4
-rw-r--r--clang/test/CodeGen/ms-declspecs.c4
-rw-r--r--clang/test/CodeGen/ms-declspecs.cpp13
3 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 2ae73de5074..349b7b43d1a 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1926,14 +1926,14 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
return DeclarationOnly;
- if (hasExternalStorage())
+ if (!hasAttr<SelectAnyAttr>() && hasExternalStorage())
return DeclarationOnly;
// [dcl.link] p7:
// A declaration directly contained in a linkage-specification is treated
// as if it contains the extern specifier for the purpose of determining
// the linkage of the declared name and whether it is a definition.
- if (isSingleLineLanguageLinkage(*this))
+ if (!hasAttr<SelectAnyAttr>() && isSingleLineLanguageLinkage(*this))
return DeclarationOnly;
// C99 6.9.2p2:
diff --git a/clang/test/CodeGen/ms-declspecs.c b/clang/test/CodeGen/ms-declspecs.c
index 328fc835d34..985c227faa3 100644
--- a/clang/test/CodeGen/ms-declspecs.c
+++ b/clang/test/CodeGen/ms-declspecs.c
@@ -5,6 +5,10 @@ const __declspec(selectany) int x2 = 2;
// CHECK: @x1 = weak_odr global i32 1, comdat, align 4
// CHECK: @x2 = weak_odr constant i32 2, comdat, align 4
+// selectany turns extern variable declarations into definitions.
+extern __declspec(selectany) int x3;
+// CHECK: @x3 = weak_odr global i32 0, comdat, align 4
+
struct __declspec(align(16)) S {
char x;
};
diff --git a/clang/test/CodeGen/ms-declspecs.cpp b/clang/test/CodeGen/ms-declspecs.cpp
new file mode 100644
index 00000000000..f77c7cb8916
--- /dev/null
+++ b/clang/test/CodeGen/ms-declspecs.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s
+
+// selectany turns extern "C" variable declarations into definitions.
+extern __declspec(selectany) int x1;
+extern "C" __declspec(selectany) int x2;
+extern "C++" __declspec(selectany) int x3;
+extern "C" {
+__declspec(selectany) int x4;
+}
+// CHECK: @"\01?x1@@3HA" = weak_odr global i32 0, comdat, align 4
+// CHECK: @x2 = weak_odr global i32 0, comdat, align 4
+// CHECK: @"\01?x3@@3HA" = weak_odr global i32 0, comdat, align 4
+// CHECK: @x4 = weak_odr global i32 0, comdat, align 4
OpenPOWER on IntegriCloud