Ich habe eine ganze Anzahl von Beispielen gesehen, die über das Erstellen von Funktionen gehen überschreitet (zB Brandon Holt und Adrian Sampson), aber ich bin neugierig auf die Schwierigkeit bei der Erstellung eines Moduls zu tun diese sehr ähnlichen Probleme. Ich habe versucht, einen Modul-Durchlauf zu implementieren, um die globalen Variablennamen anzuzeigen, die dieses Beispiel und llvm Quellcode benutzen, um zu verstehen, wie man durch Mitglieder iterieren muss.Verwendung von FunctionPass über ModulePass beim Erstellen von LLVM passiert
Ich verwende eine Quelle kompilierte Version von LLVM, und am Beispiel von den oben genannten Links den Pass hinzuzufügen, und dann ausgeführt wird:
$ clang -Xclang -load -Xclang build/Skeleton/libSkeletonPass.so something.c
die dann dieses Kauderwelsch zurückgibt. Wenn ich jedoch einen functionPass implementiere und einfach Auto verwende, um den zu initialisierenden Typ zu bestimmen, ist das sehr einfach und funktioniert. Werde ich die globalen Variablen nur falsch herum drucken?
Dies ist ein Pastebin der Fehlerausgabe vom Terminal. 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;
}