我已经看到了很多关于创建函数传递的示例(例如Brandon Holt和Adrian Sampson),但我很好奇创建模块传递来执行这些操作的难度非常相似的问题。我尝试使用此示例和llvm源代码实现模块传递以显示全局变量名称,以了解如何遍历成员。
我正在使用LLVM的源编译版本,并使用上面链接中的示例添加传递,然后运行:
$ clang -Xclang -load -Xclang build/Skeleton/libSkeletonPass.so something.c
然后返回这个胡言乱语。但是,如果我实现一个functionPass并且只使用Auto来确定要初始化的类型,那么它非常直接且有效。我只是想以错误的方式打印全局变量吗?
这是终端输出的错误的pastebin。 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;
}