r211173 - Inherit dll attributes to static locals
Hans Wennborg
hans at hanshq.net
Wed Jun 18 08:55:13 PDT 2014
Author: hans
Date: Wed Jun 18 10:55:13 2014
New Revision: 211173
URL: http://llvm.org/viewvc/llvm-project?rev=211173&view=rev
Log:
Inherit dll attributes to static locals
This makes us handle static locals in exported/imported functions correctly.
Differential Revision: http://reviews.llvm.org/D4136
Modified:
cfe/trunk/include/clang/Sema/SemaInternal.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CodeGenCXX/dllexport.cpp
cfe/trunk/test/CodeGenCXX/dllimport.cpp
Modified: cfe/trunk/include/clang/Sema/SemaInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/SemaInternal.h?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/SemaInternal.h (original)
+++ cfe/trunk/include/clang/Sema/SemaInternal.h Wed Jun 18 10:55:13 2014
@@ -74,6 +74,18 @@ inline void MarkVarDeclODRUsed(VarDecl *
Var->markUsed(SemaRef.Context);
}
+
+/// Return a DLL attribute from the declaration.
+inline InheritableAttr *getDLLAttr(Decl *D) {
+ assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
+ "A declaration cannot be both dllimport and dllexport.");
+ if (auto *Import = D->getAttr<DLLImportAttr>())
+ return Import;
+ if (auto *Export = D->getAttr<DLLExportAttr>())
+ return Export;
+ return nullptr;
+}
+
}
#endif
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Jun 18 10:55:13 2014
@@ -201,6 +201,13 @@ CodeGenFunction::CreateStaticVarDecl(con
if (D.getTLSKind())
CGM.setTLSMode(GV, D);
+ if (D.isExternallyVisible()) {
+ if (D.hasAttr<DLLImportAttr>())
+ GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
+ else if (D.hasAttr<DLLExportAttr>())
+ GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
+ }
+
// Make sure the result is of the correct type.
unsigned ExpectedAddrSpace = CGM.getContext().getTargetAddressSpace(Ty);
if (AddrSpace != ExpectedAddrSpace) {
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Jun 18 10:55:13 2014
@@ -1425,12 +1425,13 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
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 class 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");
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jun 18 10:55:13 2014
@@ -9097,6 +9097,18 @@ Sema::FinalizeDeclaration(Decl *ThisDecl
checkAttributesAfterMerging(*this, *VD);
+ // Static locals inherit dll attributes from their function.
+ if (VD->isStaticLocal()) {
+ if (FunctionDecl *FD =
+ dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) {
+ if (Attr *A = getDLLAttr(FD)) {
+ auto *NewAttr = cast<InheritableAttr>(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<DLLImportAttr>()) {
if (VD->isStaticDataMember() && VD->isOutOfLine() &&
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 18 10:55:13 2014
@@ -4347,17 +4347,6 @@ static void CheckAbstractClassUsage(Abst
}
}
-/// \brief Return a DLL attribute from the declaration.
-static InheritableAttr *getDLLAttr(Decl *D) {
- assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
- "A declaration cannot be both dllimport and dllexport.");
- if (auto *Import = D->getAttr<DLLImportAttr>())
- return Import;
- if (auto *Export = D->getAttr<DLLExportAttr>())
- return Export;
- return nullptr;
-}
-
/// \brief Check class-level dllimport/dllexport attribute.
static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
Attr *ClassAttr = getDLLAttr(Class);
Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Wed Jun 18 10:55:13 2014
@@ -72,6 +72,22 @@ namespace ns { __declspec(dllexport) int
// GNU-DAG: @ExternalAutoTypeGlobal = dllexport global %struct.External zeroinitializer, align 4
__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+int f();
+// MSC-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ at 4HA" = internal {{(unnamed_addr )*}}global i32 0
+// MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ at 4IA" = internal {{(unnamed_addr )*}}global i32 0
+int __declspec(dllexport) nonInlineStaticLocalsFunc() {
+ static int x = f();
+ return x++;
+};
+
+// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ at 4HA" = weak_odr dllexport global i32 0
+// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ at 51" = weak_odr dllexport global i32 0
+// Note: MinGW doesn't seem to export the static local here.
+inline int __declspec(dllexport) inlineStaticLocalsFunc() {
+ static int x = f();
+ return x++;
+}
+
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=211173&r1=211172&r2=211173&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Wed Jun 18 10:55:13 2014
@@ -85,6 +85,15 @@ USEVAR(GlobalRedecl3)
namespace ns { __declspec(dllimport) int ExternalGlobal; }
USEVAR(ns::ExternalGlobal)
+int f();
+// MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ at 4HA" = available_externally dllimport global i32 0
+// MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ at 51" = available_externally dllimport global i32 0
+inline int __declspec(dllimport) inlineStaticLocalsFunc() {
+ static int x = f();
+ return x++;
+};
+USE(inlineStaticLocalsFunc);
+
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list