r208925 - Allow dllimport/dllexport on inline functions and adjust the linkage.

Hans Wennborg hans at hanshq.net
Thu May 15 15:07:49 PDT 2014


Author: hans
Date: Thu May 15 17:07:49 2014
New Revision: 208925

URL: http://llvm.org/viewvc/llvm-project?rev=208925&view=rev
Log:
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

Added:
    cfe/trunk/test/CodeGen/dllexport.c
    cfe/trunk/test/CodeGenCXX/dllexport.cpp
    cfe/trunk/test/CodeGenCXX/dllimport.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/dllexport.c
    cfe/trunk/test/Sema/dllimport.c
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
    cfe/trunk/test/SemaCXX/dllexport.cpp
    cfe/trunk/test/SemaCXX/dllimport.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 15 17:07:49 2014
@@ -2091,6 +2091,8 @@ def warn_attribute_invalid_on_definition
   InGroup<IgnoredAttributes>;
 def err_attribute_dll_redeclaration : Error<
   "redeclaration of %q0 cannot add %q1 attribute">;
+def err_attribute_dllimport_function_definition : Error<
+  "dllimport cannot be applied to non-inline function definition">;
 def err_attribute_dllimport_data_definition : Error<
   "definition of dllimport data">;
 def err_attribute_weakref_not_static : Error<

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu May 15 17:07:49 2014
@@ -7742,7 +7742,8 @@ QualType ASTContext::GetBuiltinType(unsi
   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::GetGVALinkageForF
   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::GetGVALinkageForF
   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::GetGVALinkageForV
     // 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::GetGVALinkageForV
   // 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::GetGVALinkageForV
   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())

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu May 15 17:07:49 2014
@@ -2572,7 +2572,7 @@ bool FunctionDecl::isMSExternInline() co
   assert(isInlined() && "expected to get called on an inlined function!");
 
   const ASTContext &Context = getASTContext();
-  if (!Context.getLangOpts().MSVCCompat)
+  if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>())
     return false;
 
   for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDecl())

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu May 15 17:07:49 2014
@@ -1960,15 +1960,6 @@ llvm::GlobalValue::LinkageTypes CodeGenM
   if (Linkage == GVA_AvailableExternally)
     return llvm::Function::AvailableExternallyLinkage;
 
-  // LinkOnceODRLinkage is insufficient if the symbol is required to exist in
-  // the symbol table.  Promote the linkage to WeakODRLinkage to preserve the
-  // semantics of LinkOnceODRLinkage while providing visibility in the symbol
-  // table.
-  llvm::GlobalValue::LinkageTypes OnceLinkage =
-      llvm::GlobalValue::LinkOnceODRLinkage;
-  if (D->hasAttr<DLLExportAttr>() || D->hasAttr<DLLImportAttr>())
-    OnceLinkage = llvm::GlobalVariable::WeakODRLinkage;
-
   // Note that Apple's kernel linker doesn't support symbol
   // coalescing, so we need to avoid linkonce and weak linkages there.
   // Normally, this means we just map to internal, but for explicit
@@ -1981,7 +1972,7 @@ llvm::GlobalValue::LinkageTypes CodeGenM
   // merged with other definitions. c) C++ has the ODR, so we know the
   // definition is dependable.
   if (Linkage == GVA_DiscardableODR)
-    return !Context.getLangOpts().AppleKext ? OnceLinkage
+    return !Context.getLangOpts().AppleKext ? llvm::Function::LinkOnceODRLinkage
                                             : llvm::Function::InternalLinkage;
 
   // An explicit instantiation of a template has weak linkage, since
@@ -1995,14 +1986,14 @@ llvm::GlobalValue::LinkageTypes CodeGenM
   // Destructor variants in the Microsoft C++ ABI are always linkonce_odr thunks
   // emitted on an as-needed basis.
   if (UseThunkForDtorVariant)
-    return OnceLinkage;
+    return llvm::GlobalValue::LinkOnceODRLinkage;
 
   // If required by the ABI, give definitions of static data members with inline
   // initializers at least linkonce_odr linkage.
   if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
       isa<VarDecl>(D) &&
       isVarDeclInlineInitializedStaticDataMember(cast<VarDecl>(D)))
-    return OnceLinkage;
+    return llvm::GlobalValue::LinkOnceODRLinkage;
 
   // C++ doesn't have tentative definitions and thus cannot have common
   // linkage.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu May 15 17:07:49 2014
@@ -9764,20 +9764,12 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop
   if (const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>())
     ResolveExceptionSpec(D->getLocation(), FPT);
 
