0
votes

I am looking at a llvm ir file converted from a cpp file by clang. But I found there were several functions in llvm ir file only with declaration without definition. And all these functions are not the "build-in" functions like:

declare i32 @puts(i8* nocapture)

It's like:

declare void @_ZNK5Arrow7BaseRow9getColumnINS_11IpGenPrefixEEEvtRT_(%"class.Arrow::BaseRow"*, i16 zeroext, %"class.Arrow::IpGenPrefix"* dereferenceable(24)) #0

It seems like those functions are using some external definition? I am new to LLVM IR. And I was wondering is there a way that LLVM IR can do like cpp library, I can store the functions I will use in some LLVM IR libraries and use them in a .ll file by just do something like include ?

Thanks

1
Are you sure you include the file in which Arrow::BaseRow::getColumn<Arrow::IpGenPrefix> is defined? - eush77
No, there is no include declaration type. It may be achieved, obviously, by some utility that would insert the declarations. - Frank C.
@eush77 As I mentioned, this llvm ir is converted from a cpp file with clang. The cpp file include the file in which getColumn is defined. But I was wondering when I use MCJIT to execute the function in llvm ir, how would I execute the function only declared in llvm ir without definition. Is there any way the function in llvm ir only declared and defined in other files like(cpp file)? And how can I generate this kind of function? - He Yucheng

1 Answers

1
votes

It seems like those functions are using some external definition?

Exactly. declare keyword indicates a function declaration, as opposed to function definition, and function declarations can only be linked externally:

It is illegal for a function declaration to have any linkage type other than external or extern_weak.

The reason Clang generated declarations instead of definitions is (most likely) that these functions were not defined in the translation unit that was given to it.

The declarations are resolved during linking. To link several LLVM modules together, use llvm-link tool.

For example, suppose lib.cpp defines function foo() which is used in main.cpp.

$ clang++ -c -emit-llvm main.cpp lib.cpp

This command compiles these files to LLVM IR and creates two modules main.bc and lib.bc. main.bc contains just a declaration of foo() because this function is defined in a separate translation unit. The definition of foo() is in lib.bc.

$ llvm-link main.bc lib.bc -o all.bc

This command links main.bc and lib.bc into a single module, which now contains the definition of foo().