//===-- Writer.cpp - Library for writing C files --------------------------===//
//
// This library implements the functionality defined in llvm/Assembly/CWriter.h
// and CLocalVars.h
//
// TODO : Recursive types.
//
//===-----------------------------------------------------------------------==//
#include "llvm/Assembly/CWriter.h"
#include "CLocalVars.h"
#include "llvm/SlotCalculator.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
#include "llvm/Argument.h"
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/iOperators.h"
#include "llvm/SymbolTable.h"
#include "llvm/Support/InstVisitor.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include <algorithm>
#include <strstream>
using std::string;
using std::map;
using std::vector;
using std::ostream;
//===-----------------------------------------------------------------------==//
//
// Implementation of the CLocalVars methods
// Appends a variable to the LocalVars map if it does not already exist
// Also check that the type exists on the map.
void CLocalVars::addLocalVar(const Type *t, const string & var) {
if (!LocalVars.count(t) ||
find(LocalVars[t].begin(), LocalVars[t].end(), var)
== LocalVars[t].end()) {
LocalVars[t].push_back(var);
}
}
static string calcTypeNameVar(const Type *Ty,
map<const Type *, string> &TypeNames,
string VariableName, string NameSoFar);
static std::string getConstStrValue(const Constant* CPV);
static std::string getConstArrayStrValue(const Constant* CPV) {
std::string Result;
// As a special case, print the array as a string if it is an array of
// ubytes or an array of sbytes with positive values.
//
const Type *ETy = cast<ArrayType>(CPV->getType())->getElementType();
bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
if (ETy == Type::SByteTy) {
for (unsigned i = 0; i < CPV->getNumOperands(); ++i)
if (ETy == Type::SByteTy &&
cast<ConstantSInt>(CPV->getOperand(i))->getValue() < 0) {
isString = false;
break;
}
}
if (isString) {
// Make sure the last character is a null char, as automatically added by C
if (CPV->getNumOperands() == 0 ||
!cast<Constant>(*(CPV->op_end()-1))->isNullValue())
isString = false;
}
if (isString) {
Result = "\"";
// Do not include the last character, which we know is null
for (unsigned i = 0, e = CPV->getNumOperands()-1; i != e; ++i) {
unsigned char C = (ETy == Type::SByteTy) ?
(unsigned char)cast<ConstantSInt>(CPV->getOperand(i))->getValue() :
(unsigned char)cast<ConstantUInt>(CPV->getOperand(i))->getValue();
if (isprint(C)) {
Result += C;
} else {
switch (C) {
case '\n': Result += "\\n"; break;
case '\t': Result += "\\t"; break;
case '\r': Result += "\\r"; break;
case '\v': Result += "\\v"; break;
case '\a': Result += "\\a"; break;
default:
Result += "\\x";
Result += ( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A');
Result += ((C&15) < 10) ? ((C&15)+'0')