-  // Checking attributes of current function definition
-  // dllimport attribute.
-  DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
-  if (DA && (!FD->hasAttr<DLLExportAttr>())) {
-    // dllimport attribute cannot be directly applied to definition.
-    // Microsoft accepts dllimport for functions defined within class scope. 
-    if (!DA->isInherited() &&
-        !(LangOpts.MicrosoftExt && FD->getLexicalDeclContext()->isRecord())) {
-      Diag(FD->getLocation(),
-           diag::err_attribute_can_be_applied_only_to_symbol_declaration)
-        << DA;
-      FD->setInvalidDecl();
-      return D;
-    }
+  // dllimport cannot be applied to non-inline function definitions.
+  if (FD->hasAttr<DLLImportAttr>() && !FD->isInlined()) {
+    assert(!FD->hasAttr<DLLExportAttr>());
+    Diag(FD->getLocation(), diag::err_attribute_dllimport_function_definition);
+    FD->setInvalidDecl();
+    return D;
   }
   // We want to attach documentation to original Decl (which might be
   // a function template).

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu May 15 17:07:49 2014
@@ -3841,13 +3841,6 @@ static void handleDLLImportAttr(Sema &S,
     return;
   }
 
-  // Currently, the dllimport attribute is ignored for inlined functions.
-  // Warning is emitted.
-  if (FD && FD->isInlineSpecified()) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
-    return;
-  }
-
   unsigned Index = Attr.getAttributeSpellingListIndex();
   DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
   if (NewAttr)
@@ -3868,14 +3861,6 @@ DLLExportAttr *Sema::mergeDLLExportAttr(
 }
 
 static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  // Currently, the dllexport attribute is ignored for inlined functions, unless
-  // the -fkeep-inline-functions flag has been used. Warning is emitted.
-  if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isInlineSpecified()) {
-    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
-    return;
-  }
-
   unsigned Index = Attr.getAttributeSpellingListIndex();
   DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
   if (NewAttr)

Added: cfe/trunk/test/CodeGen/dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/dllexport.c?rev=208925&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/dllexport.c (added)
+++ cfe/trunk/test/CodeGen/dllexport.c Thu May 15 17:07:49 2014
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c99 -O2 -disable-llvm-optzns -emit-llvm < %s | FileCheck %s
+
+#define DLLEXPORT __declspec(dllexport)
+
+inline void DLLEXPORT f() {}
+extern void DLLEXPORT f();
+
+// CHECK: define weak_odr dllexport void @f()

Added: cfe/trunk/test/CodeGenCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=208925&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllexport.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Thu May 15 17:07:49 2014
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -x c++ -O2 -disable-llvm-optzns -emit-llvm < %s | FileCheck %s
+
+#define DLLEXPORT __declspec(dllexport)
+
+void DLLEXPORT a();
+// CHECK-DAG: declare dllexport void @"\01?a@@YAXXZ"()
+
+inline void DLLEXPORT b() {}
+// CHECK-DAG: define weak_odr dllexport void @"\01?b@@YAXXZ"()
+
+template <typename T> void c() {}
+template void DLLEXPORT c<int>();
+// CHECK-DAG: define weak_odr dllexport void @"\01??$c at H@@YAXXZ"()
+
+struct S {
+  void DLLEXPORT a() {}
+  // CHECK-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a at S@@QAEXXZ"
+};
+
+void user() {
+  // FIXME: dllexported functions must be emitted even if they're not referenced in this TU.
+  a();
+  b();
+  &S::a;
+}

Added: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=208925&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Thu May 15 17:07:49 2014
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -x c++ -O2 -disable-llvm-optzns -emit-llvm < %s | FileCheck %s
+
+#define DLLIMPORT __declspec(dllimport)
+
+void DLLIMPORT a();
+// CHECK-DAG: declare dllimport void @"\01?a@@YAXXZ"()
+
+inline void DLLIMPORT b() {}
+// CHECK-DAG: define available_externally dllimport void @"\01?b@@YAXXZ"()
+
+template <typename T> inline void c() {} // FIXME: MSVC accepts this without 'inline' too.
+template void DLLIMPORT c<int>();
+// CHECK-DAG: define available_externally dllimport void @"\01??$c at H@@YAXXZ"()
+
+struct S {
+  void DLLIMPORT a() {}
+  // CHECK-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a at S@@QAEXXZ"
+};
+
+void user(S* s) {
+  a();
+  b();
+  c<int>();
+  s->a();
+}

Modified: cfe/trunk/test/Sema/dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllexport.c?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/test/Sema/dllexport.c (original)
+++ cfe/trunk/test/Sema/dllexport.c Thu May 15 17:07:49 2014
@@ -69,10 +69,10 @@ void __declspec(dllexport)      decl2B()
 __declspec(dllexport) void def() {}
 
 // Export inline function.
