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@4HA" = internal {{(unnamed_addr )*}}global i32 0 +// MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0 +int __declspec(dllexport) nonInlineStaticLocalsFunc() { + static int x = f(); + return x++; +}; + +// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0 +// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@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@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); + //===----------------------------------------------------------------------===// _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
