forked from OSchip/llvm-project
PR41817: Fix regression in r359260 that caused the MS compatibility
extension allowing a "static" declaration to follow an "extern" declaration to stop working. llvm-svn: 360637
This commit is contained in:
parent
d64455cd43
commit
3bde7bf3e0
|
@ -613,12 +613,41 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
|
|||
static StorageClass getStorageClass(const Decl *D) {
|
||||
if (auto *TD = dyn_cast<TemplateDecl>(D))
|
||||
D = TD->getTemplatedDecl();
|
||||
if (D) {
|
||||
if (auto *VD = dyn_cast<VarDecl>(D))
|
||||
return VD->getStorageClass();
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(D))
|
||||
return FD->getStorageClass();
|
||||
if (!D)
|
||||
return SC_None;
|
||||
|
||||
if (auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
// Generally, the storage class is determined by the first declaration.
|
||||
auto SC = VD->getCanonicalDecl()->getStorageClass();
|
||||
|
||||
// ... except that MSVC permits an 'extern' declaration to be redeclared
|
||||
// 'static' as an extension.
|
||||
if (SC == SC_Extern) {
|
||||
for (auto *Redecl : VD->redecls()) {
|
||||
if (Redecl->getStorageClass() == SC_Static)
|
||||
return SC_Static;
|
||||
if (Redecl->getStorageClass() != SC_Extern &&
|
||||
!Redecl->isLocalExternDecl() && !Redecl->getFriendObjectKind())
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SC;
|
||||
}
|
||||
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
auto SC = FD->getCanonicalDecl()->getStorageClass();
|
||||
if (SC == SC_Extern) {
|
||||
for (auto *Redecl : FD->redecls()) {
|
||||
if (Redecl->getStorageClass() == SC_Static)
|
||||
return SC_Static;
|
||||
if (Redecl->getStorageClass() != SC_Extern &&
|
||||
!Redecl->isLocalExternDecl() && !Redecl->getFriendObjectKind())
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SC;
|
||||
}
|
||||
|
||||
return SC_None;
|
||||
}
|
||||
|
||||
|
@ -634,7 +663,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
|
|||
// A name having namespace scope (3.3.6) has internal linkage if it
|
||||
// is the name of
|
||||
|
||||
if (getStorageClass(D->getCanonicalDecl()) == SC_Static) {
|
||||
if (getStorageClass(D) == SC_Static) {
|
||||
// - a variable, variable template, function, or function template
|
||||
// that is explicitly declared static; or
|
||||
// (This bullet corresponds to C99 6.2.2p3.)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %clang_cc1 -emit-llvm %s -o - -fms-extensions -triple x86_64-windows | FileCheck %s
|
||||
|
||||
// CHECK: @n = internal global i32 1
|
||||
extern int n;
|
||||
static int n = 1;
|
||||
int *use = &n;
|
||||
|
||||
// CHECK: define internal void @f(
|
||||
extern void f();
|
||||
static void f() {}
|
||||
void g() { return f(); }
|
Loading…
Reference in New Issue