I have been trying to write an LLVM Pass Following a mixture of this and this part of the documentation.
I am assuming that since Mac comes with Clang and LLVM I should be able to use their installation to create plugins. So I made a directory layout as follows:
optimizations
CMakeLists.txt (--> outer)
Hello
CMakeLists.txt (--> inner)
Hello.cpp
The contents of "outer"
is:
find_package(LLVM REQUIRED CONFIG)
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(AddLLVM)
add_definitions(${LLVM_DEFINITONS})
include_directories(${LLVM_INCLUDE_DIRS})
add_subdirectory(Hello)
The contents of "inner"
are:
add_llvm_loadable_module(LLVMHello
Hello.cpp
)
In Hello.cpp I have what is made in the other set of instructions:
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
};
}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass", false, false);
So then I went to the optimizations directory and ran cmake CMakeLists.txt
. This created a Makefile
in each directory as well as a bunch of other cmake related files. This worked fine but then I tried running make
and at first I got errors similar to here. To fix that, at the top of Hello.cpp
I added:
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
But now I get these errors:
/usr/local/include/llvm/Support/AlignOf.h:53:10: error: unknown type name 'constexpr'
static constexpr unsigned Alignment =
^
/usr/local/include/llvm/Support/AlignOf.h:53:20: error: expected member name or ';' after declaration specifiers
static constexpr unsigned Alignment =
~~~~~~~~~~~~~~~~ ^
/usr/local/include/llvm/Support/AlignOf.h:59:42: error: use of undeclared identifier 'Alignment'
enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:60:42: error: use of undeclared identifier 'Alignment'
enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:61:42: error: use of undeclared identifier 'Alignment'
enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:62:43: error: use of undeclared identifier 'Alignment'
enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:64:39: error: use of undeclared identifier 'Alignment'
enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:65:39: error: use of undeclared identifier 'Alignment'
enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:66:39: error: use of undeclared identifier 'Alignment'
enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:67:40: error: use of undeclared identifier 'Alignment'
enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
^
/usr/local/include/llvm/Support/AlignOf.h:71:23: error: unknown type name 'constexpr'
template <typename T> constexpr unsigned AlignOf<T>::Alignment;
^
/usr/local/include/llvm/Support/AlignOf.h:71:33: error: expected unqualified-id
template <typename T> constexpr unsigned AlignOf<T>::Alignment;
I'm not exactly sure what to do about these errors. Any help would be appreciated.
Adding set(CMAKE_CXX_STANDARD 11)
to my CMakeLists.txt
gives:
Hello[ 50%] Linking CXX shared module LLVMHello.dylib
Undefined symbols for architecture x86_64:
"llvm::FunctionPass::assignPassManager(llvm::PMStack&, llvm::PassManagerType)", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::FunctionPass::createPrinterPass(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::getAnalysisUsage(llvm::AnalysisUsage&) const", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::getAdjustedAnalysisPointer(void const*)", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::getPassName() const", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::verifyAnalysis() const", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Value::getName() const", referenced from:
(anonymous namespace)::Hello::runOnFunction(llvm::Function&) in Hello.o
"llvm::errs()", referenced from:
(anonymous namespace)::Hello::runOnFunction(llvm::Function&) in Hello.o
"llvm::raw_ostream::write(char const*, unsigned long)", referenced from:
llvm::raw_ostream::operator<<(llvm::StringRef) in Hello.o
"llvm::Pass::dumpPassStructure(unsigned int)", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::getAsPMDataManager()", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::~Pass()", referenced from:
llvm::FunctionPass::~FunctionPass() in Hello.o
"llvm::Pass::print(llvm::raw_ostream&, llvm::Module const*) const", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::raw_ostream::write(unsigned char)", referenced from:
llvm::raw_ostream::operator<<(char) in Hello.o
"llvm::FunctionPass::getPotentialPassManagerType() const", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"vtable for llvm::FunctionPass", referenced from:
llvm::FunctionPass::FunctionPass(char&) in Hello.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"llvm::Pass::preparePassManager(llvm::PMStack&)", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::Pass::getAsImmutablePass()", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"vtable for llvm::Pass", referenced from:
llvm::Pass::Pass(llvm::PassKind, char&) in Hello.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"llvm::raw_ostream::write_escaped(llvm::StringRef, bool)", referenced from:
(anonymous namespace)::Hello::runOnFunction(llvm::Function&) in Hello.o
"llvm::Pass::releaseMemory()", referenced from:
vtable for (anonymous namespace)::Hello in Hello.o
"llvm::PassRegistry::getPassRegistry()", referenced from:
llvm::RegisterPass<(anonymous namespace)::Hello>::RegisterPass(char const*, char const*, bool, bool) in Hello.o
"llvm::PassRegistry::registerPass(llvm::PassInfo const&, bool)", referenced from:
llvm::RegisterPass<(anonymous namespace)::Hello>::RegisterPass(char const*, char const*, bool, bool) in Hello.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Hello/LLVMHello.dylib] Error 1
make[1]: *** [Hello/CMakeFiles/LLVMHello.dir/all] Error 2
make: *** [all] Error 2