Linkage Types

Okay, I'm past the GEP "have to dereference pointer first" problem of my
last post.

I now have a linkage error (I get undefined symbol when I try to
assemble the program).

gcc -o test.o test.s says:

/tmp/cczhiFk7.o(.text+0x7): In function `a':
: undefined reference to `_index_'

_index_ is defined like this:

%_index_ = external global long ; <long*> [#uses=12]

But, that's not what I expected to get when I defined it in the compiler
like this:

        TheIndex = new GlobalVariable(
            /*type=*/Type::LongTy,
            /*isConstant=*/false,
            /*Linkage=*/GlobalValue::LinkOnceLinkage,
            /*initializer=*/0,
            /*name=*/"_index_",
            /*parent=*/TheModule
        );
                                                                                                                                                             
So, reading the documentation again, I discover that LinkOnceLinkage is
an _internal_ (static) linkage type. Fine, but why does LLVM give it
"external global" linkage?

Note that the Assembly reference says:
internal: ...
linkonce: ...
weak: ...
appending: ...
externally visible:
        If none of the above identifiers are used, the global is
        externally visible, meaning that it participates in linkage and
        can be used to resolve external symbol references.

But, there's no way to do this in the code. You _must_ supply the third
argument to GlobalVariable's constructor (it doesn't default) and the
only values accepted are GlobalValue::LinkageTypes. If I use
"ExternalLinkage" is this the same as providing nothing in assembly and
getting the default "externally visible"?

Reid.

So, reading the documentation again, I discover that LinkOnceLinkage is
an _internal_ (static) linkage type. Fine, but why does LLVM give it
"external global" linkage?

Anything without an initializer gets external linkage... Try initializing
it with Constant::getNullValue(Type::LongTy).

But, there's no way to do this in the code. You _must_ supply the third
argument to GlobalVariable's constructor (it doesn't default) and the
only values accepted are GlobalValue::LinkageTypes. If I use
"ExternalLinkage" is this the same as providing nothing in assembly and
getting the default "externally visible"?

The thing about LLVM linkage is that linkage types do not apply for
external symbols (not to be confused with 'external linkage symbols').
When you link two translation units together, LLVM changes the external
symbol to work with whatever the linked symbols linkage is. Thus, if you
want to make it 'linkonce', you should give it an initializer (making it
not be an external symbol).

I should probably add an assertion to this effect. :slight_smile:

-Chris