'Opaque error message for Hello World LLVM pass in C++

I wrote a simple Hello World LLVM pass using the new pass manager. It is important to note that I did not obtain the entire LLVM source and write the pass somewhere in this source tree.

Instead I installed llvm with

sudo apt install llvm

However when I want to compile my pass code to a dynamic library to run it with opt as a plugin I get the following error message (and yes, later on I will also use cmake for this but it gave me a similar error):

$ clang -shared -I/usr/include/llvm-13 -I/usr/include/llvm-c-13 -o libpass_test.so pass_test.cpp

In file included from pass_test.cpp:1:
In file included from /usr/include/llvm-13/llvm/IR/PassManager.h:48:
/usr/include/llvm-13/llvm/IR/PassManagerInternal.h:85:16: error: member reference base type 'bool (llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>)' is not a structure or union
    return Pass.run(IR, AM, ExtraArgs...);
           ~~~~^~~~
/usr/include/llvm-13/llvm/IR/PassManagerInternal.h:67:12: note: in instantiation of member function 'llvm::detail::PassModel<llvm::Function, bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>), llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run' requested here
  explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
           ^
/usr/include/llvm-13/llvm/IR/PassManager.h:547:29: note: in instantiation of member function 'llvm::detail::PassModel<llvm::Function, bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>), llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::PassModel' requested here
    Passes.emplace_back(new PassModelT(std::forward<PassT>(Pass)));
                            ^
pass_test.cpp:29:6: note: in instantiation of function template specialization 'llvm::PassManager<llvm::Function>::addPass<bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>)>' requested here
        FPM.addPass(passHook);
            ^
In file included from pass_test.cpp:1:
In file included from /usr/include/llvm-13/llvm/IR/PassManager.h:48:
/usr/include/llvm-13/llvm/IR/PassManagerInternal.h:88:44: error: type 'bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>)' cannot be used prior to '::' because it has no members
  StringRef name() const override { return PassT::name(); }
                                           ^
/usr/include/llvm-13/llvm/IR/PassManagerInternal.h:67:12: note: in instantiation of member function 'llvm::detail::PassModel<llvm::Function, bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>), llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::name' requested here
  explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
           ^
/usr/include/llvm-13/llvm/IR/PassManager.h:547:29: note: in instantiation of member function 'llvm::detail::PassModel<llvm::Function, bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>), llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::PassModel' requested here
    Passes.emplace_back(new PassModelT(std::forward<PassT>(Pass)));
                            ^
pass_test.cpp:29:6: note: in instantiation of function template specialization 'llvm::PassManager<llvm::Function>::addPass<bool (&)(llvm::StringRef, llvm::PassManager<llvm::Function> &, llvm::ArrayRef<llvm::PassBuilder::PipelineElement>)>' requested here
        FPM.addPass(passHook);
            ^
2 errors generated.

The source code is this:

pass_test.h:

#ifndef PASS_TEST_H
#define PASS_TEST_H

using namespace llvm;

class PassTest : public PassInfoMixin<PassTest> {
public:
        PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};

#endif

pass_test.cpp:

#include <llvm/IR/PassManager.h>
#include <llvm/Passes/PassBuilder.h>
#include <llvm/Passes/PassPlugin.h>
#include <llvm/Support/raw_ostream.h>

#include "pass_test.h"

//------------------------------------------------------------------------------
// The pass functionality
//------------------------------------------------------------------------------
PreservedAnalyses PassTest::run(Function &F, FunctionAnalysisManager &AM)
{
        errs() << F.getName() << "\n";
        return PreservedAnalyses::all();
}


//------------------------------------------------------------------------------
// Register the pass as a plugin for opt
//------------------------------------------------------------------------------

// the hook of my pass for opt
bool passHook(StringRef Name, FunctionPassManager &FPM,
                ArrayRef<PassBuilder::PipelineElement>)
{
        if (Name != "pass_test")
                return false;

        FPM.addPass(passHook);
        return true;
}


// the pass builder hook using my pass hook
void builderHook(PassBuilder &PB)
{
        PB.registerPipelineParsingCallback(passHook);
}

// information for this specific pass
llvm::PassPluginLibraryInfo getPassTestPluginInfo()
{
        return {LLVM_PLUGIN_API_VERSION, "pass_test",
                LLVM_VERSION_STRING, builderHook};
}

// public entry for my pass
extern "C" LLVM_ATTRIBUTE_WEAK llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo()
{
        return getPassTestPluginInfo();
}

I am happy for any hint what the actual problem is because I don't understand what exactly this error message is telling me.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source