xref: /llvm-project/clang/test/CodeGenCXX/code-seg1.cpp (revision 7963e8bebb90543d997bf99ae5f8cf9be579d9ea)
1*7963e8beSErich Keane // RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -fms-extensions -verify -o - %s | FileCheck %s
2*7963e8beSErich Keane // expected-no-diagnostics
3*7963e8beSErich Keane // The Microsoft document says: "When this attribute is applied to a class,
4*7963e8beSErich Keane // all member functions of the class and nested classes - this includes
5*7963e8beSErich Keane // compiler-generated special member functions - are put in the specified segment."
6*7963e8beSErich Keane // But the MS compiler does not always follow that.  A bug has been reported:
7*7963e8beSErich Keane // see https://reviews.llvm.org/D22931, the Microsoft feedback page is no
8*7963e8beSErich Keane // longer available.
9*7963e8beSErich Keane // The MS compiler will apply a declspec from the parent class if there is no
10*7963e8beSErich Keane // #pragma code_seg active at the class definition.  If there is an active
11*7963e8beSErich Keane // code_seg that is used instead.
12*7963e8beSErich Keane 
13*7963e8beSErich Keane // No active code_seg
14*7963e8beSErich Keane 
15*7963e8beSErich Keane struct __declspec(code_seg("foo_outer")) Foo1 {
16*7963e8beSErich Keane   struct Inner {
17*7963e8beSErich Keane     void bar1();
18*7963e8beSErich Keane     static void bar2();
19*7963e8beSErich Keane   };
20*7963e8beSErich Keane };
bar1()21*7963e8beSErich Keane void Foo1::Inner::bar1() {}
bar2()22*7963e8beSErich Keane void Foo1::Inner::bar2() {}
23*7963e8beSErich Keane 
24*7963e8beSErich Keane //CHECK: define {{.*}}bar1@Inner@Foo1{{.*}} section "foo_outer"
25*7963e8beSErich Keane //CHECK: define {{.*}}bar2@Inner@Foo1{{.*}} section "foo_outer"
26*7963e8beSErich Keane 
27*7963e8beSErich Keane struct __declspec(code_seg("foo_outer")) Foo2 {
28*7963e8beSErich Keane   struct __declspec(code_seg("foo_inner")) Inner {
29*7963e8beSErich Keane     void bar1();
30*7963e8beSErich Keane     static void bar2();
31*7963e8beSErich Keane   };
32*7963e8beSErich Keane };
bar1()33*7963e8beSErich Keane void Foo2::Inner::bar1() {}
bar2()34*7963e8beSErich Keane void Foo2::Inner::bar2() {}
35*7963e8beSErich Keane 
36*7963e8beSErich Keane //CHECK: define {{.*}}bar1@Inner@Foo2{{.*}} section "foo_inner"
37*7963e8beSErich Keane //CHECK: define {{.*}}bar2@Inner@Foo2{{.*}} section "foo_inner"
38*7963e8beSErich Keane 
39*7963e8beSErich Keane #pragma code_seg(push, "otherseg")
40*7963e8beSErich Keane struct __declspec(code_seg("foo_outer")) Foo3 {
41*7963e8beSErich Keane   struct Inner {
42*7963e8beSErich Keane     void bar1();
43*7963e8beSErich Keane     static void bar2();
44*7963e8beSErich Keane   };
45*7963e8beSErich Keane };
bar1()46*7963e8beSErich Keane void Foo3::Inner::bar1() {}
bar2()47*7963e8beSErich Keane void Foo3::Inner::bar2() {}
48*7963e8beSErich Keane 
49*7963e8beSErich Keane //CHECK: define {{.*}}bar1@Inner@Foo3{{.*}} section "otherseg"
50*7963e8beSErich Keane //CHECK: define {{.*}}bar2@Inner@Foo3{{.*}} section "otherseg"
51*7963e8beSErich Keane 
52*7963e8beSErich Keane struct __declspec(code_seg("foo_outer")) Foo4 {
53*7963e8beSErich Keane   struct __declspec(code_seg("foo_inner")) Inner {
54*7963e8beSErich Keane     void bar1();
55*7963e8beSErich Keane     static void bar2();
56*7963e8beSErich Keane   };
57*7963e8beSErich Keane };
bar1()58*7963e8beSErich Keane void Foo4::Inner::bar1() {}
bar2()59*7963e8beSErich Keane void Foo4::Inner::bar2() {}
60*7963e8beSErich Keane 
61*7963e8beSErich Keane //CHECK: define {{.*}}bar1@Inner@Foo4{{.*}} section "foo_inner"
62*7963e8beSErich Keane //CHECK: define {{.*}}bar2@Inner@Foo4{{.*}} section "foo_inner"
63*7963e8beSErich Keane 
64*7963e8beSErich Keane #pragma code_seg(pop)
65*7963e8beSErich Keane // Back to no active pragma
66*7963e8beSErich Keane struct __declspec(code_seg("foo_outer")) Foo5 {
67*7963e8beSErich Keane   struct Inner {
68*7963e8beSErich Keane     void bar1();
69*7963e8beSErich Keane     static void bar2();
70*7963e8beSErich Keane     struct __declspec(code_seg("inner1_seg")) Inner1 {
71*7963e8beSErich Keane       struct Inner2 {
72*7963e8beSErich Keane         void bar1();
73*7963e8beSErich Keane         static void bar2();
74*7963e8beSErich Keane       };
75*7963e8beSErich Keane     };
76*7963e8beSErich Keane   };
77*7963e8beSErich Keane };
bar1()78*7963e8beSErich Keane void Foo5::Inner::bar1() {}
bar2()79*7963e8beSErich Keane void Foo5::Inner::bar2() {}
bar1()80*7963e8beSErich Keane void Foo5::Inner::Inner1::Inner2::bar1() {}
bar2()81*7963e8beSErich Keane void Foo5::Inner::Inner1::Inner2::bar2() {}
82*7963e8beSErich Keane 
83*7963e8beSErich Keane //CHECK: define {{.*}}bar1@Inner@Foo5{{.*}} section "foo_outer"
84*7963e8beSErich Keane //CHECK: define {{.*}}bar2@Inner@Foo5{{.*}} section "foo_outer"
85*7963e8beSErich Keane //CHECK: define {{.*}}bar1@Inner2@Inner1@Inner@Foo5{{.*}} section "inner1_seg"
86*7963e8beSErich Keane //CHECK: define {{.*}}bar2@Inner2@Inner1@Inner@Foo5{{.*}} section "inner1_seg"
87*7963e8beSErich Keane 
88