LLVM linkage flags

An enumeration for the kinds of linkage for global values.

Hi, I’m currently writing a compiler that takes llvm-ir input. I’m a little confused by the following linkage flags:

Enumerator:

ExternalLinkage: Externally visible function

AvailableExternallyLinkage: Available for inspection, not emission.

LinkOnceAnyLinkage: Keep one copy of function when linking (inline)

LinkOnceODRLinkage: Same, but only replaced by something equivalent.

WeakAnyLinkage: Keep one copy of named function when linking (weak)

WeakODRLinkage: Same, but only replaced by something equivalent.

AppendingLinkage: Special purpose, only applies to global arrays.

InternalLinkage: Rename collisions when linking (static functions).

PrivateLinkage: Like Internal, but omit from symbol table.

ExternalWeakLinkage: ExternalWeak linkage description.

CommonLinkage: Tentative definitions.

When I have source code like:

int x = 0;
int main(){…}

I end up with an ExternalLinkage flag on x. Why would this not have CommonLinkage? When I have the same code as above and don’t initialize x,
I end up with the CommonLinkage flag.

Any insight would be appreciated.

Best,
M.R.

ExternalLinkage: Externally visible function

That documentation is not ideal. As you've discovered it applies to
things other than functions.

When I have source code like:

int x = 0;
int main(){...}

I end up with an ExternalLinkage flag on x. Why would this not have
CommonLinkage? When I have the same code as above and don't initialize x,
I end up with the CommonLinkage flag.

It comes down to the requirements of the C specification. You're
allowed to have a simple "int x;" in multiple files and link them
together, but not an "int x = 0;". The rule dates from the bad-old
days of pre-ANSI C, and wouldn't be included in any sensible language
being created now.

But because of that rule, the two situations tend to be treated
differently in object formats so the linker can complain if you get it
wrong, and so LLVM has to have a way to represent it.

Cheers.

Tim.

It's no longer a tentative definition because you have initialized it.
Doesn't matter what it has been initialized to i don't think...

Pretty decent description here:
https://blogs.oracle.com/ali/entry/what_are_tentative_symbols

HTH