В моем приложении у меня есть 2 модуля LLVM - модуль времени выполнения (содержащий определение функции void foo(int * a)
) и исполняемый модуль (который я создаю с помощью LLVM C ++ API).
В моем исполняемом модуле я создаю int main(int argc, char ** argv)
и хочу поместить llvm::CallInst
в его тело, что вызовет функцию foo()
из модуля времени выполнения.
Вот мой код:
Function * fooF = Function::Create(runtimeModule->getFunction("foo")->getFunctionType(),
GlobalValue::WeakAnyLinkage, "foo", execModule);
После этого я соединяю два модуля вместе:
Linker linker("blabla", execModule, false);
linker.LinkInFile("/path/to/runtime.bc", false);
execModule = linker.releaseModule();
Это компилируется нормально, однако, когда я запускаю Verifier pass для связанного модуля, я получаю:
Global is external, but doesn't have external or dllimport or weak linkage!
void (%i32*)* @foo
invalid linkage type for function declaration
void (%i32*)* @foo
Стоит отметить, что все глобальные объекты в runtime-модуле интернализируются с помощью прохода Internalize. После связывания, но перед запуском Verifier, я запускаю Dead Global Elimination Pass среди некоторых других оптимизаций. И когда я делаю dump()
в результирующем модуле, я вижу, что @foo
, который поступает из модуля времени выполнения, тоже удаляется, несмотря на то, что он используется main()
. Похоже, LLVM считает, что @foo
определение во время выполнения и @foo
объявление в исполняемом файле не связаны.
Я пробовал поиграть с типами связей - не повезло.
Итак, как правильно создать вызов функции из другого модуля?