Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -201,6 +201,13 @@ if (D.getTLSKind()) CGM.setTLSMode(GV, D); + if (D.isExternallyVisible()) { + if (D.hasAttr()) + GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); + else if (D.hasAttr()) + GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass); + } + // Make sure the result is of the correct type. unsigned ExpectedAddrSpace = CGM.getContext().getTargetAddressSpace(Ty); if (AddrSpace != ExpectedAddrSpace) { Index: lib/CodeGen/MicrosoftCXXABI.cpp =================================================================== --- lib/CodeGen/MicrosoftCXXABI.cpp +++ lib/CodeGen/MicrosoftCXXABI.cpp @@ -1425,12 +1425,13 @@ Out.flush(); } - // Create the guard variable with a zero-initializer. Just absorb linkage - // and visibility from the guarded variable. + // Create the guard variable with a zero-initializer. Just absorb linkage, + // visibility and dll storage clsas from the guarded variable. GI->Guard = new llvm::GlobalVariable(CGM.getModule(), GuardTy, false, GV->getLinkage(), Zero, GuardName.str()); GI->Guard->setVisibility(GV->getVisibility()); + GI->Guard->setDLLStorageClass(GV->getDLLStorageClass()); } else { assert(GI->Guard->getLinkage() == GV->getLinkage() && "static local from the same function had different linkage"); Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -9105,6 +9105,21 @@ checkAttributesAfterMerging(*this, *VD); + // Static locals inherit dll attributes from their function. + if (VD->isStaticLocal()) { + if (FunctionDecl *FD = + dyn_cast(VD->getParentFunctionOrMethod())) { + Attr *A = FD->getAttr(); + if (!A) + A = FD->getAttr(); + if (A) { + auto *NewAttr = cast(A->clone(getASTContext())); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + } + } + } + // Imported static data members cannot be defined out-of-line. if (const DLLImportAttr *IA = VD->getAttr()) { if (VD->isStaticDataMember() && VD->isOutOfLine() && Index: test/CodeGenCXX/dllexport.cpp =================================================================== --- test/CodeGenCXX/dllexport.cpp +++ test/CodeGenCXX/dllexport.cpp @@ -254,7 +254,24 @@ // GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv() namespace ns { __declspec(dllexport) void externalFunc() {} } +//===----------------------------------------------------------------------===// +// Static locals +//===----------------------------------------------------------------------===// +int f(); +// M32-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0 +// M32-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0 +int __declspec(dllexport) nonInlineStaticLocalsFunc() { + static int x = f(); + return x++; +}; + +// M32-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0 +// M32-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0 +inline int __declspec(dllexport) inlineStaticLocalsFunc() { + static int x = f(); + return x++; +}; //===----------------------------------------------------------------------===// // Function templates Index: test/CodeGenCXX/dllimport.cpp =================================================================== --- test/CodeGenCXX/dllimport.cpp +++ test/CodeGenCXX/dllimport.cpp @@ -285,6 +285,20 @@ //===----------------------------------------------------------------------===// +// Static locals +//===----------------------------------------------------------------------===// + +int f(); +// MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0 +// MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0 +inline int __declspec(dllimport) inlineStaticLocalsFunc() { + static int x = f(); + return x++; +}; +USE(inlineStaticLocalsFunc); + + +//===----------------------------------------------------------------------===// // Function templates //===----------------------------------------------------------------------===//