2016-05-04 14 views
1

Ich überlege mir, ein Tool zu erstellen, mit dem ich den generierten LLVM-IR-Code für jede Anweisung/Funktion in meiner ursprünglichen Quelldatei visualisieren kann. Etwas wie this aber für LLVM-IR.Parsing LLVM IR-Code (mit Debug-Symbolen), um es zurück auf die ursprüngliche Quelle

Die Schritte solches Werkzeug zu bauen, so scheinen weit zu sein:

  • starten durch mit LLVM-IR AST Builder.
  • Parse generierten IR-Code.
  • Auf Caret-Position erhalten AST-Element.
  • Lesen Sie das Element Umfang, Zeile, Spalte und Datei und signalisieren Sie es auf der ursprünglichen Quelldatei.

Ist dies der richtige Weg, um es zu nähern? Vermute ich es zu sehr?

+0

Blick ist ganz richtig. Die Sache, die Sie erreichen möchten, ist ziemlich einfach mit llvm, aber erfordert eine Menge von UI-Code –

Antwort

2

Ich denke, Ihr Ansatz ist ziemlich richtig. Der UI-Teil wird wahrscheinlich ziemlich lang sein, damit ich mich auf den llvm-Teil konzentriere.

Angenommen, Sie beginnen mit einer Eingabedatei, die Ihr LLVM-IR enthält.

Schritt 1 Prozessmodule:
Read Dateiinhalt in einen String. Dann Bauen Sie ein Modul von ihm, und verarbeiten sie die Debug-Informationen zu bekommen:

llvm::MemoryBuffer* buf = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(fileContent)).release(); 
llvm::SMDiagnostic diag; 
llvm::Module* module = llvm::parseIR(buf->getMemBufferRef(), diag, *context).release(); 
llvm::DebugInfoFinder* dif = new llvm::DebugInfoFinder(); 
dif->processModule(*module); 

Schritt 2 Iterierte auf Anweisungen:
einmal damit fertig, Sie einfach auf Funktion laufen kann und Blöcke und Anweisungen:

// pseudo code for loops (real code is a bit long) 
foreach(llvm::Function f in module.functions) 
{ 
    foreach(llvm::BasicBlock b in f.BasicBlockList) 
    { 
     foreach(llvm::Instruction inst in b.InstList) 
     { 
     llvm::DebugLoc dl = inst.getDebugLoc(); 
     unsigned line = dl->getLine(); 
     // accordingly populate some dictionary between your instructions and source code 
     } 
    } 
} 

Schritt 3 Update UI
Dies ist eine andere Geschichte ...

+0

Was soll der * Kontext sein? Ich habe Beispiele gefunden, in denen getGlobalContext() verwendet wird, aber ich habe es nicht auf meinem "llvm/IR/LLVMContext.h" definiert. –

+0

es ist nur ein neuer Kontext, vom Typ llvm :: LLVMContext –

+1

Wie @Regis Portalez sagte der For-Code ist ein bisschen länger. Um über jede Sammlung zu iterieren, finde ich es so: for (auto curFref = m-> getFunctionList(). Begin(), endFref = modul-> getFunctionList(). End(); curFref! = EndFref; ++ curFref) {...} –