r209596 - IRGen: Add more tests for dll attributes

Nico Rieck nico.rieck at gmail.com
Sun May 25 03:34:17 PDT 2014


Author: nrieck
Date: Sun May 25 05:34:16 2014
New Revision: 209596

URL: http://llvm.org/viewvc/llvm-project?rev=209596&view=rev
Log:
IRGen: Add more tests for dll attributes

Added:
    cfe/trunk/test/CodeGen/dllimport.c
    cfe/trunk/test/CodeGenCXX/dllexport-members.cpp
    cfe/trunk/test/CodeGenCXX/dllimport-members.cpp
Removed:
    cfe/trunk/test/CodeGen/dllimport-dllexport.c
Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CodeGen/dllexport.c
    cfe/trunk/test/CodeGenCXX/dllexport.cpp
    cfe/trunk/test/CodeGenCXX/dllimport.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=209596&r1=209595&r2=209596&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun May 25 05:34:16 2014
@@ -5056,7 +5056,8 @@ Sema::ActOnVariableDeclarator(Scope *S,
   // dllimport globals without explicit storage class are treated as extern. We
   // have to change the storage class this early to get the right DeclContext.
   if (SC == SC_None && !DC->isRecord() &&
-      hasParsedAttr(S, D, AttributeList::AT_DLLImport))
+      hasParsedAttr(S, D, AttributeList::AT_DLLImport) &&
+      !hasParsedAttr(S, D, AttributeList::AT_DLLExport))
     SC = SC_Extern;
 
   DeclContext *OriginalDC = DC;

Modified: cfe/trunk/test/CodeGen/dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/dllexport.c?rev=209596&r1=209595&r2=209596&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/dllexport.c (original)
+++ cfe/trunk/test/CodeGen/dllexport.c Sun May 25 05:34:16 2014
@@ -1,8 +1,115 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -std=c99 -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
 
-#define DLLEXPORT __declspec(dllexport)
 
-inline void DLLEXPORT f() {}
-extern void DLLEXPORT f();
 
