//===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
//
// This library implements the functionality defined in llvm/Assembly/CWriter.h
//
// TODO : Recursive types.
//
//===-----------------------------------------------------------------------==//
#include "llvm/Assembly/CWriter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/iOperators.h"
#include "llvm/Pass.h"
#include "llvm/SymbolTable.h"
#include "llvm/SlotCalculator.h"
#include "llvm/Analysis/FindUsedTypes.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/InstIterator.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include <algorithm>
#include <set>
using std::string;
using std::map;
using std::ostream;
namespace {
class CWriter : public Pass, public InstVisitor<CWriter> {
ostream &Out;
SlotCalculator *Table;
const Module *TheModule;
map<const Type *, string> TypeNames;
std::set<const Value*> MangledGlobals;
std::set<const StructType *> StructPrinted;
public:
CWriter(ostream &o) : Out(o) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<FindUsedTypes>();
}
virtual bool run(Module &M) {
// Initialize
Table = new SlotCalculator(&M, false);
TheModule = &M;
// Ensure that all structure types have names...
bool Changed = nameAllUsedStructureTypes(M);
// Run...
printModule(&M);
// Free memory...
delete Table;
TypeNames.clear();
MangledGlobals.clear();
return false;
}
ostream &printType(const Type *Ty, const string &VariableName = "",
bool IgnoreName = false, bool namedContext = true);
void writeOperand(Value *Operand);
void writeOperandInternal(Value *Operand);
string getValueName(const Value *V);
private :
bool nameAllUsedStructureTypes(Module &M);
void parseStruct(const Type *Ty);
void printModule(Module *M);
void printSymbolTable(const SymbolTable &ST);
void printGlobal(const GlobalVariable *GV);
void printFunctionSignature(const Function *F, bool Prototype);
void printFunction(Function *);
void printConstant(Constant *CPV);
void printConstantArray(ConstantArray *CPA);
// isInlinableInst - Attempt to inline instructions into their uses to build
// trees as much as possible. To do this, we have to consistently decide
// what is acceptable to inline, so that variable declarations don't get
// printed and an extra copy of the expr is not emitted.
//
static bool isInlinableInst(const Instruction &I) {
// Must be an expression, must be used exactly once. If it is dead, we
// emit it inline where it would go.
if (I.getType() == Type::VoidTy || I.use_size() != 1 ||
isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I))
return false;
// Only inline instruction it it's use is in the same BB as the inst.
return I.getParent() == cast<Instruction>(I.use_back())->getParent();
}
// Instruction visitation functions
friend class InstVisitor<CWriter>;
void visitReturnInst(ReturnInst &I);
void visitBranchInst(BranchInst &I);
void visitPHINode(PHINode &I) {}
void visitBinaryOperator(Instruction &I);
void visitCastInst (CastInst &I);
void visitCallInst (CallInst &I);
void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
void visitMallocInst(MallocInst &I);
void visitAllocaInst(AllocaInst &I);
void visitFreeInst (FreeInst &I);
void visitLoadInst (LoadInst &I);
void visitStoreInst (StoreInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitInstruction(Instruction &I) {
std::cerr <<