[PATCH] IRGen: Add more tests for dll attributes

Hans Wennborg hans at chromium.org
Fri May 23 18:25:32 PDT 2014


Whoa, that's a lot of tests :)

On Fri, May 23, 2014 at 3:01 AM, Nico Rieck <nico.rieck at gmail.com> wrote:
> These mirror the non-error tests in Sema/dll*port.c and
> SemaCXX/dll*port.cpp.

Whoa, that's a lot of tests :) LGTM, feel free to land. Just some
minor comments below:

> ---
>  lib/Sema/SemaDecl.cpp                 |   3 +-
>  test/CodeGen/dllexport.c              | 121 +++++-
>  test/CodeGen/dllimport-dllexport.c    |  22 --
>  test/CodeGen/dllimport.c              |  90 +++++
>  test/CodeGenCXX/dllexport-members.cpp | 435 +++++++++++++++++++++
>  test/CodeGenCXX/dllexport.cpp         | 343 ++++++++++++++++-

I got a merge conflict on dllexport.cpp, but I think you can just drop
my changes :)

[..]

> --- a/test/CodeGen/dllexport.c
> +++ b/test/CodeGen/dllexport.c
> @@ -1,8 +1,119 @@
> -// RUN: %clang_cc1 -triple i686-pc-win32 -std=c99 -O2 -disable-llvm-optzns -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
> +// RUN: %clang_cc1 -triple i686-pc-win32 -std=c99 -O2 -disable-llvm-optzns -emit-llvm < %s | FileCheck %s --check-prefix=MO2

The last run line is my fault. I was copy-pasting from the dllimport
tests; the -O2 -disable-llvm-optzns flags are not needed, and I've
removed them in r209559.

> -#define DLLEXPORT __declspec(dllexport)
>
> -inline void DLLEXPORT f() {}
> -extern void DLLEXPORT f();
>
> -// CHECK: define weak_odr dllexport void @f()
> +//===----------------------------------------------------------------------===//
> +// Globals
> +//===----------------------------------------------------------------------===//
> +
> +// Declarations are not exported.
> +__declspec(dllexport) extern int ExternGlobalDecl;

Should this have a check line of some sort?

> +// 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;
> +
> +// MO2-DAG: define weak_odr dllexport void @f()

This should just be CHECK-DAG, and I suppose we should move it down to
the "Functions" section.. in fact, it's probably already covered in
there :)

[...]

> +++ b/test/CodeGenCXX/dllexport-members.cpp
> @@ -0,0 +1,435 @@
> +// 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 Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
> +    // M64-DAG: define dllexport                void @"\01?normalDef 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)
> +    __declspec(dllexport) void normalDef();
> +  };
> +
> +  // 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-FIXME: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass at ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
> +  // M64-DAG-FIXME: define weak_odr dllexport                void @"\01?normalInclass at ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)

All the FIXMEs in this file seem to pass now, presumably because of r208925.

[...]

> +++ b/test/CodeGenCXX/dllexport.cpp

[...]

> +//===----------------------------------------------------------------------===//
> +// Functions
> +//===----------------------------------------------------------------------===//
> +
> +// Declarations are not exported.

Should there be tests here, or is the comment superfluous?

[...]

> +++ b/test/CodeGenCXX/dllimport-members.cpp

[...]

> +//===----------------------------------------------------------------------===//
> +// Class members
> +//===----------------------------------------------------------------------===//
> +
> +// Import individual members of a class.
> +struct ImportMembers {
> +  struct Nested {
> +    // 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"*)
> +    // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
> +    // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
> +    __declspec(dllimport) void normalDecl();
> +  };
> +
> +  // 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*)
> +  __declspec(dllimport)                void normalDef(); // dllimport ignored
> +  __declspec(dllimport)                void normalDecl();
> +  __declspec(dllimport)                void normalInclass() {}
> +  __declspec(dllimport)                void normalInlineDef();
> +  __declspec(dllimport)         inline void normalInlineDecl();

Should the inline members have tests that check they get
availablexternally definitions at O1?

[...]

> +  // 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

Are the FIXMEs here just because we always inline the value of the
static member?

[...]

> +// 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.

Hmm, this worries me a bit :-/



More information about the cfe-commits mailing list