[cfe-commits] [patch] Add support for weakref
Rafael Espindola
espindola at google.com
Mon Feb 22 14:09:34 PST 2010
> That's a bug in llvm-gcc; there's a PR in Bugzilla on it, although
> it's down at the moment. The correct semantics for weakref if we
> implement it purely in clang are as follows:
>
> 1. Emit weakref variables as external declarations, and put them on a
> list to go through after everything is emitted.
> 2. For each weakref variable, see if there is an existing declaration
> of the target: if there isn't, build a weak declaration of the target.
> 3. Replace all uses of the weakref with the target.
>
> The only issue with this is that it doesn't interact with inline asm correctly.
Interesting. I did some experimentation with gcc
Compiling
------------------------------------
extern int a(void);
static int c(void) __attribute__((weakref("a")));
void* f(void) {
return (void*)c;
}
-------------------------------
the generated .o by has
WEAK DEFAULT UND a
but if I add
---------------------------------
void* g(void) {
return (void*)a;
}
--------------------------------
the generated file has
GLOBAL DEFAULT UND a
in no case a "c" symbol is produced. In the case of gcc all it does is
pass the work to the assembler via ".weakref c,a".
I see two ways we could implement this:
1) Add support in LLVM. The advantage is that we can also just emit a
.weakref. The problem is that this would have very strange semantics
for LTO.
2) Do it in clang. The first example above would be compiled to
-------------------------------------------------
....
declare extern_weak i32 @a()
----------------------------------------------
but the second example would be compiled to
------------------------------------------
....
declare i32 @a()
----------------------------------------
I think the algorithm is a bit different than what you described:
1) Emit uses of a weakref as uses the target
if (If the target exists in this file) {
nothing to do. There will be no undefined references
} else {
If (the target declaration is marked with __attribute__((weak))) {
declare it using extern_weak.
} else if (there is at least one direct undefined reference to it) {
declare it without extern_weak.
} else {
declare it using extern_weak.
}
}
for now my patch gets clang on the same level as llvm-gcc at least.
> -Eli
>
Cheers,
--
Rafael Ávila de Espíndola
More information about the cfe-commits
mailing list