From 56fc62bf01a8f2a9ff9590fa768b3e9ff7ad4c0b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jul 2014 20:25:23 +0000 Subject: MS compatibility: always emit dllexported in-class initialized static data members (PR20140) This makes us emit dllexported in-class initialized static data members (which are treated as definitions in MSVC), even when they're not referenced. It also makes their special linkage reflected in the GVA linkage instead of getting massaged in CodeGen. Differential Revision: http://reviews.llvm.org/D4563 llvm-svn: 213304 --- clang/lib/AST/ASTContext.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'clang/lib/AST') diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5c271f027fe..bccdae91d2e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4781,6 +4781,12 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const { return sz; } +bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { + return getLangOpts().MSVCCompat && VD->isStaticDataMember() && + VD->getType()->isIntegralOrEnumerationType() && + !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); +} + static inline std::string charUnitsToString(const CharUnits &CU) { return llvm::itostr(CU.getQuantity()); @@ -7849,6 +7855,12 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, : StaticLocalLinkage; } + // MSVC treats in-class initialized static data members as definitions. + // By giving them non-strong linkage, out-of-line definitions won't + // cause link errors. + if (Context.isMSStaticDataMemberInlineDefinition(VD)) + return GVA_DiscardableODR; + switch (VD->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: @@ -7934,7 +7946,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { const VarDecl *VD = cast(D); assert(VD->isFileVarDecl() && "Expected file scoped var"); - if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly) + if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly && + !isMSStaticDataMemberInlineDefinition(VD)) return false; // Variables that can be needed in other TUs are required. -- cgit v1.2.3