//===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
//
// This library converts LLVM code to C code, compilable by GCC.
//
//===-----------------------------------------------------------------------==//
#include "llvm/Assembly/CWriter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/SymbolTable.h"
#include "llvm/SlotCalculator.h"
#include "llvm/Analysis/FindUsedTypes.h"
#include "llvm/Analysis/ConstantsScanner.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/InstIterator.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include <algorithm>
#include <set>
#include <sstream>
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;
bool needsMalloc;
map<const ConstantFP *, unsigned> FPConstantMap;
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(std::ostream &Out, 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 printModule(Module *M);
void printSymbolTable(const SymbolTable &ST);
void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
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) ||
isa<LoadInst>(I)) // Don't inline a load across a store!
return