Я работаю над учебным пособием по калейдоскопу LLVM . Все работает нормально, кроме локальных внешних (в отличие от таких вещей, как математические функции).
[c34n10 kaleidoscope] ./toy
ready> extern sin(x); sin(1);
ready> Read extern:
declare double @sin(double)
ready> ready> Evaluated to 0.841471
ready> extern putchard(x); putchard(120);
ready> Read extern:
declare double @putchard(double)
ready> ready> Failure value returned from cantFail wrapped call
UNREACHABLE executed at /gpfs/loomis/project/fas/manohar/emb99/llvm/include/llvm/Support/Error.h:732!
Aborted (core dumped)
putchard
объявлено в моем коде, согласно учебнику, как
/// putchard - putchar that takes a double and returns 0.
extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
Другие посты онлайн предполагают, что эта проблема может быть вызвана не компиляцией с -rdynamic
, но я.
Фактическая ошибка происходит со следующим кодом
auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
assert(ExprSymbol && "Function not found");
// cast to double-returning function
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());
и некоторые исследования с GDB показывают, что флаг hasError
для ExprSymbol.getAddress()
является истинным, поэтому cantFail
терпит неудачу. Что касается того, почему этот флаг установлен, я в растерянности.
Кажется, это не проблема самой функции: из GDB я могу успешно запустить call putchard(120)
, поэтому символ определенно существует в исполняемом файле.
Наконец, мой make-файл выглядит как
LIBS=core orcjit native analysis executionengine instcombine object runtimedyld scalaropts support
FLAGS=`llvm-config --cxxflags --ldflags --system-libs --libs $(LIBS)`
%: %.cpp
clang++ -v -g3 -O0 $^ -o $@ $(FLAGS) -rdynamic