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