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