-// CHECK: define weak_odr dllexport void @f()
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+// CHECK-NOT: @ExternGlobalDecl
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+// CHECK-DAG: @GlobalDef = common dllexport global i32 0, align 4
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+// CHECK-DAG: @GlobalInit = dllexport global i32 1, align 4
+__declspec(dllexport) int GlobalInit = 1;
+
+// Declare, then export definition.
+// CHECK-DAG: @GlobalDeclInit = dllexport global i32 1, align 4
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+// CHECK-DAG: @GlobalRedecl1 = common dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport)        int GlobalRedecl1;
+
+// CHECK-DAG: @GlobalRedecl2 = common dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl2;
+                             int GlobalRedecl2;
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// Export function definition.
+// CHECK-DAG: define dllexport void @def()
+__declspec(dllexport) void def(void) {}
+
+// Export inline function.
+// CHECK-DAG: define weak_odr dllexport void @inlineFunc()
+// CHECK-DAG: define weak_odr dllexport void @externInlineFunc()
+__declspec(dllexport) inline void inlineFunc(void) {}
+__declspec(dllexport) inline void externInlineFunc(void) {}
+extern void externInlineFunc(void);
+
+// Redeclarations
+// CHECK-DAG: define dllexport void @redecl1()
+__declspec(dllexport) void redecl1(void);
+__declspec(dllexport) void redecl1(void) {}
+
+// CHECK-DAG: define dllexport void @redecl2()
+__declspec(dllexport) void redecl2(void);
+                      void redecl2(void) {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over the dllimport if both are specified.
+// CHECK-DAG: @PrecedenceGlobal1A = common dllexport global i32 0, align 4
+// CHECK-DAG: @PrecedenceGlobal1B = common dllexport global i32 0, align 4
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A;
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B;
+
+// CHECK-DAG: @PrecedenceGlobal2A = common dllexport global i32 0, align 4
+// CHECK-DAG: @PrecedenceGlobal2B = common dllexport global i32 0, align 4
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A;
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B;
+
+// CHECK-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1 = 0;
+
+// CHECK-DAG: @PrecedenceGlobalRedecl2 = common dllexport global i32 0, align 4
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+// CHECK-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 1, align 4
+__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
+__declspec(dllimport)             int PrecedenceGlobalMixed1 = 1;
+
+// CHECK-DAG: @PrecedenceGlobalMixed2 = common dllexport global i32 0, align 4
+__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
+__declspec(dllexport)             int PrecedenceGlobalMixed2;
+
+// CHECK-DAG: define dllexport void @precedence1A()
+// CHECK-DAG: define dllexport void @precedence1B()
+void __attribute__((dllimport, dllexport))       precedence1A(void) {}
+void __declspec(dllimport) __declspec(dllexport) precedence1B(void) {}
+
+// CHECK-DAG: define dllexport void @precedence2A()
+// CHECK-DAG: define dllexport void @precedence2B()
+void __attribute__((dllexport, dllimport))       precedence2A(void) {}
+void __declspec(dllexport) __declspec(dllimport) precedence2B(void) {}
+
+// CHECK-DAG: define dllexport void @precedenceRedecl1()
+void __declspec(dllimport) precedenceRedecl1(void);
+void __declspec(dllexport) precedenceRedecl1(void) {}
+
+// CHECK-DAG: define dllexport void @precedenceRedecl2()
+void __declspec(dllexport) precedenceRedecl2(void);
+void __declspec(dllimport) precedenceRedecl2(void) {}

Removed: cfe/trunk/test/CodeGen/dllimport-dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/dllimport-dllexport.c?rev=209595&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/dllimport-dllexport.c (original)
+++ cfe/trunk/test/CodeGen/dllimport-dllexport.c (removed)
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s
-
-__attribute__((dllexport)) int bar1 = 2;
-// CHECK-LABEL: @bar1 = dllexport global i32 2
-__attribute__((dllimport)) extern int bar2;
-// CHECK-LABEL: @bar2 = external dllimport global i32
-
-void __attribute__((dllimport)) foo1();
-void __attribute__((dllexport)) foo1(){}
-// CHECK-LABEL: define dllexport void @foo1
-void __attribute__((dllexport)) foo2();
-
-// PR6269
-__declspec(dllimport) void foo3();
-__declspec(dllexport) void foo3(){}
-// CHECK-LABEL: define dllexport void @foo3
-__declspec(dllexport) void foo4();
-
-__declspec(dllimport) void foo5();
-// CHECK-LABEL: declare dllimport void @foo5
-
-int use() { foo5(); return bar2; }

Added: cfe/trunk/test/CodeGen/dllimport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/dllimport.c?rev=209596&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/dllimport.c (added)
+++ cfe/trunk/test/CodeGen/dllimport.c Sun May 25 05:34:16 2014
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define USEVAR(var) int JOIN(use, __LINE__)() { return var; }
+#define USE(func) void JOIN(use, __LINE__)() { func(); }
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// CHECK: @ExternGlobalDecl = external dllimport global i32
+__declspec(dllimport) extern int ExternGlobalDecl;
+USEVAR(ExternGlobalDecl)
+
+// dllimport implies a declaration.
+// CHECK: @GlobalDecl = external dllimport global i32
+__declspec(dllimport) int GlobalDecl;
+USEVAR(GlobalDecl)
+
+// Redeclarations
+// CHECK: @GlobalRedecl1 = external dllimport global i32
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+USEVAR(GlobalRedecl1)
+
+// CHECK: @GlobalRedecl2 = external dllimport global i32
+__declspec(dllimport) int GlobalRedecl2;
+__declspec(dllimport) int GlobalRedecl2;
+USEVAR(GlobalRedecl2)
+
+// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// CHECK: @GlobalRedecl3 = external global i32
+__declspec(dllimport) extern int GlobalRedecl3;
+                      extern int GlobalRedecl3; // dllimport ignored
+USEVAR(GlobalRedecl3)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration.
+// CHECK-DAG: declare dllimport void @decl()
+__declspec(dllimport) void decl(void);
+USE(decl)
+
+// Import inline function.
+// CHECK-DAG: declare dllimport void @inlineFunc()
+// O1-DAG: define available_externally dllimport void @inlineFunc()
+__declspec(dllimport) inline void inlineFunc(void) {}
+USE(inlineFunc)
+
+// inline attributes
+// CHECK-DAG: declare dllimport void @noinline()
+// O1-DAG: define available_externally dllimport void @noinline()
+// CHECK-NOT: @alwaysInline()
+// O1-NOT: @alwaysInline()
+__declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {}
+__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {}
+USE(noinline)
+USE(alwaysInline)
+
+// Redeclarations
+// CHECK-DAG: declare dllimport void @redecl1()
+__declspec(dllimport) void redecl1(void);
+__declspec(dllimport) void redecl1(void);
+USE(redecl1)
+
+// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// CHECK-DAG: declare void @redecl2()
+__declspec(dllimport) void redecl2(void);
+                      void redecl2(void);
+USE(redecl2)
+
+// CHECK-DAG: define void @redecl3()
+__declspec(dllimport) void redecl3(void);
+                      void redecl3(void) {} // dllimport ignored
+USE(redecl3)

Added: cfe/trunk/test/CodeGenCXX/dllexport-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport-members.cpp?rev=209596&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllexport-members.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/dllexport-members.cpp Sun May 25 05:34:16 2014
@@ -0,0 +1,657 @@
+// RUN: %clang_cc1 -triple i686-win32     -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-mingw32   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+
+extern "C" void* malloc(__SIZE_TYPE__ size);
+extern "C" void free(void* p);
+
+// Used to force non-trivial special members.
+struct ForceNonTrivial {
+  ForceNonTrivial();
+  ~ForceNonTrivial();
+  ForceNonTrivial(const ForceNonTrivial&);
+  ForceNonTrivial& operator=(const ForceNonTrivial&);
+  ForceNonTrivial(ForceNonTrivial&&);
+  ForceNonTrivial& operator=(ForceNonTrivial&&);
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class.
+struct ExportMembers {
+  struct Nested;
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?normalDef at ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?normalDef at ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass at ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInclass at ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDef at ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDef at ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDecl at ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDecl at ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInclass() {}
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?virtualDef at ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?virtualDef at ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInclass at ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInclass at ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDef at ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDef at ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDecl at ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDecl at ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this)
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInclass() {}
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define          dllexport                void @"\01?staticDef at ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInclass at ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDef at ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDecl at ExportMembers@@SAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers9staticDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers13staticInclassEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers15staticInlineDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16staticInlineDeclEv()
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInclass() {}
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?protectedDef at ExportMembers@@IAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?protectedDef at ExportMembers@@IEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this)
+  // MSC-DAG: define          dllexport                void @"\01?protectedStaticDef at ExportMembers@@KAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers18protectedStaticDefEv()
+protected:
+  __declspec(dllexport)                void protectedDef();
+  __declspec(dllexport) static         void protectedStaticDef();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?privateDef at ExportMembers@@AAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?privateDef at ExportMembers@@AEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this)
+  // MSC-DAG: define          dllexport                void @"\01?privateStaticDef at ExportMembers@@CAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers16privateStaticDefEv()
+private:
+  __declspec(dllexport)                void privateDef();
+  __declspec(dllexport) static         void privateStaticDef();
+
+  // M32-DAG: define                    x86_thiscallcc void @"\01?ignored at ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define                                   void @"\01?ignored at ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define                    x86_thiscallcc void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this)
+  // G64-DAG: define                                   void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField at ExportMembers@@2HA"               = dllexport global i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstField at ExportMembers@@2HB"          = dllexport constant i32 1, align 4
+  // FIXME: These three should be weak_odr.
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit at ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit at ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField at ExportMembers@@2HB"            = linkonce_odr dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers11StaticFieldE                   = dllexport global i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE              = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldBraceInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers14ConstexprFieldE                = dllexport constant i32 1, align 4
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+       void ExportMembers::normalDef() {}
+inline void ExportMembers::normalInlineDef() {}
+       void ExportMembers::normalInlineDecl() {}
+       void ExportMembers::virtualDef() {}
+inline void ExportMembers::virtualInlineDef() {}
+       void ExportMembers::virtualInlineDecl() {}
+       void ExportMembers::staticDef() {}
+inline void ExportMembers::staticInlineDef() {}
+       void ExportMembers::staticInlineDecl() {}
+       void ExportMembers::ignored() {}
+       void ExportMembers::protectedDef() {}
+       void ExportMembers::protectedStaticDef() {}
+       void ExportMembers::privateDef() {}
+       void ExportMembers::privateStaticDef() {}
+
+       int  ExportMembers::StaticField = 1;
+const  int  ExportMembers::StaticConstField = 1;
+const  int  ExportMembers::StaticConstFieldEqualInit;
+const  int  ExportMembers::StaticConstFieldBraceInit;
+constexpr int ExportMembers::ConstexprField;
+
+
+// Export individual members of a nested class.
+struct ExportMembers::Nested {
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?normalDef at Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?normalDef at Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass at Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInclass at Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDef at Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDef at Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDecl at Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDecl at Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInclass() {}
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?virtualDef at Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?virtualDef at Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInclass at Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInclass at Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDef at Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDef at Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDecl at Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDecl at Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInclass() {}
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define          dllexport                void @"\01?staticDef at Nested@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInclass at Nested@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDef at Nested@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDecl at Nested@ExportMembers@@SAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers6Nested9staticDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested13staticInclassEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested15staticInlineDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested16staticInlineDeclEv()
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInclass() {}
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?protectedDef at Nested@ExportMembers@@IAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?protectedDef at Nested@ExportMembers@@IEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this)
+  // MSC-DAG: define          dllexport                void @"\01?protectedStaticDef at Nested@ExportMembers@@KAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers6Nested18protectedStaticDefEv()
+protected:
+  __declspec(dllexport)                void protectedDef();
+  __declspec(dllexport) static         void protectedStaticDef();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?privateDef at Nested@ExportMembers@@AAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?privateDef at Nested@ExportMembers@@AEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this)
+  // MSC-DAG: define          dllexport                void @"\01?privateStaticDef at Nested@ExportMembers@@CAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers6Nested16privateStaticDefEv()
+private:
+  __declspec(dllexport)                void privateDef();
+  __declspec(dllexport) static         void privateStaticDef();
+
+  // M32-DAG: define                    x86_thiscallcc void @"\01?ignored at Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define                                   void @"\01?ignored at Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define                    x86_thiscallcc void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define                                   void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField at Nested@ExportMembers@@2HA"               = dllexport global i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstField at Nested@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit at Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit at Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField at Nested@ExportMembers@@2HB"            = linkonce_odr dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE                   = dllexport global i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE              = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldBraceInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested14ConstexprFieldE                = dllexport constant i32 1, align 4
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+       void ExportMembers::Nested::normalDef() {}
+inline void ExportMembers::Nested::normalInlineDef() {}
+       void ExportMembers::Nested::normalInlineDecl() {}
+       void ExportMembers::Nested::virtualDef() {}
+inline void ExportMembers::Nested::virtualInlineDef() {}
+       void ExportMembers::Nested::virtualInlineDecl() {}
+       void ExportMembers::Nested::staticDef() {}
+inline void ExportMembers::Nested::staticInlineDef() {}
+       void ExportMembers::Nested::staticInlineDecl() {}
+       void ExportMembers::Nested::ignored() {}
+       void ExportMembers::Nested::protectedDef() {}
+       void ExportMembers::Nested::protectedStaticDef() {}
+       void ExportMembers::Nested::privateDef() {}
+       void ExportMembers::Nested::privateStaticDef() {}
+
+       int  ExportMembers::Nested::StaticField = 1;
+const  int  ExportMembers::Nested::StaticConstField = 1;
+const  int  ExportMembers::Nested::StaticConstFieldEqualInit;
+const  int  ExportMembers::Nested::StaticConstFieldBraceInit;
+constexpr int ExportMembers::Nested::ConstexprField;
+
+
+// Export special member functions.
+struct ExportSpecials {
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE at XZ"(%struct.ExportSpecials* returned %this)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA at XZ"(%struct.ExportSpecials* returned %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this)
+  __declspec(dllexport) ExportSpecials();
+
+  // M32-DAG: define dllexport x86_thiscallcc void @"\01??1ExportSpecials@@QAE at XZ"(%struct.ExportSpecials* %this)
+  // M64-DAG: define dllexport                void @"\01??1ExportSpecials@@QEAA at XZ"(%struct.ExportSpecials* %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
+  __declspec(dllexport) ~ExportSpecials();
+
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE at ABU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA at AEBU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  __declspec(dllexport) ExportSpecials(const ExportSpecials&);
+
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0 at ABU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0 at AEBU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G64-DAG: define dllexport                %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
+
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@$$QAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  __declspec(dllexport) ExportSpecials(ExportSpecials&&);
+
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  // G64-DAG: define dllexport                %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*)
+  __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
+};
+ExportSpecials::ExportSpecials() {}
+ExportSpecials::~ExportSpecials() {}
+ExportSpecials::ExportSpecials(const ExportSpecials&) {}
+ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
+ExportSpecials::ExportSpecials(ExportSpecials&&) {}
+ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
+
+
+// Export class with inline special member functions.
+struct ExportInlineSpecials {
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE at XZ"(%struct.ExportInlineSpecials* returned %this)
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA at XZ"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1Ev(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1Ev(
+  __declspec(dllexport) ExportInlineSpecials() {}
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportInlineSpecials@@QAE at XZ"(
+  // M64-DAG: define weak_odr dllexport                void @"\01??1ExportInlineSpecials@@QEAA at XZ"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsD1Ev(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsD1Ev(
+  __declspec(dllexport) ~ExportInlineSpecials() {}
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE at ABU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA at AEBU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1ERKS_(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1ERKS_(
+  __declspec(dllexport) inline ExportInlineSpecials(const ExportInlineSpecials&);
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0 at ABU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0 at AEBU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+  // G64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+  __declspec(dllexport) ExportInlineSpecials& operator=(const ExportInlineSpecials&);
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@$$QAU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@$$QEAU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1EOS_(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1EOS_(
+  __declspec(dllexport) ExportInlineSpecials(ExportInlineSpecials&&) {}
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+  // G64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+  __declspec(dllexport) ExportInlineSpecials& operator=(ExportInlineSpecials&&) { return *this; }
+};
+ExportInlineSpecials::ExportInlineSpecials(const ExportInlineSpecials&) {}
+inline ExportInlineSpecials& ExportInlineSpecials::operator=(const ExportInlineSpecials&) { return *this; }
+
+
+// Export defaulted member function definitions.
+struct ExportDefaultedDefs {
+  __declspec(dllexport) ExportDefaultedDefs();
+  __declspec(dllexport) ~ExportDefaultedDefs();
+  __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
+  __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
+  __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
+  __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
+};
+
+// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE at XZ"(%struct.ExportDefaultedDefs* returned %this)
+// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA at XZ"(%struct.ExportDefaultedDefs* returned %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this)
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
+
+// M32-DAG: define dllexport x86_thiscallcc void @"\01??1ExportDefaultedDefs@@QAE at XZ"(%struct.ExportDefaultedDefs* %this)
+// M64-DAG: define dllexport                void @"\01??1ExportDefaultedDefs@@QEAA at XZ"(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
+ExportDefaultedDefs::~ExportDefaultedDefs() = default;
+
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE at ABU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
+// M64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA at AEBU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
+
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0 at ABU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// M64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0 at AEBU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
+
+// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
+// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
+
+// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+// G64-DAG: define dllexport                %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*)
+ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
+
+
+// Export allocation functions.
+struct ExportAlloc {
+  __declspec(dllexport) void* operator new(__SIZE_TYPE__);
+  __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
+  __declspec(dllexport) void operator delete(void*);
+  __declspec(dllexport) void operator delete[](void*);
+};
+
+// M32-DAG: define dllexport i8* @"\01??2ExportAlloc@@SAPAXI at Z"(i32 %n)
+// M64-DAG: define dllexport i8* @"\01??2ExportAlloc@@SAPEAX_K at Z"(i64 %n)
+// G32-DAG: define dllexport i8* @_ZN11ExportAllocnwEj(i32 %n)
+// G64-DAG: define dllexport i8* @_ZN11ExportAllocnwEy(i64 %n)
+void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
+
+// M32-DAG: define dllexport i8* @"\01??_UExportAlloc@@SAPAXI at Z"(i32 %n)
+// M64-DAG: define dllexport i8* @"\01??_UExportAlloc@@SAPEAX_K at Z"(i64 %n)
+// G32-DAG: define dllexport i8* @_ZN11ExportAllocnaEj(i32 %n)
+// G64-DAG: define dllexport i8* @_ZN11ExportAllocnaEy(i64 %n)
+void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
+
+// M32-DAG: define dllexport void @"\01??3ExportAlloc@@SAXPAX at Z"(i8* %p)
+// M64-DAG: define dllexport void @"\01??3ExportAlloc@@SAXPEAX at Z"(i8* %p)
+// G32-DAG: define dllexport void @_ZN11ExportAllocdlEPv(i8* %p)
+// G64-DAG: define dllexport void @_ZN11ExportAllocdlEPv(i8* %p)
+void ExportAlloc::operator delete(void* p) { free(p); }
+
+// M32-DAG: define dllexport void @"\01??_VExportAlloc@@SAXPAX at Z"(i8* %p)
+// M64-DAG: define dllexport void @"\01??_VExportAlloc@@SAXPEAX at Z"(i8* %p)
+// G32-DAG: define dllexport void @_ZN11ExportAllocdaEPv(i8* %p)
+// G64-DAG: define dllexport void @_ZN11ExportAllocdaEPv(i8* %p)
+void ExportAlloc::operator delete[](void* p) { free(p); }
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct MemFunTmpl {
+  template<typename T>                              void normalDef() {}
+  template<typename T> __declspec(dllexport)        void exportedNormal() {}
+  template<typename T>                       static void staticDef() {}
+  template<typename T> __declspec(dllexport) static void exportedStatic() {}
+};
+
+// Export implicit instantiation of an exported member function template.
+void useMemFunTmpl() {
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal at UImplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal at UImplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+  MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
+
+  // MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic at UImplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI21ImplicitInst_ExportedEEvv()
+  MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
+}
+
+
+// Export explicit instantiation declaration of an exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal at UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal at UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+       template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic at UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI21ExplicitDecl_ExportedEEvv()
+extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+       template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+
+
+// Export explicit instantiation definition of an exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal at UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal at UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic at UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI21ExplicitInst_ExportedEEvv()
+template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
+
+
+// Export specialization of an exported member function template.
+// M32-DAG: define          dllexport x86_thiscallcc void @"\01??$exportedNormal at UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define          dllexport                void @"\01??$exportedNormal at UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define          dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define          dllexport                void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
+
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal at UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal at UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
+
+// MSC-DAG: define          dllexport                void @"\01??$exportedStatic at UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define          dllexport                void @_ZN10MemFunTmpl14exportedStaticI25ExplicitSpec_Def_ExportedEEvv()
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic at UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI31ExplicitSpec_InlineDef_ExportedEEvv()
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
+
+
+// Not exporting specialization of an exported member function template without
+// explicit dllexport.
+// M32-DAG: define                    x86_thiscallcc void @"\01??$exportedNormal at UExplicitSpec_NotExported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define                                   void @"\01??$exportedNormal at UExplicitSpec_NotExported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define                    x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define                                   void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this)
+template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
+
+// M32-DAG: define                                   void @"\01??$exportedStatic at UExplicitSpec_NotExported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define                                   void @_ZN10MemFunTmpl14exportedStaticI24ExplicitSpec_NotExportedEEvv()
+template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef at UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$normalDef at UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+
+// M32-DAG: define weak_odr dllexport                void @"\01??$staticDef at UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ExportedEEvv()
+extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+
+
+// Export explicit instantiation definition of a non-exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef at UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$normalDef at UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$staticDef at UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ExportedEEvv()
+template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
+
+
+// Export specialization of a non-exported member function template.
+// M32-DAG: define          dllexport x86_thiscallcc void @"\01??$normalDef at UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define          dllexport                void @"\01??$normalDef at UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef at UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$normalDef at UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define          dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define          dllexport                void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
+
+// MSC-DAG: define          dllexport                void @"\01??$staticDef at UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"()
+// MSC-DAG: define weak_odr dllexport                void @"\01??$staticDef at UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define          dllexport                void @_ZN10MemFunTmpl9staticDefI25ExplicitSpec_Def_ExportedEEvv()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ExportedEEvv()
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
+};
+template<typename T> const int MemVarTmpl::StaticVar;
+template<typename T> const int MemVarTmpl::ExportedStaticVar;
+
+// Export implicit instantiation of an exported member variable template.
+// MSC-DAG: @"\01??$ExportedStaticVar at UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported member variable
+// template.
+// MSC-DAG: @"\01??$ExportedStaticVar at UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+       template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported member variable
+// template.
+// MSC-DAG: @"\01??$ExportedStaticVar at UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
+
+// Export specialization of an exported member variable template.
+// MSC-DAG: @"\01??$ExportedStaticVar at UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI25ExplicitSpec_Def_ExportedEE       = dllexport constant i32 1, align 4
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported member variable template without
+// explicit dllexport.
+// MSC-DAG: @"\01??$ExportedStaticVar at UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI24ExplicitSpec_NotExportedEE       = constant i32 1, align 4
+template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1;
+
+
+// Export explicit instantiation declaration of a non-exported member variable
+// template.
+// MSC-DAG: @"\01??$StaticVar at UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE        = weak_odr dllexport constant i32 1, align 4
+extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+       template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported member variable
+// template.
+// MSC-DAG: @"\01??$StaticVar at UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE        = weak_odr dllexport constant i32 1, align 4
+template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported member variable template.
+// MSC-DAG: @"\01??$StaticVar at UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI25ExplicitSpec_Def_ExportedEE        = dllexport constant i32 1, align 4
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;

Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=209596&r1=209595&r2=209596&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Sun May 25 05:34:16 2014
@@ -1,28 +1,449 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -x c++ -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
 
-#define DLLEXPORT __declspec(dllexport)
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+struct External { int v; };
 
-void DLLEXPORT a();
-// CHECK-DAG: declare dllexport void @"\01?a@@YAXXZ"()
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEVAR(var) int UNIQ(use)() { return var; }
+#define USE(func) void UNIQ(use)() { func(); }
+#define INSTVAR(var) template int var;
+#define INST(func) template void func();
 
-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"()
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
 
-struct S {
-  void DLLEXPORT a() {}
-  // CHECK-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a at S@@QAEXXZ"
+// Declarations are not exported.
+// MSC-NOT: @"\01?ExternGlobalDecl@@3HA"
+// GNU-NOT: @ExternGlobalDecl
+__declspec(dllexport) extern int ExternGlobalDecl;
 
-  struct T {
-    void DLLEXPORT a() {}
-    // CHECK-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a at T@S@@QAEXXZ"
-  };
+// dllexport implies a definition.
+// MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @GlobalDef            = dllexport global i32 0, align 4
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+// MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @GlobalInit1            = dllexport global i32 1, align 4
+__declspec(dllexport) int GlobalInit1 = 1;
+
+// MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @GlobalInit2            = dllexport global i32 1, align 4
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+// MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @GlobalDeclInit            = dllexport global i32 1, align 4
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @GlobalRedecl1            = dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport)        int GlobalRedecl1;
+
+// MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @GlobalRedecl2            = dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl2;
+                             int GlobalRedecl2;
+
+// MSC-DAG: @"\01?ExternalGlobal at ns@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @_ZN2ns14ExternalGlobalE      = dllexport global i32 0, align 4
+namespace ns { __declspec(dllexport) int ExternalGlobal; }
+
+// MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4
+// GNU-DAG: @ExternalAutoTypeGlobal                      = dllexport global %struct.External zeroinitializer, align 4
+__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// dllexport implies a definition.
+// MSC-NOT: @"\01??$VarTmplDef at UExplicitInst_Exported@@@@3HA"
+// GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
+template<typename T> __declspec(dllexport) int VarTmplDef;
+INSTVAR(VarTmplDef<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$VarTmplImplicitDef at UImplicitInst_Exported@@@@3HA" = external dllexport global
+// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE          = external dllexport global
+template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
+USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
+
+// Export definition.
+// MSC-DAG: @"\01??$VarTmplInit1 at UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
+INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$VarTmplInit2 at UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
+INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
+
+// Declare, then export definition.
+// MSC-DAG: @"\01??$VarTmplDeclInit at UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
+template<typename T>                              int VarTmplDeclInit = 1;
+INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
+
+// Redeclarations
+// MSC-DAG: @"\01??$VarTmplRedecl1 at UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
+INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$VarTmplRedecl2 at UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
+template<typename T>                              int VarTmplRedecl2 = 1;
+INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$ExternalVarTmpl at UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE        = weak_odr dllexport global i32 1, align 4
+namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
+INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl at UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4
+// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE                    = weak_odr dllexport global %struct.External zeroinitializer, align 4
+template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
+template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
+
+
+template<typename T> int VarTmpl = 1;
+template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
+
+// Export implicit instantiation of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl at UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
+
+// Export explicit instantiation declaration of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl at UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE          = weak_odr dllexport global i32 1, align 4
+extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
+       template int ExportedVarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl at UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl at UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE          = dllexport global i32 0, align 4
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
+
+// MSC-DAG: @"\01??$ExportedVarTmpl at UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE          = dllexport global i32 1, align 4
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported variable template without
+// explicit dllexport.
+// MSC-DAG: @"\01??$ExportedVarTmpl at UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE          = global i32 0, align 4
+template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported variable template.
+// MSC-DAG: @"\01??$VarTmpl at UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE           = weak_odr dllexport global i32 1, align 4
+extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+       template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported variable template.
+// MSC-DAG: @"\01??$VarTmpl at UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE           = weak_odr dllexport global i32 1, align 4
+template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported variable template.
+// MSC-DAG: @"\01??$VarTmpl at UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE           = dllexport global i32 0, align 4
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
+
+// MSC-DAG: @"\01??$VarTmpl at UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE           = dllexport global i32 1, align 4
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// Export function definition.
+// MSC-DAG: define dllexport void @"\01?def@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z3defv()
+__declspec(dllexport) void def() {}
+
+// extern "C"
+// MSC-DAG: define dllexport void @externC()
+// GNU-DAG: define dllexport void @externC()
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+// MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv()
+__declspec(dllexport) inline void inlineFunc() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv()
+__declspec(dllexport) inline void inlineDecl();
+                             void inlineDecl() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv()
+__declspec(dllexport) void inlineDef();
+               inline void inlineDef() {}
+
+// Redeclarations
+// MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7redecl1v()
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+// MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7redecl2v()
+__declspec(dllexport) void redecl2();
+                      void redecl2() {}
+
+// Friend functions
+// MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7friend1v()
+// MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7friend2v()
+struct FuncFriend {
+  friend __declspec(dllexport) void friend1();
+  friend __declspec(dllexport) void friend2();
+};
+__declspec(dllexport) void friend1() {}
+                      void friend2() {}
+
+// Implicit declarations can be redeclared with dllexport.
+// MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
+// GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}(
+void* alloc(__SIZE_TYPE__ n);
+__declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); }
+
+// MSC-DAG: define dllexport void @"\01?externalFunc at ns@@YAXXZ"()
+// GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv()
+namespace ns { __declspec(dllexport) void externalFunc() {} }
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template definition.
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+INST(funcTmplDef<ExplicitInst_Exported>)
+
+// Export inline function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
+INST(inlineFuncTmpl1<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv()
+template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
+INST(inlineFuncTmpl2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
+template<typename T>                              void inlineFuncTmplDecl() {}
+INST(inlineFuncTmplDecl<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
+template<typename T>                inline void inlineFuncTmplDef() {}
+INST(inlineFuncTmplDef<ExplicitInst_Exported>)
+
+
+// Redeclarations
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+INST(funcTmplRedecl1<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2() {}
+INST(funcTmplRedecl2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl3();
+template<typename T>                       void funcTmplRedecl3() {}
+INST(funcTmplRedecl3<ExplicitInst_Exported>)
+
+
+// Function template friends
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv()
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2 at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv()
+struct FuncTmplFriend {
+  template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
+  template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
 };
+template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
+template<typename T>                       void funcTmplFriend2() {}
+INST(funcTmplFriend1<ExplicitInst_Exported>)
+INST(funcTmplFriend2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl at UExplicitInst_Exported@@@ns@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv()
+namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} }
+INST(ns::externalFuncTmpl<ExplicitInst_Exported>)
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl at UImplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv()
+USE(exportedFuncTmpl<ImplicitInst_Exported>)
+
+// Export explicit instantiation declaration of an exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl at UExplicitDecl_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv()
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+       template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv()
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+// MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl at UExplicitSpec_Def_Exported@@@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv()
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl at UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv()
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+// MSC-DAG: define void @"\01??$exportedFuncTmpl at UExplicitSpec_NotExported@@@@YAXXZ"()
+// GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv()
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl at UExplicitDecl_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv()
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl at UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv()
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+// MSC-DAG: define dllexport void @"\01??$funcTmpl at UExplicitSpec_Def_Exported@@@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv()
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl at UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv()
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over the dllimport if both are specified.
+// MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4
+// MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal1A            = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal1B            = dllexport global i32 0, align 4
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // dllimport ignored
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored
+
+// MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4
+// MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal2A            = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal2B            = dllexport global i32 0, align 4
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // dllimport ignored
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored
+
+// MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalRedecl1            = dllexport global i32 0, align 4
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1 = 0;
+
+// MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalRedecl2            = dllexport global i32 0, align 4
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+// MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalMixed1            = dllexport global i32 0, align 4
+__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
+__declspec(dllimport)             int PrecedenceGlobalMixed1 = 0;
+
+// MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalMixed2            = dllexport global i32 0, align 4
+__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
+__declspec(dllexport)             int PrecedenceGlobalMixed2;
+
+// MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ"
+// MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z12precedence1Av()
+// GNU-DAG: define dllexport void @_Z12precedence1Bv()
+void __attribute__((dllimport, dllexport))       precedence1A() {}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {}
+
+// MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ"
+// MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z12precedence2Av()
+// GNU-DAG: define dllexport void @_Z12precedence2Bv()
+void __attribute__((dllexport, dllimport))       precedence2A() {}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {}
 
+// MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z17precedenceRedecl1v()
+void __declspec(dllimport) precedenceRedecl1();
+void __declspec(dllexport) precedenceRedecl1() {}
 
-void user() {
-  a();
-}
+// MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z17precedenceRedecl2v()
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {}

Added: cfe/trunk/test/CodeGenCXX/dllimport-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport-members.cpp?rev=209596&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport-members.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/dllimport-members.cpp Sun May 25 05:34:16 2014
@@ -0,0 +1,886 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USE(func) void UNIQ(use)() { func(); }
+#define USEMV(cls, var) int UNIQ(use)() { return ref(cls::var); }
+#define USEMF(cls, fun) template<> void useMemFun<__LINE__, cls>() { cls().fun(); }
+#define USESPECIALS(cls) void UNIQ(use)() { useSpecials<cls>(); }
+
+template<typename T>
+T ref(T const& v) { return v; }
+
+template<int Line, typename T>
+void useMemFun();
+
+template<typename T>
+void useSpecials() {
+  T v; // Default constructor
+
+  T c1(static_cast<const T&>(v)); // Copy constructor
+  T c2 = static_cast<const T&>(v); // Copy constructor
+  T c3;
+  c3 = static_cast<const T&>(v); // Copy assignment
+
+  T m1(static_cast<T&&>(v)); // Move constructor
+  T m2 = static_cast<T&&>(v); // Move constructor
+  T m3;
+  m3 = static_cast<T&&>(v); // Move assignment
+}
+
+// Used to force non-trivial special members.
+struct ForceNonTrivial {
+  ForceNonTrivial();
+  ~ForceNonTrivial();
+  ForceNonTrivial(const ForceNonTrivial&);
+  ForceNonTrivial& operator=(const ForceNonTrivial&);
+  ForceNonTrivial(ForceNonTrivial&&);
+  ForceNonTrivial& operator=(ForceNonTrivial&&);
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class.
+struct ImportMembers {
+  struct Nested;
+
+  // M32-DAG: define            x86_thiscallcc void @"\01?normalDef at ImportMembers@@QAEXXZ"(%struct.ImportMembers* %this)
+  // M64-DAG: define                           void @"\01?normalDef at ImportMembers@@QEAAXXZ"(%struct.ImportMembers* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl at ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalDecl at ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass at ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalInclass at ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDef at ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDef at ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDecl at ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDecl at ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInclass at ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDef at ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDecl at ImportMembers@@QAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(
+  __declspec(dllimport)                void normalDef(); // dllimport ignored
+  __declspec(dllimport)                void normalDecl();
+  __declspec(dllimport)                void normalInclass() {}
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+
+  // M32-DAG: define            x86_thiscallcc void @"\01?virtualDef at ImportMembers@@UAEXXZ"(%struct.ImportMembers* %this)
+  // M64-DAG: define                           void @"\01?virtualDef at ImportMembers@@UEAAXXZ"(%struct.ImportMembers* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl at ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualDecl at ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass at ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInclass at ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDef at ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDef at ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDecl at ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDecl at ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInclass at ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDef at ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDecl at ImportMembers@@UAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(
+  __declspec(dllimport) virtual        void virtualDef(); // dllimport ignored
+  __declspec(dllimport) virtual        void virtualDecl();
+  __declspec(dllimport) virtual        void virtualInclass() {}
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define                           void @"\01?staticDef at ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticDecl at ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInclass at ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDef at ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDecl at ImportMembers@@SAXXZ"()
+  // GNU-DAG: define                           void @_ZN13ImportMembers9staticDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers10staticDeclEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers13staticInclassEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers15staticInlineDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers16staticInlineDeclEv()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInclass at ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDef at ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDecl at ImportMembers@@SAXXZ"()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers13staticInclassEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers15staticInlineDefEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers16staticInlineDeclEv()
+  __declspec(dllimport) static         void staticDef(); // dllimport ignored
+  __declspec(dllimport) static         void staticDecl();
+  __declspec(dllimport) static         void staticInclass() {}
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?protectedNormalDecl at ImportMembers@@IAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?protectedNormalDecl at ImportMembers@@IEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*)
+  // MSC-DAG: declare dllimport                void @"\01?protectedStaticDecl at ImportMembers@@KAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers19protectedStaticDeclEv()
+protected:
+  __declspec(dllimport)                void protectedNormalDecl();
+  __declspec(dllimport) static         void protectedStaticDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?privateNormalDecl at ImportMembers@@AAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?privateNormalDecl at ImportMembers@@AEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*)
+  // MSC-DAG: declare dllimport                void @"\01?privateStaticDecl at ImportMembers@@CAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers17privateStaticDeclEv()
+private:
+  __declspec(dllimport)                void privateNormalDecl();
+  __declspec(dllimport) static         void privateStaticDecl();
+
+  // M32-DAG: declare           x86_thiscallcc void @"\01?ignored at ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare                          void @"\01?ignored at ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: declare           x86_thiscallcc void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*)
+  // G64-DAG: declare                          void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField at ImportMembers@@2HA"               = external dllimport global i32
+  // MSC-DAG: @"\01?StaticConstField at ImportMembers@@2HB"          = external dllimport constant i32
+  // MSC-DAG-FIXME: @"\01?StaticConstFieldEqualInit at ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG-FIXME: @"\01?StaticConstFieldBraceInit at ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG-FIXME: @"\01?ConstexprField at ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ImportMembers11StaticFieldE                   = external dllimport global i32
+  // GNU-DAG: @_ZN13ImportMembers16StaticConstFieldE              = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldEqualInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldBraceInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers14ConstexprFieldE                = external dllimport constant i32
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static  const  int  StaticConstField;
+  #ifndef MSABI // FIXME
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+  #endif
+
+  template<int Line, typename T> friend void useMemFun();
+};
+
+       void ImportMembers::normalDef() {} // dllimport ignored
+inline void ImportMembers::normalInlineDef() {}
+       void ImportMembers::normalInlineDecl() {}
+       void ImportMembers::virtualDef() {} // dllimport ignored
+inline void ImportMembers::virtualInlineDef() {}
+       void ImportMembers::virtualInlineDecl() {}
+       void ImportMembers::staticDef() {} // dllimport ignored
+inline void ImportMembers::staticInlineDef() {}
+       void ImportMembers::staticInlineDecl() {}
+
+USEMF(ImportMembers, normalDef)
+USEMF(ImportMembers, normalDecl)
+USEMF(ImportMembers, normalInclass)
+USEMF(ImportMembers, normalInlineDef)
+USEMF(ImportMembers, normalInlineDecl)
+USEMF(ImportMembers, virtualDef)
+USEMF(ImportMembers, virtualDecl)
+USEMF(ImportMembers, virtualInclass)
+USEMF(ImportMembers, virtualInlineDef)
+USEMF(ImportMembers, virtualInlineDecl)
+USEMF(ImportMembers, staticDef)
+USEMF(ImportMembers, staticDecl)
+USEMF(ImportMembers, staticInclass)
+USEMF(ImportMembers, staticInlineDef)
+USEMF(ImportMembers, staticInlineDecl)
+USEMF(ImportMembers, protectedNormalDecl)
+USEMF(ImportMembers, protectedStaticDecl)
+USEMF(ImportMembers, privateNormalDecl)
+USEMF(ImportMembers, privateStaticDecl)
+USEMF(ImportMembers, ignored)
+
+USEMV(ImportMembers, StaticField)
+USEMV(ImportMembers, StaticConstField)
+#ifndef MSABI // FIXME
+USEMV(ImportMembers, StaticConstFieldEqualInit)
+USEMV(ImportMembers, StaticConstFieldBraceInit)
+USEMV(ImportMembers, ConstexprField)
+#endif
+
+
+// Import individual members of a nested class.
+struct ImportMembers::Nested {
+  // M32-DAG: define            x86_thiscallcc void @"\01?normalDef at Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M64-DAG: define                           void @"\01?normalDef at Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl at Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalDecl at Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass at Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalInclass at Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDef at Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDef at Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDecl at Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDecl at Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInclass at Nested@ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDef at Nested@ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDecl at Nested@ImportMembers@@QAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(
+  __declspec(dllimport)                void normalDef(); // dllimport ignored
+  __declspec(dllimport)                void normalDecl();
+  __declspec(dllimport)                void normalInclass() {}
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+
+  // M32-DAG: define            x86_thiscallcc void @"\01?virtualDef at Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M64-DAG: define                           void @"\01?virtualDef at Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl at Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualDecl at Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass at Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInclass at Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDef at Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDef at Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDecl at Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDecl at Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"*)
+
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInclass at Nested@ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDef at Nested@ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDecl at Nested@ImportMembers@@UAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(
+  __declspec(dllimport) virtual        void virtualDef(); // dllimport ignored
+  __declspec(dllimport) virtual        void virtualDecl();
+  __declspec(dllimport) virtual        void virtualInclass() {}
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define                           void @"\01?staticDef at Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticDecl at Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInclass at Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDef at Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDecl at Nested@ImportMembers@@SAXXZ"()
+  // GNU-DAG: define                           void @_ZN13ImportMembers6Nested9staticDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested10staticDeclEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested13staticInclassEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested15staticInlineDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested16staticInlineDeclEv()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInclass at Nested@ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDef at Nested@ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDecl at Nested@ImportMembers@@SAXXZ"()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested13staticInclassEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested15staticInlineDefEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested16staticInlineDeclEv()
+  __declspec(dllimport) static         void staticDef(); // dllimport ignored
+  __declspec(dllimport) static         void staticDecl();
+  __declspec(dllimport) static         void staticInclass() {}
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?protectedNormalDecl at Nested@ImportMembers@@IAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?protectedNormalDecl at Nested@ImportMembers@@IEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // MSC-DAG: declare dllimport                void @"\01?protectedStaticDecl at Nested@ImportMembers@@KAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested19protectedStaticDeclEv()
+protected:
+  __declspec(dllimport)                void protectedNormalDecl();
+  __declspec(dllimport) static         void protectedStaticDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?privateNormalDecl at Nested@ImportMembers@@AAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?privateNormalDecl at Nested@ImportMembers@@AEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // MSC-DAG: declare dllimport                void @"\01?privateStaticDecl at Nested@ImportMembers@@CAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested17privateStaticDeclEv()
+private:
+  __declspec(dllimport)                void privateNormalDecl();
+  __declspec(dllimport) static         void privateStaticDecl();
+
+  // M32-DAG: declare           x86_thiscallcc void @"\01?ignored at Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare                          void @"\01?ignored at Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare           x86_thiscallcc void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare                          void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField at Nested@ImportMembers@@2HA"               = external dllimport global i32
+  // MSC-DAG: @"\01?StaticConstField at Nested@ImportMembers@@2HB"          = external dllimport constant i32
+  // MSC-DAG-FIXME: @"\01?StaticConstFieldEqualInit at Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG-FIXME: @"\01?StaticConstFieldBraceInit at Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG-FIXME: @"\01?ConstexprField at Nested@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ImportMembers6Nested11StaticFieldE                   = external dllimport global i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested16StaticConstFieldE              = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldEqualInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldBraceInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested14ConstexprFieldE                = external dllimport constant i32
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static  const  int  StaticConstField;
+  #ifndef MSABI // FIXME
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+  #endif
+
+  template<int Line, typename T> friend void useMemFun();
+};
+
+       void ImportMembers::Nested::normalDef() {} // dllimport ignored
+inline void ImportMembers::Nested::normalInlineDef() {}
+       void ImportMembers::Nested::normalInlineDecl() {}
+       void ImportMembers::Nested::virtualDef() {} // dllimport ignored
+inline void ImportMembers::Nested::virtualInlineDef() {}
+       void ImportMembers::Nested::virtualInlineDecl() {}
+       void ImportMembers::Nested::staticDef() {} // dllimport ignored
+inline void ImportMembers::Nested::staticInlineDef() {}
+       void ImportMembers::Nested::staticInlineDecl() {}
+
+USEMF(ImportMembers::Nested, normalDef)
+USEMF(ImportMembers::Nested, normalDecl)
+USEMF(ImportMembers::Nested, normalInclass)
+USEMF(ImportMembers::Nested, normalInlineDef)
+USEMF(ImportMembers::Nested, normalInlineDecl)
+USEMF(ImportMembers::Nested, virtualDef)
+USEMF(ImportMembers::Nested, virtualDecl)
+USEMF(ImportMembers::Nested, virtualInclass)
+USEMF(ImportMembers::Nested, virtualInlineDef)
+USEMF(ImportMembers::Nested, virtualInlineDecl)
+USEMF(ImportMembers::Nested, staticDef)
+USEMF(ImportMembers::Nested, staticDecl)
+USEMF(ImportMembers::Nested, staticInclass)
+USEMF(ImportMembers::Nested, staticInlineDef)
+USEMF(ImportMembers::Nested, staticInlineDecl)
+USEMF(ImportMembers::Nested, protectedNormalDecl)
+USEMF(ImportMembers::Nested, protectedStaticDecl)
+USEMF(ImportMembers::Nested, privateNormalDecl)
+USEMF(ImportMembers::Nested, privateStaticDecl)
+USEMF(ImportMembers::Nested, ignored)
+
+USEMV(ImportMembers::Nested, StaticField)
+USEMV(ImportMembers::Nested, StaticConstField)
+#ifndef MSABI // FIXME
+USEMV(ImportMembers::Nested, StaticConstFieldEqualInit)
+USEMV(ImportMembers::Nested, StaticConstFieldBraceInit)
+USEMV(ImportMembers::Nested, ConstexprField)
+#endif
+
+
+// Import special member functions.
+struct ImportSpecials {
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE at XZ"(%struct.ImportSpecials* returned)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA at XZ"(%struct.ImportSpecials* returned)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
+  __declspec(dllimport) ImportSpecials();
+
+  // FIXME: MSVC emits ??1ImportSpecials@@{{QAE|QEAA}}@XZ here.
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportSpecials@@QAE at XZ"(%struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                void @"\01??_DImportSpecials@@QEAA at XZ"(%struct.ImportSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
+  __declspec(dllimport) ~ImportSpecials() {}
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE at ABU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA at AEBU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  __declspec(dllimport) ImportSpecials(const ImportSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0 at ABU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0 at AEBU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@$$QAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  __declspec(dllimport) ImportSpecials(ImportSpecials&&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials*)
+  __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
+};
+USESPECIALS(ImportSpecials)
+
+
+// Export inline special member functions.
+struct ImportInlineSpecials {
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE at XZ"(%struct.ImportInlineSpecials* returned)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA at XZ"(%struct.ImportInlineSpecials* returned)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE at XZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(
+  __declspec(dllimport) ImportInlineSpecials() {}
+
+  // FIXME: MSVC emits ??1ImportInlineSpecials@@{{QAE|QEAA}}@XZ here.
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE at XZ"(%struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                void @"\01??_DImportInlineSpecials@@QEAA at XZ"(%struct.ImportInlineSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE at XZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(
+  __declspec(dllimport) ~ImportInlineSpecials() {}
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE at ABU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA at AEBU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE at ABU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(
+  __declspec(dllimport) inline ImportInlineSpecials(const ImportInlineSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0 at ABU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0 at AEBU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0 at ABU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(
+  __declspec(dllimport) ImportInlineSpecials& operator=(const ImportInlineSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void  @_ZN20ImportInlineSpecialsC1EOS_(
+  __declspec(dllimport) ImportInlineSpecials(ImportInlineSpecials&&) {}
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(
+  __declspec(dllimport) ImportInlineSpecials& operator=(ImportInlineSpecials&&) { return *this; }
+};
+ImportInlineSpecials::ImportInlineSpecials(const ImportInlineSpecials&) {}
+inline ImportInlineSpecials& ImportInlineSpecials::operator=(const ImportInlineSpecials&) { return *this; }
+USESPECIALS(ImportInlineSpecials)
+
+
+// Import defaulted member functions.
+struct ImportDefaulted {
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE at XZ"(%struct.ImportDefaulted* returned)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA at XZ"(%struct.ImportDefaulted* returned)
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE at XZ"(%struct.ImportDefaulted* returned %this)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this)
+  __declspec(dllimport) ImportDefaulted() = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE at XZ"(%struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                void @"\01??_DImportDefaulted@@QEAA at XZ"(%struct.ImportDefaulted*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE at XZ"(%struct.ImportDefaulted* %this)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
+  __declspec(dllimport) ~ImportDefaulted() = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE at ABU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA at AEBU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE at ABU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted*)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0 at ABU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0 at AEBU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0 at ABU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*)
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted*)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*)
+  __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
+
+  ForceNonTrivial v; // ensure special members are non-trivial
+};
+USESPECIALS(ImportDefaulted)
+
+
+// Import defaulted member function definitions.
+struct ImportDefaultedDefs {
+  __declspec(dllimport) inline ImportDefaultedDefs();
+  __declspec(dllimport) inline ~ImportDefaultedDefs();
+
+  __declspec(dllimport) ImportDefaultedDefs(const ImportDefaultedDefs&);
+  __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
+
+  __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
+  __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&);
+};
+
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE at XZ"(%struct.ImportDefaultedDefs* returned)
+// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA at XZ"(%struct.ImportDefaultedDefs* returned)
+// G32-DAG: declare dllimport x86_thiscallcc void                         @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*)
+// G64-DAG: declare dllimport                void                         @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*)
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default;
+
+// FIXME: MSVC emits ??1ImportDefaultedDefs@@{{QAE|QEAA}}@XZ here.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaultedDefs@@QAE at XZ"(%struct.ImportDefaultedDefs*)
+// M64-DAG: declare dllimport                void @"\01??_DImportDefaultedDefs@@QEAA at XZ"(%struct.ImportDefaultedDefs*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
+// G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
+__declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default;
+
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE at ABU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs*)
+// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA at AEBU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+// G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+inline ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
+
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0 at ABU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0 at AEBU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+// G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+// G64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*)
+inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
+
+// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs*)
+// M64-DAG: define                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs*)
+// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// G64-DAG: define                void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// G64-DAG: define                void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // dllimport ignored
+
+// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// M64-DAG: define                %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// G32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+// G64-DAG: define                %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*)
+ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // dllimport ignored
+
+USESPECIALS(ImportDefaultedDefs)
+
+
+// Import allocation functions.
+struct ImportAlloc {
+  __declspec(dllimport) void* operator new(__SIZE_TYPE__);
+  __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
+  __declspec(dllimport) void operator delete(void*);
+  __declspec(dllimport) void operator delete[](void*);
+};
+
+// M32-DAG: declare dllimport i8* @"\01??2ImportAlloc@@SAPAXI at Z"(i32)
+// M64-DAG: declare dllimport i8* @"\01??2ImportAlloc@@SAPEAX_K at Z"(i64)
+// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnwEj(i32)
+// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnwEy(i64)
+void UNIQ(use)() { new ImportAlloc(); }
+
+// M32-DAG: declare dllimport i8* @"\01??_UImportAlloc@@SAPAXI at Z"(i32)
+// M64-DAG: declare dllimport i8* @"\01??_UImportAlloc@@SAPEAX_K at Z"(i64)
+// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnaEj(i32)
+// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnaEy(i64)
+void UNIQ(use)() { new ImportAlloc[1]; }
+
+// M32-DAG: declare dllimport void @"\01??3ImportAlloc@@SAXPAX at Z"(i8*)
+// M64-DAG: declare dllimport void @"\01??3ImportAlloc@@SAXPEAX at Z"(i8*)
+// G32-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*)
+// G64-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*)
+void UNIQ(use)(ImportAlloc* ptr) { delete ptr; }
+
+// M32-DAG: declare dllimport void @"\01??_VImportAlloc@@SAXPAX at Z"(i8*)
+// M64-DAG: declare dllimport void @"\01??_VImportAlloc@@SAXPEAX at Z"(i8*)
+// G32-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*)
+// G64-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*)
+void UNIQ(use)(ImportAlloc* ptr) { delete[] ptr; }
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct MemFunTmpl {
+  template<typename T>                              void normalDef() {}
+  template<typename T> __declspec(dllimport)        void importedNormal() {}
+  template<typename T>                       static void staticDef() {}
+  template<typename T> __declspec(dllimport) static void importedStatic() {}
+};
+
+// Import implicit instantiation of an imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal at UImplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal at UImplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+USEMF(MemFunTmpl, importedNormal<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic at UImplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ImplicitInst_ImportedEEvv()
+USE(MemFunTmpl::importedStatic<ImplicitInst_Imported>)
+
+
+// Import explicit instantiation declaration of an imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal at UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal at UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitDecl_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic at UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ExplicitDecl_ImportedEEvv()
+extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of an imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal at UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal at UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic at UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ExplicitInst_ImportedEEvv()
+template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitInst_Imported>)
+
+
+// Import specialization of an imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal at UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal at UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Imported>)
+
+// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$importedNormal at UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG-FIXME: declare dllimport                void @"\01??$importedNormal at UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {}
+//USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Def_Imported>)
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal at UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal at UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic at UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ExplicitSpec_ImportedEEvv()
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport                void @"\01??$importedStatic at UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {}
+//USE(MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic at UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI31ExplicitSpec_InlineDef_ImportedEEvv()
+template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>)
+
+
+// Not importing specialization of an imported member function template without
+// explicit dllimport.
+// M32-DAG: define x86_thiscallcc void @"\01??$importedNormal at UExplicitSpec_NotImported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define                void @"\01??$importedNormal at UExplicitSpec_NotImported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define                void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this)
+template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_NotImported>)
+
+// MSC-DAG: define                void @"\01??$importedStatic at UExplicitSpec_NotImported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define                void @_ZN10MemFunTmpl14importedStaticI24ExplicitSpec_NotImportedEEvv()
+template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef at UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef at UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitDecl_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$staticDef at UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ImportedEEvv()
+extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of a non-imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef at UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef at UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$staticDef at UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ImportedEEvv()
+template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitInst_Imported>)
+
+
+// Import specialization of a non-imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef at UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef at UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_Imported>)
+
+// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$normalDef at UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG-FIXME: declare dllimport                void @"\01??$normalDef at UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {}
+//USEMF(MemFunTmpl, normalDef<ExplicitSpec_Def_Imported>)
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef at UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef at UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"\01??$staticDef at UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI21ExplicitSpec_ImportedEEvv()
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$staticDef at UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {}
+//USE(MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$staticDef at UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ImportedEEvv()
+template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
+USE(MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>)
+
+
+
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
+};
+
+// Import implicit instantiation of an imported member variable template.
+// MSC-DAG: @"\01??$ImportedStaticVar at UImplicitInst_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ImplicitInst_ImportedEE       = external dllimport constant i32
+USEMV(MemVarTmpl, ImportedStaticVar<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported member variable
+// template.
+// MSC-DAG: @"\01??$ImportedStaticVar at UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitDecl_ImportedEE       = external dllimport constant i32
+extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of an imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of an imported member variable template.
+// MSC-DAG: @"\01??$ImportedStaticVar at UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitSpec_ImportedEE       = external dllimport constant i32
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_Imported>)
+
+// Not importing specialization of a member variable template without explicit
+// dllimport.
+// MSC-DAG: @"\01??$ImportedStaticVar at UExplicitSpec_NotImported@@@MemVarTmpl@@2HB" = external constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE       = external constant i32
+template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported member variable
+// template.
+// MSC-DAG: @"\01??$StaticVar at UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ImportedEE        = external dllimport constant i32
+extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
+USEMV(MemVarTmpl, StaticVar<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of a non-imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of a non-imported member variable template.
+// MSC-DAG: @"\01??$StaticVar at UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitSpec_ImportedEE        = external dllimport constant i32
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
+USEMV(MemVarTmpl, StaticVar<ExplicitSpec_Imported>)

Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=209596&r1=209595&r2=209596&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Sun May 25 05:34:16 2014
@@ -1,25 +1,503 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -x c++ -O2 -disable-llvm-optzns -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
 
-#define DLLIMPORT __declspec(dllimport)
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ImplicitInst_NotImported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
 
-void DLLIMPORT a();
-// CHECK-DAG: declare dllimport void @"\01?a@@YAXXZ"()
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
+#define USEVAR(var) USEVARTYPE(int, var)
+#define USE(func) void UNIQ(use)() { func(); }
 
-inline void DLLIMPORT b() {}
-// CHECK-DAG: define available_externally dllimport void @"\01?b@@YAXXZ"()
 
-template <typename T> void c() {}
-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"
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32
+// GNU-DAG: @ExternGlobalDecl            = external dllimport global i32
+__declspec(dllimport) extern int ExternGlobalDecl;
+USEVAR(ExternGlobalDecl)
+
+// dllimport implies a declaration.
+// MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalDecl            = external dllimport global i32
+__declspec(dllimport) int GlobalDecl;
+USEVAR(GlobalDecl)
+
+// Redeclarations
+// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl1            = external dllimport global i32
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+USEVAR(GlobalRedecl1)
+
+// MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl2a            = external dllimport global i32
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+USEVAR(GlobalRedecl2a)
+
+// M32-DAG: @"\01?GlobalRedecl2b@@3PAHA"   = external dllimport global i32*
+// M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
+// GNU-DAG: @GlobalRedecl2b                = external dllimport global i32*
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+USEVARTYPE(int*, GlobalRedecl2b)
+
+// MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl2c            = external dllimport global i32
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+USEVAR(GlobalRedecl2c)
+
+// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32
+// GNU-DAG: @GlobalRedecl3            = external global i32
+__declspec(dllimport) extern int GlobalRedecl3;
+                      extern int GlobalRedecl3; // dllimport ignored
+USEVAR(GlobalRedecl3)
+
+// MSC-DAG: @"\01?ExternalGlobal at ns@@3HA" = external dllimport global i32
+// GNU-DAG: @_ZN2ns14ExternalGlobalE      = external dllimport global i32
+namespace ns { __declspec(dllimport) int ExternalGlobal; }
+USEVAR(ns::ExternalGlobal)
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// MSC-DAG: @"\01??$ExternVarTmplDecl at UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
+USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
+
+// dllimport implies a declaration.
+// MSC-DAG: @"\01??$VarTmplDecl at UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) int VarTmplDecl;
+USEVAR(VarTmplDecl<ImplicitInst_Imported>)
+
+// Redeclarations
+// MSC-DAG: @"\01??$VarTmplRedecl1 at UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
+
+// MSC-DAG: @"\01??$VarTmplRedecl2 at UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
+
+// MSC-DAG: @"\01??$VarTmplRedecl3 at UImplicitInst_Imported@@@@3HA" = external global i32
+// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE          = external global i32
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
+template<typename T>                       extern int VarTmplRedecl3; // dllimport ignored
+USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
+
+
+// MSC-DAG: @"\01??$ExternalVarTmpl at UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE        = external dllimport global i32
+namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
+USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
+
+
+template<typename T> int VarTmpl;
+template<typename T> __declspec(dllimport) int ImportedVarTmpl;
+
+// Import implicit instantiation of an imported variable template.
+// MSC-DAG: @"\01??$ImportedVarTmpl at UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE          = external dllimport global i32
+USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported variable template.
+// MSC-DAG: @"\01??$ImportedVarTmpl at UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE          = external dllimport global i32
+extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
+USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of an imported variable template cannot
+// be imported because the template must be defined which is illegal.
+
+// Import specialization of an imported variable template.
+// MSC-DAG: @"\01??$ImportedVarTmpl at UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE          = external dllimport global i32
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
+USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
+
+// Not importing specialization of an imported variable template without
+// explicit dllimport.
+// MSC-DAG: @"\01??$ImportedVarTmpl at UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4
+// GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE          = global i32 0, align 4
+template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
+USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
+
+// Import explicit instantiation declaration of a non-imported variable template.
+// MSC-DAG: @"\01??$VarTmpl at UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE           = external dllimport global i32
+extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
+USEVAR(VarTmpl<ExplicitDecl_Imported>)
+
+// Import explicit instantiation definition of a non-imported variable template.
+// MSC-DAG: @"\01??$VarTmpl at UExplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE           = external dllimport global i32
+template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
+USEVAR(VarTmpl<ExplicitInst_Imported>)
+
+// Import specialization of a non-imported variable template.
+// MSC-DAG: @"\01??$VarTmpl at UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE           = external dllimport global i32
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
+USEVAR(VarTmpl<ExplicitSpec_Imported>)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration.
+// MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z4declv()
+__declspec(dllimport) void decl();
+USE(decl)
+
+// extern "C"
+// MSC-DAG: declare dllimport void @externC()
+// GNU-DAG: declare dllimport void @externC()
+extern "C" __declspec(dllimport) void externC();
+USE(externC)
+
+// Import inline function.
+// MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z10inlineFuncv()
+// MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z10inlineFuncv()
+__declspec(dllimport) inline void inlineFunc() {}
+USE(inlineFunc)
+
+// MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z10inlineDeclv()
+// MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z10inlineDeclv()
+__declspec(dllimport) inline void inlineDecl();
+                             void inlineDecl() {}
+USE(inlineDecl)
+
+// MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z9inlineDefv()
+// MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z9inlineDefv()
+__declspec(dllimport) void inlineDef();
+               inline void inlineDef() {}
+USE(inlineDef)
+
+// inline attributes
+// MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8noinlinev()
+__declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
+USE(noinline)
+
+// MSC-NOT: @"\01?alwaysInline@@YAXXZ"()
+// GNU-NOT: @_Z12alwaysInlinev()
+__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
+USE(alwaysInline)
+
+// Redeclarations
+// MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7redecl1v()
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+USE(redecl1)
+
+// NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// MSC-DAG: declare void @"\01?redecl2@@YAXXZ"()
+// GNU-DAG: declare void @_Z7redecl2v()
+__declspec(dllimport) void redecl2();
+                      void redecl2();
+USE(redecl2)
+
+// MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
+// GNU-DAG: define void @_Z7redecl3v()
+__declspec(dllimport) void redecl3();
+                      void redecl3() {} // dllimport ignored
+USE(redecl3)
+
+
+// Friend functions
+// MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7friend1v()
+// MSC-DAG: declare           void @"\01?friend2@@YAXXZ"()
+// GNU-DAG: declare           void @_Z7friend2v()
+// MSC-DAG: define            void @"\01?friend3@@YAXXZ"()
+// GNU-DAG: define            void @_Z7friend3v()
+struct FuncFriend {
+  friend __declspec(dllimport) void friend1();
+  friend __declspec(dllimport) void friend2();
+  friend __declspec(dllimport) void friend3();
 };
+__declspec(dllimport) void friend1();
+                      void friend2(); // dllimport ignored
+                      void friend3() {} // dllimport ignored
+USE(friend1)
+USE(friend2)
+USE(friend3)
+
+// Implicit declarations can be redeclared with dllimport.
+// MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
+// GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
+__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
+void UNIQ(use)() { ::operator new(42); }
+
+// MSC-DAG: declare dllimport void @"\01?externalFunc at ns@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
+namespace ns { __declspec(dllimport) void externalFunc(); }
+USE(ns::externalFunc)
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration.
+// MSC-DAG: declare dllimport void @"\01??$funcTmplDecl at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplDecl();
+USE(funcTmplDecl<ImplicitInst_Imported>)
+
+// Function template definitions cannot be imported.
+
+// Import inline function template.
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1 at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1 at UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
+USE(inlineFuncTmpl1<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2 at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2 at UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+USE(inlineFuncTmpl2<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl at UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
+template<typename T>                              void inlineFuncTmplDecl() {}
+USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef at UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
+template<typename T>                inline void inlineFuncTmplDef() {}
+USE(inlineFuncTmplDef<ImplicitInst_Imported>)
+
+
+// Redeclarations
+// MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1 at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+USE(funcTmplRedecl1<ImplicitInst_Imported>)
+
+// MSC-DAG: declare void @"\01??$funcTmplRedecl2 at UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2(); // dllimport ignored
+USE(funcTmplRedecl2<ImplicitInst_NotImported>)
+
+// MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3 at UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl3();
+template<typename T>                       void funcTmplRedecl3() {} // dllimport ignored
+USE(funcTmplRedecl3<ImplicitInst_NotImported>)
+
+
+// Function template friends
+// MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend1 at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport   void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
+// MSC-DAG: declare             void @"\01??$funcTmplFriend2 at UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: declare             void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
+// MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3 at UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
+// MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend4 at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport   void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
+struct FuncTmplFriend {
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
+  template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
+};
+template<typename T> __declspec(dllimport) void funcTmplFriend1();
+template<typename T>                       void funcTmplFriend2(); // dllimport ignored
+template<typename T>                       void funcTmplFriend3() {} // dllimport ignored
+template<typename T>                       inline void funcTmplFriend4() {}
+USE(funcTmplFriend1<ImplicitInst_Imported>)
+USE(funcTmplFriend2<ImplicitInst_NotImported>)
+USE(funcTmplFriend3<ImplicitInst_NotImported>)
+USE(funcTmplFriend4<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl at UImplicitInst_Imported@@@ns@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
+namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
+USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> inline void inlineFuncTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
+template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
+
+// Import implicit instantiation of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
+USE(importedFuncTmplDecl<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl at UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl at UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
+USE(importedFuncTmpl<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl at UExplicitDecl_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl at UExplicitDecl_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
+extern template void importedFuncTmpl<ExplicitDecl_Imported>();
+USE(importedFuncTmpl<ExplicitDecl_Imported>)
+
+// Import explicit instantiation definition of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl at UExplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl at UExplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
+template void importedFuncTmpl<ExplicitInst_Imported>();
+USE(importedFuncTmpl<ExplicitInst_Imported>)
+
+
+// Import specialization of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl at UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
+USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl at UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl at UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
+//USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl at UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl at UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
+USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl at UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+USE(importedFuncTmpl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl at UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl at UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
+//USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl at UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl at UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
+USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
+
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+// MSC-DAG: define void @"\01??$importedFuncTmpl at UExplicitSpec_NotImported@@@@YAXXZ"()
+// GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+USE(importedFuncTmpl<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl at UExplicitDecl_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl at UExplicitDecl_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
+// GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl at UExplicitDecl_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
+USE(funcTmpl<ExplicitDecl_Imported>)
+USE(inlineFuncTmpl<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of a non-imported function template.
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl at UExplicitInst_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl at UExplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
+// GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl at UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl at UExplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
+// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
+template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
+template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
+USE(funcTmpl<ExplicitInst_Imported>)
+USE(inlineFuncTmpl<ExplicitInst_Imported>)
+
+
+// Import specialization of a non-imported function template.
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl at UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+USE(funcTmpl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl at UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl at UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
+//USE(funcTmpl<ExplicitSpec_Def_Imported>)
+#endif
 
-void user(S* s) {
-  a();
-  b();
-  c<int>();
-  s->a();
-}
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl at UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl at UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
+USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)





More information about the cfe-commits mailing list