diff options
author | Erich Keane <erich.keane@intel.com> | 2018-07-18 20:04:48 +0000 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2018-07-18 20:04:48 +0000 |
commit | 1a78aeb17c78bc38c5cc7580dccc49136079ac07 (patch) | |
tree | 01b9b8251f3e9fb7601ac2f4c45c606ee3fadb65 /test/CodeGenCXX/code-seg.cpp | |
parent | 0e4f59d7b40a4e5cb0189e4c69fce75279031a10 (diff) |
Add support for __declspec(code_seg("segname"))
This patch uses CodeSegAttr to represent __declspec(code_seg) rather than
building on the existing support for #pragma code_seg.
The code_seg declspec is applied on functions and classes. This attribute
enables the placement of code into separate named segments, including compiler-
generated codes and template instantiations.
For more information, please see the following:
https://msdn.microsoft.com/en-us/library/dn636922.aspx
This patch fixes the regression for the support for attribute ((section).
https://github.com/llvm-mirror/clang/commit/746b78de7812bc785fbb5207b788348040b23fa7
Patch by Soumi Manna (Manna)
Differential Revision: https://reviews.llvm.org/D48841
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337420 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/code-seg.cpp')
-rw-r--r-- | test/CodeGenCXX/code-seg.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/test/CodeGenCXX/code-seg.cpp b/test/CodeGenCXX/code-seg.cpp new file mode 100644 index 0000000000..7dad927420 --- /dev/null +++ b/test/CodeGenCXX/code-seg.cpp @@ -0,0 +1,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" + |