-__declspec(dllexport) inline void inlineFunc1() {} // expected-warning{{'dllexport' attribute ignored}}
+__declspec(dllexport) inline void inlineFunc1() {}
 extern void inlineFunc1();
 
-inline void __attribute__((dllexport)) inlineFunc2() {} // expected-warning{{'dllexport' attribute ignored}}
+inline void __attribute__((dllexport)) inlineFunc2() {}
 extern void inlineFunc2();
 
 // Redeclarations

Modified: cfe/trunk/test/Sema/dllimport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport.c?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/test/Sema/dllimport.c (original)
+++ cfe/trunk/test/Sema/dllimport.c Thu May 15 17:07:49 2014
@@ -97,11 +97,11 @@ void __attribute__((dllimport)) decl2A()
 void __declspec(dllimport)      decl2B();
 
 // Not allowed on function definitions.
-__declspec(dllimport) void def() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
 
 // Import inline function.
-__declspec(dllimport) inline void inlineFunc1() {} // expected-warning{{'dllimport' attribute ignored}}
-inline void __attribute__((dllimport)) inlineFunc2() {} // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) inline void inlineFunc1() {}
+inline void __attribute__((dllimport)) inlineFunc2() {}
 
 // Redeclarations
 __declspec(dllimport) void redecl1();

Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Thu May 15 17:07:49 2014
@@ -122,7 +122,7 @@ __declspec(dllimport) void f(void) { }
 void f2(void); // expected-note{{previous declaration is here}}
 };
 
-__declspec(dllimport) void AAA::f2(void) { // expected-error{{'dllimport' attribute can be applied only to symbol}}
+__declspec(dllimport) void AAA::f2(void) { // expected-error{{dllimport cannot be applied to non-inline function definition}}
                                            // expected-error at -1{{redeclaration of 'AAA::f2' cannot add 'dllimport' attribute}}
 
 }

Modified: cfe/trunk/test/SemaCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllexport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllexport.cpp Thu May 15 17:07:49 2014
@@ -92,10 +92,10 @@ __declspec(dllexport) void def() {}
 extern "C" __declspec(dllexport) void externC() {}
 
 // Export inline function.
-__declspec(dllexport) inline void inlineFunc1() {} // expected-warning{{'dllexport' attribute ignored}}
-inline void __attribute__((dllexport)) inlineFunc2() {} // expected-warning{{'dllexport' attribute ignored}}
+__declspec(dllexport) inline void inlineFunc1() {}
+inline void __attribute__((dllexport)) inlineFunc2() {}
 
-__declspec(dllexport) inline void inlineDecl(); // expected-warning{{'dllexport' attribute ignored}}
+__declspec(dllexport) inline void inlineDecl();
                              void inlineDecl() {}
 
 __declspec(dllexport) void inlineDef();
@@ -188,7 +188,7 @@ template void exportedFuncTmpl<ExplicitI
 // Export specialization of an exported function template.
 template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
 template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
-template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {} // expected-warning{{'dllexport' attribute ignored}}
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
 
 // Not exporting specialization of an exported function template without
 // explicit dllexport.
@@ -205,7 +205,7 @@ template __declspec(dllexport) void func
 // Export specialization of a non-exported function template.
 template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
 template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
-template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {} // expected-warning{{'dllexport' attribute ignored}}
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
 
 
 

Modified: cfe/trunk/test/SemaCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=208925&r1=208924&r2=208925&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllimport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Thu May 15 17:07:49 2014
@@ -116,14 +116,14 @@ void __attribute__((dllimport)) decl2A()
 void __declspec(dllimport)      decl2B();
 
 // Not allowed on function definitions.
-__declspec(dllimport) void def() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
 
 // extern  "C"
 extern "C" __declspec(dllexport) void externC();
 
 // Import inline function.
-__declspec(dllimport) inline void inlineFunc1() {} // expected-warning{{'dllimport' attribute ignored}}
-inline void __attribute__((dllimport)) inlineFunc2() {} // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) inline void inlineFunc1() {}
+inline void __attribute__((dllimport)) inlineFunc2() {}
 
 // Redeclarations
 __declspec(dllimport) void redecl1();
@@ -209,8 +209,8 @@ template<typename T> __declspec(dllimpor
 // Import specialization of an imported function template. A definition must be
 // declared inline.
 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
-template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} // expected-warning{{'dllimport' attribute ignored}}
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
 
 // Not importing specialization of an imported function template without
 // explicit dllimport.
@@ -223,5 +223,5 @@ extern template __declspec(dllimport) vo
 // Import specialization of a non-imported function template. A definition must
 // be declared inline.
 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
-template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} // expected-warning{{'dllimport' attribute ignored}}
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}





More information about the cfe-commits mailing list