1 // RUN: clang-cc -emit-llvm -o %t %s && 2 3 #pragma weak weakvar 4 int weakvar; 5 // RUN: grep '@weakvar = weak global' %t | count 1 && 6 7 #pragma weak weakdef 8 void weakdef(void) {} 9 // RUN: grep 'define weak void @weakdef()' %t | count 1 && 10 11 #pragma weak param // expected-warning {{weak identifier 'param' never declared}} 12 #pragma weak correct_linkage 13 void f(int param) { 14 int correct_linkage; 15 } 16 int correct_linkage; 17 // RUN: grep '@correct_linkage = weak global' %t | count 1 && 18 19 #pragma weak weakvar_alias = __weakvar_alias 20 int __weakvar_alias; 21 // RUN: grep '@__weakvar_alias = common global' %t | count 1 && 22 // RUN: grep '@weakvar_alias = alias weak i32\* @__weakvar_alias' %t | count 1 && 23 //@weakvar_alias = alias weak i32* @__weakvar_alias 24 25 #pragma weak foo = __foo 26 void __foo(void) {} 27 // RUN: grep '@foo = alias weak void ()\* @__foo\>' %t | count 1 && 28 // RUN: grep 'define void @__foo()' %t | count 1 && 29 30 31 void __foo2(void) {} 32 #pragma weak foo2 = __foo2 33 // RUN: grep '@foo2 = alias weak void ()\* @__foo2\>' %t | count 1 && 34 // RUN: grep 'define void @__foo2()' %t | count 1 && 35 36 37 ///// test errors 38 39 #pragma weak unused // expected-warning {{weak identifier 'unused' never declared}} 40 #pragma weak unused_alias = __unused_alias // expected-warning {{weak identifier '__unused_alias' never declared}} 41 42 #pragma weak td // expected-warning {{weak identifier 'td' never declared}} 43 typedef int td; 44 45 #pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}} 46 typedef int __td2; 47 48 49 ///// test weird cases 50 51 // test repeats 52 53 #pragma weak stutter = __stutter 54 #pragma weak stutter = __stutter 55 void __stutter(void) {} 56 // RUN: grep '@stutter = alias weak void ()\* @__stutter\>' %t | count 1 && 57 // RUN: grep 'define void @__stutter()' %t | count 1 && 58 59 void __stutter2(void) {} 60 #pragma weak stutter2 = __stutter2 61 #pragma weak stutter2 = __stutter2 62 // RUN: grep '@stutter2 = alias weak void ()\* @__stutter2\>' %t | count 1 && 63 // RUN: grep 'define void @__stutter2()' %t | count 1 && 64 65 66 // test decl/pragma weak order 67 68 void __declfirst(void); 69 #pragma weak declfirst = __declfirst 70 void __declfirst(void) {} 71 // RUN: grep '@declfirst = alias weak void ()\* @__declfirst\>' %t | count 1 && 72 // RUN: grep 'define void @__declfirst()' %t | count 1 && 73 74 void __declfirstattr(void) __attribute((noinline)); 75 #pragma weak declfirstattr = __declfirstattr 76 void __declfirstattr(void) {} 77 // RUN: grep '@declfirstattr = alias weak void ()\* @__declfirstattr\>' %t | count 1 && 78 // RUN: grep 'define void @__declfirstattr()' %t | count 1 && 79 80 //// test that other attributes are preserved 81 82 //// ensure that pragma weak/__attribute((weak)) play nice 83 84 void mix(void); 85 #pragma weak mix 86 __attribute((weak)) void mix(void) { } 87 // RUN: grep 'define weak void @mix()' %t | count 1 && 88 89 // ensure following __attributes are preserved and that only a single 90 // alias is generated 91 #pragma weak mix2 = __mix2 92 void __mix2(void) __attribute((noinline)); 93 void __mix2(void) __attribute((noinline)); 94 void __mix2(void) {} 95 // RUN: grep '@mix2 = alias weak void ()\* @__mix2\>' %t | count 1 && 96 // RUN: grep 'define void @__mix2()' %t | count 1 && 97 98 ////////////// test #pragma weak/__attribute combinations 99 100 // if the SAME ALIAS is already declared then it overrides #pragma weak 101 // resulting in a non-weak alias in this case 102 void both(void) __attribute((alias("__both"))); 103 #pragma weak both = __both 104 void __both(void) {} 105 // RUN: grep '@both = alias void ()\* @__both\>' %t | count 1 && 106 // RUN: grep 'define void @__both()' %t | count 1 && 107 108 // if the TARGET is previously declared then whichever aliasing method 109 // comes first applies and subsequent aliases are discarded. 110 // TODO: warn about this 111 112 void __both2(void); 113 void both2(void) __attribute((alias("__both2"))); // first, wins 114 #pragma weak both2 = __both2 115 void __both2(void) {} 116 // RUN: grep '@both2 = alias void ()\* @__both2\>' %t | count 1 && 117 // RUN: grep 'define void @__both2()' %t | count 1 && 118 119 void __both3(void); 120 #pragma weak both3 = __both3 // first, wins 121 void both3(void) __attribute((alias("__both3"))); 122 void __both3(void) {} 123 // RUN: grep '@both3 = alias weak void ()\* @__both3\>' %t | count 1 && 124 // RUN: grep 'define void @__both3()' %t | count 1 && 125 126 ///////////// ensure that #pragma weak does not alter existing __attributes() 127 128 void __a1(void) __attribute((noinline)); 129 #pragma weak a1 = __a1 130 void __a1(void) {} 131 // RUN: grep '@a1 = alias weak void ()\* @__a1\>' %t | count 1 && 132 // RUN: grep 'define void @__a1()' %t | count 1 && 133 134 // attributes introduced BEFORE a combination of #pragma weak and alias() 135 // hold... 136 void __a3(void) __attribute((noinline)); 137 #pragma weak a3 = __a3 138 void a3(void) __attribute((alias("__a3"))); 139 void __a3(void) {} 140 // RUN: grep '@a3 = alias weak void ()\* @__a3\>' %t | count 1 && 141 // RUN: grep 'define void @__a3()' %t | count 1 && 142 143 #pragma weak xxx = __xxx 144 __attribute((pure,noinline,const,fastcall)) void __xxx(void) { } 145 // RUN: grep '@xxx = alias weak void ()\* @__xxx\>' %t | count 1 && 146 // RUN: grep 'define .*fastcall.* void @__xxx()' %t | count 1 && 147 148 /// TODO: stuff that still doesn't work 149 150 // due to the fact that disparate TopLevelDecls cannot affect each other 151 // (due to clang's Parser and ASTConsumer behavior, and quite reasonable) 152 // #pragma weak must appear before or within the same TopLevelDecl as it 153 // references. 154 void yyy(void){} 155 void zzz(void){} 156 #pragma weak yyy 157 // NOTE: weak doesn't apply, not before or in same TopLevelDec(!) 158 // RUN: grep 'define void @yyy()' %t | count 1 159