forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			140 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
| // 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"
 | |
| 
 |