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