Я видел довольно много примеров, которые переходят на создание пропусков функций (например, Brandon Holt и Adrian Sampson), но мне любопытно узнать о сложности создания прохода модуля для выполнения эти очень похожие проблемы. Я попытался реализовать пропуск модуля, чтобы отображать имена глобальных переменных, используя этот пример, и исходный код llvm, чтобы понять, как вы должны проходить через членов.Использование функцииPass over ModulePass при создании пропусков LLVM
Я использую скомпилированную версию LLVM и используя пример из ссылки выше, чтобы добавить проход, а затем работает:
$ clang -Xclang -load -Xclang build/Skeleton/libSkeletonPass.so something.c
который затем возвращает эту тарабарщину. Однако, если я реализую функциюPass и просто использую Auto для определения типа, который будет инициализирован, он очень прямолинейный и работает. Я просто собираюсь напечатать глобальные переменные неправильно?
Это пастообразный сигнал ошибки, выводимой с терминала. link
Skeleton.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/LLVMContext.h"
using namespace llvm;
namespace {
// Helper method for converting the name of a LLVM type to a string
static std::string LLVMTypeAsString(const Type *T) {
std::string TypeName;
raw_string_ostream N(TypeName);
T->print(N);
return N.str();
}
struct SkeletonPass : public ModulePass {
static char ID;
SkeletonPass() : ModulePass(ID) {}
virtual bool runOnModule(Module &M) {
for (Module::const_global_iterator GI = M.global_begin(),
GE = M.global_end(); GI != GE; ++GI) {
errs() << "Found global named: " << GI->getName()
<< "\tType: " << LLVMTypeAsString(GI->getType()) << "!\n";
}
return false;
}
};
}
char SkeletonPass::ID = 0;
// Automatically enable the pass.
// http://adriansampson.net/blog/clangpass.html
static void registerSkeletonPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new SkeletonPass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
registerSkeletonPass);
something.c
int value0 = 5;
int main(int argc, char const *argv[])
{
int value = 4;
value += 1;
return 0;
}