summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-05-15 22:07:49 +0000
committerHans Wennborg <hans@hanshq.net>2014-05-15 22:07:49 +0000
commitb0f2f146bb6574ec8eba5ead788d95f47a7cc3ba (patch)
tree4c1326f49266952e3130fcc5f3c723f7343d588b /clang/lib/AST/ASTContext.cpp
parent03efd41bc04c44afc5e3fb5789288f3a327b0cbc (diff)
downloadbcm5719-llvm-b0f2f146bb6574ec8eba5ead788d95f47a7cc3ba.tar.gz
bcm5719-llvm-b0f2f146bb6574ec8eba5ead788d95f47a7cc3ba.zip
Allow dllimport/dllexport on inline functions and adjust the linkage.
This is a step towards handling these attributes on classes (PR11170). Differential Revision: http://reviews.llvm.org/D3772 llvm-svn: 208925
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r--clang/lib/AST/ASTContext.cpp38
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())
OpenPOWER on IntegriCloud