//===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
//
-// This library implements the functionality defined in llvm/Assembly/CWriter.h
-//
-// TODO : Recursive types.
+// This library converts LLVM code to C code, compilable by GCC.
//
//===-----------------------------------------------------------------------==//
#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"
const Module *TheModule;
map<const Type *, string> TypeNames;
std::set<const Value*> MangledGlobals;
+
+ map<const ConstantFP *, unsigned> FPConstantMap;
public:
CWriter(ostream &o) : Out(o) {}
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);
// Do not need parens around "* NameSoFar" if NameSoFar consists only
// of zero or more '*' chars *and* this is not an unnamed pointer type
// such as the result type in a cast statement. Otherwise, enclose in ( ).
- if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext)
+ if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext ||
+ PTy->getElementType()->getPrimitiveID() == Type::ArrayTyID)
ptrName = "(" + ptrName + ")"; //
return printType(PTy->getElementType(), ptrName);
(unsigned char)cast<ConstantUInt>(CPA->getOperand(i))->getValue();
if (isprint(C)) {
- Out << C;
+ if (C == '"')
+ Out << "\\\"";
+ else
+ Out << C;
} else {
switch (C) {
case '\n': Out << "\\n"; break;
case '\r': Out << "\\r"; break;
case '\v': Out << "\\v"; break;
case '\a': Out << "\\a"; break;
+ case '\"': Out << "\\\""; break;
+ case '\'': Out << "\\\'"; break;
default:
Out << "\\x";
Out << ( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A');
Out << cast<ConstantUInt>(CPV)->getValue() << "ull"; break;
case Type::FloatTyID:
- case Type::DoubleTyID:
- Out << cast<ConstantFP>(CPV)->getValue(); break;
+ case Type::DoubleTyID: {
+ ConstantFP *FPC = cast<ConstantFP>(CPV);
+ map<const ConstantFP *, unsigned>::iterator I = FPConstantMap.find(FPC);
+ if (I != FPConstantMap.end()) {
+ // Because of FP precision problems we must load from a stack allocated
+ // value that holds the value in hex.
+ Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
+ << "*)&FloatConstant" << I->second << ")";
+ } else {
+ Out << FPC->getValue();
+ }
+ break;
+ }
case Type::ArrayTyID:
printConstantArray(cast<ConstantArray>(CPV));
// get declaration for alloca
Out << "/* Provide Declarations */\n"
- << "#include <malloc.h>\n"
<< "#include <alloca.h>\n\n"
// Provide a definition for null if one does not already exist,
<< "#ifndef NULL\n#define NULL 0\n#endif\n\n"
<< "#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n"
+ << "\n\n/* Support for floating point constants */\n"
+ << "typedef unsigned long long ConstantDoubleTy;\n"
+
<< "\n\n/* Global Declarations */\n";
// First output all the declarations for the program, because C requires
// Global variable declarations...
if (!M->gempty()) {
- Out << "\n/* Global Variable Declarations */\n";
+ Out << "\n/* External Global Variable Declarations */\n";
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
- Out << (I->hasExternalLinkage() ? "extern " : "static ");
- printType(I->getType()->getElementType(), getValueName(I));
- Out << ";\n";
+ if (I->hasExternalLinkage()) {
+ Out << "extern ";
+ printType(I->getType()->getElementType(), getValueName(I));
+ Out << ";\n";
+ }
}
}
}
}
- // Output the global variable contents...
+ // Output the global variable definitions and contents...
if (!M->gempty()) {
- Out << "\n\n/* Global Data */\n";
+ Out << "\n\n/* Global Variable Definitions and Initialization */\n";
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) {
- if (I->hasInternalLinkage()) Out << "static ";
+ if (I->hasExternalLinkage())
+ continue; // printed above!
+ Out << "static ";
printType(I->getType()->getElementType(), getValueName(I));
if (I->hasInitializer()) {
}
-// printSymbolTable - Run through symbol table looking for named constants
-// if a named constant is found, emit it's declaration...
-// Assuming that symbol table has only types and constants.
+/// printSymbolTable - Run through symbol table looking for type names. If a
+/// type name is found, emit it's declaration...
+///
void CWriter::printSymbolTable(const SymbolTable &ST) {
- for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
- SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
- SymbolTable::type_const_iterator End = ST.type_end(TI->first);
-
- for (; I != End; ++I)
- if (const Type *Ty = dyn_cast<StructType>(I->second)) {
- string Name = "struct l_" + makeNameProper(I->first);
- Out << Name << ";\n";
- TypeNames.insert(std::make_pair(Ty, Name));
- }
+ // If there are no type names, exit early.
+ if (ST.find(Type::TypeTy) == ST.end())
+ return;
+
+ // We are only interested in the type plane of the symbol table...
+ SymbolTable::type_const_iterator I = ST.type_begin(Type::TypeTy);
+ SymbolTable::type_const_iterator End = ST.type_end(Type::TypeTy);
+
+ // Print out forward declarations for structure types before anything else!
+ Out << "/* Structure forward decls */\n";
+ for (; I != End; ++I)
+ if (const Type *STy = dyn_cast<StructType>(I->second)) {
+ string Name = "struct l_" + makeNameProper(I->first);
+ Out << Name << ";\n";
+ TypeNames.insert(std::make_pair(STy, Name));
+ }
+
+ Out << "\n";
+
+ // Now we can print out typedefs...
+ Out << "/* Typedefs */\n";
+ for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
+ const Type *Ty = cast<Type>(I->second);
+ string Name = "l_" + makeNameProper(I->first);
+ Out << "typedef ";
+ printType(Ty, Name);
+ Out << ";\n";
}
Out << "\n";
- for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
- SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
- SymbolTable::type_const_iterator End = ST.type_end(TI->first);
-
- for (; I != End; ++I) {
- const Value *V = I->second;
- if (const Type *Ty = dyn_cast<Type>(V)) {
- string Name = "l_" + makeNameProper(I->first);
- if (isa<StructType>(Ty))
- Name = "struct " + makeNameProper(Name);
- else
- Out << "typedef ";
+ // Keep track of which structures have been printed so far...
+ std::set<const StructType *> StructPrinted;
- printType(Ty, Name, true);
- Out << ";\n";
+ // Loop over all structures then push them into the stack so they are
+ // printed in the correct order.
+ //
+ Out << "/* Structure contents */\n";
+ for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
+ if (const StructType *STy = dyn_cast<StructType>(I->second))
+ printContainedStructs(STy, StructPrinted);
+}
+
+// Push the struct onto the stack and recursively push all structs
+// this one depends on.
+void CWriter::printContainedStructs(const Type *Ty,
+ std::set<const StructType*> &StructPrinted){
+ if (const StructType *STy = dyn_cast<StructType>(Ty)){
+ //Check to see if we have already printed this struct
+ if (StructPrinted.count(STy) == 0) {
+ // Print all contained types first...
+ for (StructType::ElementTypes::const_iterator
+ I = STy->getElementTypes().begin(),
+ E = STy->getElementTypes().end(); I != E; ++I) {
+ const Type *Ty1 = I->get();
+ if (isa<StructType>(Ty1) || isa<ArrayType>(Ty1))
+ printContainedStructs(Ty1, StructPrinted);
}
+
+ //Print structure type out..
+ StructPrinted.insert(STy);
+ string Name = TypeNames[STy];
+ printType(STy, Name, true);
+ Out << ";\n\n";
}
+
+ // If it is an array, check contained types and continue
+ } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)){
+ const Type *Ty1 = ATy->getElementType();
+ if (isa<StructType>(Ty1) || isa<ArrayType>(Ty1))
+ printContainedStructs(Ty1, StructPrinted);
}
}
}
}
- // Finish printing arguments...
- if (FT->isVarArg()) {
+ // Finish printing arguments... if this is a vararg function, print the ...,
+ // unless there are no known types, in which case, we just emit ().
+ //
+ if (FT->isVarArg() && !FT->getParamTypes().empty()) {
if (FT->getParamTypes().size()) Out << ", ";
Out << "..."; // Output varargs portion of signature!
}
printType((*I)->getType(), getValueName(*I));
Out << ";\n";
}
+
+ Out << "\n";
+
+ // Scan the function for floating point constants. If any FP constant is used
+ // in the function, we want to redirect it here so that we do not depend on
+ // the precision of the printed form.
+ //
+ unsigned FPCounter = 0;
+ for (constant_iterator I = constant_begin(F), E = constant_end(F); I != E;++I)
+ if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
+ if (FPConstantMap.find(FPC) == FPConstantMap.end()) {
+ double Val = FPC->getValue();
+
+ FPConstantMap[FPC] = FPCounter; // Number the FP constants
+ Out << " const ConstantDoubleTy FloatConstant" << FPCounter++
+ << " = 0x" << std::hex << *(unsigned long long*)&Val << std::dec
+ << "; /* " << Val << " */\n";
+ }
+
+ Out << "\n";
// print the basic blocks
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
Out << "}\n\n";
Table->purgeFunction();
+ FPConstantMap.clear();
}
// Specific Instruction type classes... note that all of the casts are
writeOperandInternal(Ptr);
- if (HasImplicitAddress && (!CI || !CI->isNullValue()))
+ if (HasImplicitAddress && (!CI || !CI->isNullValue())) {
Out << ")";
+ HasImplicitAddress = false; // HIA is only true if we haven't addressed yet
+ }
+
+ assert(!HasImplicitAddress || (CI && CI->isNullValue()) &&
+ "Can only have implicit address with direct accessing");
- // Print out the -> operator if possible...
- if (CI && CI->isNullValue() && I+1 != E) {
+ if (HasImplicitAddress) {
+ ++I;
+ } else if (CI && CI->isNullValue() && I+1 != E) {
+ // Print out the -> operator if possible...
if ((*(I+1))->getType() == Type::UByteTy) {
Out << (HasImplicitAddress ? "." : "->");
Out << "field" << cast<ConstantUInt>(*(I+1))->getValue();
I += 2;
- } else { // First array index of 0: Just skip it
- ++I;
+ }
+ }
+
+ for (; I != E; ++I)
+ if ((*I)->getType() == Type::LongTy) {
+ Out << "[";
+ writeOperand(*I);
+ Out << "]";
+ } else {
+ Out << ".field" << cast<ConstantUInt>(*I)->getValue();
}
+}
+
+
+
+
+
+/*
+void CWriter::printIndexingExpression(Value *Ptr, User::op_iterator I,
+ User::op_iterator E) {
+ bool HasImplicitAddress = false;
+ // If accessing a global value with no indexing, avoid *(&GV) syndrome
+ if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) {
+ HasImplicitAddress = true;
+ } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) {
+ HasImplicitAddress = true;
+ Ptr = CPR->getValue(); // Get to the global...
+ }
+
+ if (I == E) {
+ if (!HasImplicitAddress)
+ Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
+
+ writeOperandInternal(Ptr);
+ return;
+ }
+
+ const Constant *CI = dyn_cast<Constant>(I->get());
+ if (HasImplicitAddress && (!CI || !CI->isNullValue()))
+ Out << "(&";
+
+ writeOperandInternal(Ptr);
+
+ if (HasImplicitAddress && (!CI || !CI->isNullValue())) {
+ Out << ")";
+ HasImplicitAddress = false; // HIA is only true if we haven't addressed yet
+ }
+
+ assert(!HasImplicitAddress || (CI && CI->isNullValue()) &&
+ "Can only have implicit address with direct accessing");
+
+ if (HasImplicitAddress) {
+ ++I;
+ } else if (CI && CI->isNullValue() && I+1 != E) {
+ // Print out the -> operator if possible...
+ if ((*(I+1))->getType() == Type::UByteTy) {
+ Out << (HasImplicitAddress ? "." : "->");
+ Out << "field" << cast<ConstantUInt>(*(I+1))->getValue();
+ I += 2;
+ }
}
for (; I != E; ++I)
if ((*I)->getType() == Type::LongTy) {
- Out << "[((int) ("; // sign-extend from 32 (to 64) bits
+ Out << "[";
writeOperand(*I);
- Out << " * sizeof(";
- printType(cast<PointerType>(Ptr->getType())->getElementType());
- Out << "))) / sizeof(";
- printType(cast<PointerType>(Ptr->getType())->getElementType());
- Out << ")]";
+ Out << "]";
} else {
Out << ".field" << cast<ConstantUInt>(*I)->getValue();
}
}
+*/
void CWriter::visitLoadInst(LoadInst &I) {
- Out << "*";
+ //Out << "*";
writeOperand(I.getOperand(0));
}
void CWriter::visitStoreInst(StoreInst &I) {
- Out << "*";
+ //Out << "*";
writeOperand(I.getPointerOperand());
Out << " = ";
writeOperand(I.getOperand(0));
}
void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
- Out << "&";
+ //Out << "&";
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
}