forked from OSchip/llvm-project
Inherit dll attributes to static locals
This makes us handle static locals in exported/imported functions correctly. Differential Revision: http://reviews.llvm.org/D4136 llvm-svn: 211173
This commit is contained in:
parent
dbb3e3e64f
commit
ef2272c49e
|
@ -74,6 +74,18 @@ inline void MarkVarDeclODRUsed(VarDecl *Var,
|
|||
|
||||
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
|
||||
|
|
|
@ -201,6 +201,13 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
|
|||
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) {
|
||||
|
|
|
@ -1425,12 +1425,13 @@ void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
|
|||
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");
|
||||
|
|
|
@ -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() &&
|
||||
|
|
|
@ -4347,17 +4347,6 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
|
|||
}
|
||||
}
|
||||
|
||||
/// \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);
|
||||
|
|
|
@ -72,6 +72,22 @@ namespace ns { __declspec(dllexport) int ExternalGlobal; }
|
|||
// 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++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue