xref: /llvm-project/clang/test/CodeGenCXX/code-seg.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 
4*7963e8beSErich Keane // Simple case
5*7963e8beSErich Keane 
bar_one()6*7963e8beSErich Keane int __declspec(code_seg("foo_one")) bar_one() { return 1; }
7*7963e8beSErich Keane //CHECK: define {{.*}}bar_one{{.*}} section "foo_one"
8*7963e8beSErich Keane 
9*7963e8beSErich Keane // Simple case - explicit attribute used over pragma
10*7963e8beSErich Keane #pragma code_seg("foo_two")
bar2()11*7963e8beSErich Keane int __declspec(code_seg("foo_three")) bar2() { return 2; }
12*7963e8beSErich Keane //CHECK: define {{.*}}bar2{{.*}} section "foo_three"
13*7963e8beSErich Keane 
14*7963e8beSErich Keane // Check that attribute on one function doesn't affect another
another1()15*7963e8beSErich Keane int another1() { return 1001; }
16*7963e8beSErich Keane //CHECK: define {{.*}}another1{{.*}} section "foo_two"
17*7963e8beSErich Keane 
18*7963e8beSErich Keane // Member functions
19*7963e8beSErich Keane 
20*7963e8beSErich Keane struct __declspec(code_seg("foo_four")) Foo {
bar3Foo21*7963e8beSErich Keane   int bar3() {return 0;}
22*7963e8beSErich Keane   int bar4();
bar6Foo23*7963e8beSErich Keane   int __declspec(code_seg("foo_six")) bar6() { return 6; }
bar7Foo24*7963e8beSErich Keane   int bar7() { return 7; }
25*7963e8beSErich Keane   struct Inner {
bar5Foo::Inner26*7963e8beSErich Keane     int bar5() { return 5; }
27*7963e8beSErich Keane   } z;
baz1Foo28*7963e8beSErich Keane   virtual int baz1() { return 1; }
29*7963e8beSErich Keane };
30*7963e8beSErich Keane 
31*7963e8beSErich Keane struct __declspec(code_seg("foo_four")) FooTwo : Foo {
baz1FooTwo32*7963e8beSErich Keane   int baz1() { return 20; }
33*7963e8beSErich Keane };
34*7963e8beSErich Keane 
caller1()35*7963e8beSErich Keane int caller1() {
36*7963e8beSErich Keane   Foo f; return f.bar3();
37*7963e8beSErich Keane }
38*7963e8beSErich Keane 
39*7963e8beSErich Keane //CHECK: define {{.*}}bar3@Foo{{.*}} section "foo_four"
bar4()40*7963e8beSErich Keane int Foo::bar4() { return 4; }
41*7963e8beSErich Keane //CHECK: define {{.*}}bar4@Foo{{.*}} section "foo_four"
42*7963e8beSErich Keane 
43*7963e8beSErich Keane #pragma code_seg("someother")
44*7963e8beSErich Keane 
caller2()45*7963e8beSErich Keane int caller2() {
46*7963e8beSErich Keane   Foo f;
47*7963e8beSErich Keane   Foo *fp = new FooTwo;
48*7963e8beSErich Keane   return f.z.bar5() + f.bar6() + f.bar7() + fp->baz1();
49*7963e8beSErich Keane }
50*7963e8beSErich Keane // MS Compiler and Docs do not match for nested routines
51*7963e8beSErich Keane // Doc says:      define {{.*}}bar5@Inner@Foo{{.*}} section "foo_four"
52*7963e8beSErich Keane // Compiler says: define {{.*}}bar5@Inner@Foo{{.*}} section "foo_two"
53*7963e8beSErich Keane // A bug has been reported: see https://reviews.llvm.org/D22931, the
54*7963e8beSErich Keane // Microsoft feedback page is no longer available.
55*7963e8beSErich Keane //CHECK: define {{.*}}bar5@Inner@Foo{{.*}} section "foo_two"
56*7963e8beSErich Keane //CHECK: define {{.*}}bar6@Foo{{.*}} section "foo_six"
57*7963e8beSErich Keane //CHECK: define {{.*}}bar7@Foo{{.*}} section "foo_four"
58*7963e8beSErich Keane // Check that code_seg active at class declaration is not used on member
59*7963e8beSErich Keane // declared outside class when it is not active.
60*7963e8beSErich Keane 
61*7963e8beSErich Keane #pragma code_seg(push,"AnotherSeg")
62*7963e8beSErich Keane 
63*7963e8beSErich Keane struct FooThree {
64*7963e8beSErich Keane   int bar8();
bar9FooThree65*7963e8beSErich Keane   int bar9() { return 9; }
66*7963e8beSErich Keane };
67*7963e8beSErich Keane 
68*7963e8beSErich Keane #pragma code_seg(pop)
69*7963e8beSErich Keane 
70*7963e8beSErich Keane 
bar8()71*7963e8beSErich Keane int FooThree::bar8() {return 0;}
72*7963e8beSErich Keane 
caller3()73*7963e8beSErich Keane int caller3()
74*7963e8beSErich Keane {
75*7963e8beSErich Keane   FooThree f;
76*7963e8beSErich Keane   return f.bar8() + f.bar9();
77*7963e8beSErich Keane }
78*7963e8beSErich Keane 
79*7963e8beSErich Keane //CHECK: define {{.*}}bar8@FooThree{{.*}} section "someother"
80*7963e8beSErich Keane //CHECK: define {{.*}}bar9@FooThree{{.*}} section "AnotherSeg"
81*7963e8beSErich Keane 
82*7963e8beSErich Keane struct NonTrivialCopy {
83*7963e8beSErich Keane   NonTrivialCopy();
84*7963e8beSErich Keane   NonTrivialCopy(const NonTrivialCopy&);
85*7963e8beSErich Keane   ~NonTrivialCopy();
86*7963e8beSErich Keane };
87*7963e8beSErich Keane 
88*7963e8beSErich Keane // check the section for compiler-generated function with declspec.
89*7963e8beSErich Keane 
90*7963e8beSErich Keane struct __declspec(code_seg("foo_seven")) FooFour {
FooFourFooFour91*7963e8beSErich Keane   FooFour() {}
bar10FooFour92*7963e8beSErich Keane   int __declspec(code_seg("foo_eight")) bar10(int t) { return t; }
93*7963e8beSErich Keane   NonTrivialCopy f;
94*7963e8beSErich Keane };
95*7963e8beSErich Keane 
96*7963e8beSErich Keane //CHECK: define {{.*}}0FooFour@@QAE@ABU0@@Z{{.*}} section "foo_seven"
97*7963e8beSErich Keane // check the section for compiler-generated function with no declspec.
98*7963e8beSErich Keane 
99*7963e8beSErich Keane struct FooFive {
FooFiveFooFive100*7963e8beSErich Keane   FooFive() {}
bar11FooFive101*7963e8beSErich Keane   int __declspec(code_seg("foo_nine")) bar11(int t) { return t; }
102*7963e8beSErich Keane   NonTrivialCopy f;
103*7963e8beSErich Keane };
104*7963e8beSErich Keane 
105*7963e8beSErich Keane //CHECK: define {{.*}}0FooFive@@QAE@ABU0@@Z{{.*}} section "someother"
106*7963e8beSErich Keane 
107*7963e8beSErich Keane #pragma code_seg("YetAnother")
caller4()108*7963e8beSErich Keane int caller4()
109*7963e8beSErich Keane {
110*7963e8beSErich Keane   FooFour z1;
111*7963e8beSErich Keane   FooFour z2 = z1;
112*7963e8beSErich Keane   FooFive y1;
113*7963e8beSErich Keane   FooFive y2 = y1;
114*7963e8beSErich Keane  return z2.bar10(0) + y2.bar11(1);
115*7963e8beSErich Keane }
116*7963e8beSErich Keane 
117*7963e8beSErich Keane //CHECK: define {{.*}}bar10@FooFour{{.*}} section "foo_eight"
118*7963e8beSErich Keane //CHECK: define {{.*}}bar11@FooFive{{.*}} section "foo_nine"
119*7963e8beSErich Keane 
120*7963e8beSErich Keane struct FooSix {
121*7963e8beSErich Keane   #pragma code_seg("foo_ten")
bar12FooSix122*7963e8beSErich Keane   int bar12() { return 12; }
123*7963e8beSErich Keane   #pragma code_seg("foo_eleven")
bar13FooSix124*7963e8beSErich Keane   int bar13() { return 13; }
125*7963e8beSErich Keane };
126*7963e8beSErich Keane 
bar14()127*7963e8beSErich Keane int bar14() { return 14; }
128*7963e8beSErich Keane //CHECK: define {{.*}}bar14{{.*}} section "foo_eleven"
129*7963e8beSErich Keane 
caller5()130*7963e8beSErich Keane int caller5()
131*7963e8beSErich Keane {
132*7963e8beSErich Keane   FooSix fsix;
133*7963e8beSErich Keane   return fsix.bar12() + fsix.bar13();
134*7963e8beSErich Keane }
135*7963e8beSErich Keane 
136*7963e8beSErich Keane //CHECK: define {{.*}}bar12@FooSix{{.*}} section "foo_ten"
137*7963e8beSErich Keane //CHECK: define {{.*}}bar13@FooSix{{.*}} section "foo_eleven"
138*7963e8beSErich Keane //CHECK: define {{.*}}baz1@FooTwo{{.*}} section "foo_four"
139*7963e8beSErich Keane 
140