diff options
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index aa74e1a6924..2f406166690 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -7742,7 +7742,8 @@ QualType ASTContext::GetBuiltinType(unsigned Id, return getFunctionType(ResType, ArgTypes, EPI); } -GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { +static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, + const FunctionDecl *FD) { if (!FD->isExternallyVisible()) return GVA_Internal; @@ -7773,8 +7774,11 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { if (!FD->isInlined()) return External; - if ((!getLangOpts().CPlusPlus && !getLangOpts().MSVCCompat) || + if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat && + !FD->hasAttr<DLLExportAttr>()) || FD->hasAttr<GNUInlineAttr>()) { + // FIXME: This doesn't match gcc's behavior for dllexport inline functions. + // GNU or C99 inline semantics. Determine whether this symbol should be // externally visible. if (FD->isInlineDefinitionExternallyVisible()) @@ -7793,7 +7797,26 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { return GVA_DiscardableODR; } -GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { +static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) { + // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx + // dllexport/dllimport on inline functions. + if (D->hasAttr<DLLImportAttr>()) { + if (L == GVA_DiscardableODR || L == GVA_StrongODR) + return GVA_AvailableExternally; + } else if (D->hasAttr<DLLExportAttr>()) { + if (L == GVA_DiscardableODR) + return GVA_StrongODR; + } + return L; +} + +GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { + return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD), + FD); +} + +static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, + const VarDecl *VD) { if (!VD->isExternallyVisible()) return GVA_Internal; @@ -7807,7 +7830,7 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { // enclosing function. if (LexicalContext) StaticLocalLinkage = - GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext)); + Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext)); // GVA_StrongODR function linkage is stronger than what we need, // downgrade to GVA_DiscardableODR. @@ -7821,7 +7844,7 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { // Itanium-specified entry point, which has the normal linkage of the // variable. if (VD->getTLSKind() == VarDecl::TLS_Dynamic && - getTargetInfo().getTriple().isMacOSX()) + Context.getTargetInfo().getTriple().isMacOSX()) return GVA_Internal; switch (VD->getTemplateSpecializationKind()) { @@ -7842,6 +7865,11 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { llvm_unreachable("Invalid Linkage!"); } +GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { + return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD), + VD); +} + bool ASTContext::DeclMustBeEmitted(const Decl *D) { if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (!VD->isFileVarDecl()) |