blob: 3476e71f0cc0f61178e2a2ab80df84fbd54235f5 [file] [log] [blame]
/*
* Formatting.cpp
*/
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llbrowse/Formatting.h"
using namespace llvm;
void printType(wxTextOutputStream & out, const Module* module,
const Type* ty, uint32_t maxDepth) {
std::string typeName = module->getTypeName(ty);
if (!typeName.empty()) {
out << wxString::From8BitData(&*typeName.begin(), typeName.size());
return;
}
printTypeExpansion(out, module, ty, maxDepth);
}
void printTypeExpansion(wxTextOutputStream & out, const Module* module,
const Type* ty, uint32_t maxDepth) {
switch (ty->getTypeID()) {
case Type::VoidTyID: out << _("void"); break;
case Type::FloatTyID: out << _("float"); break;
case Type::DoubleTyID: out << _("double"); break;
case Type::X86_FP80TyID: out << _("x86_fp80"); break;
case Type::FP128TyID: out << _("fp128"); break;
case Type::PPC_FP128TyID: out << _("ppc_fp128"); break;
#if HAVE_LLVM_TYPE_X86_FP80TY_ID
case Type::X86_MMXTyID: out << _("x86mmx"); break;
#endif
case Type::MetadataTyID: out << _("metadata"); break;
case Type::LabelTyID: out << _("label"); break;
case Type::IntegerTyID: {
const IntegerType* iTy = cast<IntegerType>(ty);
out << _("int") << iTy->getBitWidth();
break;
}
case Type::FunctionTyID: {
const FunctionType* fTy = cast<FunctionType>(ty);
printType(out, module, fTy->getReturnType(), maxDepth);
out << _(" (");
unsigned numParams = fTy->getNumParams();
for (unsigned i = 0; i < numParams; ++i) {
if (i != 0) {
out << _(", ");
}
printType(out, module, fTy->getParamType(i), maxDepth);
}
out << _(")");
break;
}
case Type::StructTyID: {
const StructType* sTy = cast<StructType>(ty);
if (maxDepth == 0) {
out << _("{...}");
} else {
out << (sTy->isPacked() ? _("<{") : _("{"));
for (int i = 0, ct = sTy->getNumContainedTypes(); i < ct; ++i) {
if (i != 0) {
out << _(", ");
}
if (maxDepth == 1 && i > 3) {
out << _("...");
break;
}
printType(out, module, sTy->getContainedType(i), maxDepth - 1);
}
out << (sTy->isPacked() ? _("}>") : _("}"));
}
(void) sTy;
break;
}
case Type::ArrayTyID: {
const ArrayType* aTy = cast<ArrayType>(ty);
out << _("[") << int(aTy->getNumElements()) << _(" x ");
printType(out, module, aTy->getContainedType(0), maxDepth);
out << _("]");
break;
}
case Type::PointerTyID: {
const PointerType* pTy = cast<PointerType>(ty);
printType(out, module, ty->getContainedType(0), maxDepth);
if (pTy->getAddressSpace() != 0) {
out << _(" addrspace (") << pTy->getAddressSpace() << _(")");
}
out << _("*");
break;
}
case Type::VectorTyID: {
const VectorType* vTy = cast<VectorType>(ty);
out << _("<") << int(vTy->getNumElements()) << _(" x ");
printType(out, module, vTy->getContainedType(0), maxDepth);
out << _(">");
break;
}
case Type::OpaqueTyID:
out << _("opaque");
break;
default:
out << _("???");
break;
}
}
/// Pretty-print an LLVM constant expression to a stream.
/// 'maxDepth' limits expansion of complex expressions.
void printConstant(wxTextOutputStream & out, const llvm::Module* module,
const llvm::Constant* val, uint32_t maxDepth) {
if (const ConstantInt* ci = dyn_cast<ConstantInt>(val)) {
SmallVector<char, 16> intVal;
ci->getValue().toString(intVal, 10, true);
out << toWxStr(StringRef(intVal.data(), intVal.size()));
} else if (const ConstantFP* cf = dyn_cast<ConstantFP>(val)) {
// TODO: Implement
(void) cf;
out << _("FP?");
} else if (const ConstantAggregateZero* cz =
dyn_cast<ConstantAggregateZero>(val)) {
(void) cz;
out << _("constantzero");
} else if (const ConstantArray* ca = dyn_cast<ConstantArray>(val)) {
if (maxDepth > 0) {
out << _("[");
printConstantList(out, module, ca, maxDepth);
out << _("]");
} else {
out << _("[...]");
}
} else if (const ConstantStruct* cs = dyn_cast<ConstantStruct>(val)) {
if (maxDepth > 0) {
out << _("{");
printConstantList(out, module, cs, maxDepth);
out << _("}");
} else {
out << _("{...}");
}
} else if (const ConstantVector* cv = dyn_cast<ConstantVector>(val)) {
if (maxDepth > 0) {
out << _("<");
printConstantList(out, module, cv, maxDepth);
out << _(">");
} else {
out << _("<...>");
}
} else if (isa<ConstantPointerNull>(val)) {
printType(out, module, val->getType(), maxDepth);
out << _(" null");
} else if (const BlockAddress* ba = dyn_cast<BlockAddress>(val)) {
// TODO: Implement
(void) ba;
out << _("BA?");
} else if (const ConstantExpr* ce = dyn_cast<ConstantExpr>(val)) {
out << wxString::From8BitData(ce->getOpcodeName());
if (maxDepth > 0) {
out << _("(");
printConstantList(out, module, ce, maxDepth);
out << _(")");
} else {
out << _("(...)");
}
(void) ce;
} else if (isa<UndefValue>(val)) {
out << _("undef");
} else if (const GlobalValue* gv = dyn_cast<GlobalValue>(val)) {
out << toWxStr(gv->getName());
} else {
out << _("???");
}
}
void printConstantList(wxTextOutputStream & out, const llvm::Module* module,
const llvm::Constant* parent, uint32_t maxDepth) {
unsigned ct = parent->getNumOperands();
for (unsigned i = 0; i < ct; ++i) {
if (i != 0) {
out << _(", ");
}
if (i > 3) {
out << _("...");
break;
}
printConstant(out, module, cast<Constant>(parent->getOperand(i)),
maxDepth - 1);
}
}
void printMetadata(wxTextOutputStream & out, const llvm::Value* nodeVal,
uint32_t maxDepth) {
if (const MDString* ms = dyn_cast<MDString>(nodeVal)) {
out << _("\"") << toWxStr(ms->getString()) << _("\"");
} else if (const MDNode* m = dyn_cast<MDNode>(nodeVal)) {
if (maxDepth > 0) {
out << _("{");
for (unsigned i = 0; i < m->getNumOperands(); ++i) {
if (i != 0) {
out << _(", ");
}
if (maxDepth == 1 && i > 3) {
out << _("...");
break;
}
printMetadata(out, m->getOperand(i), maxDepth - 1);
}
out << _("}");
} else {
out << _("{...}");
}
} else if (const GlobalVariable* gv = dyn_cast<GlobalVariable>(nodeVal)) {
out << toWxStr(gv->getName());
} else if (const Function* fn = dyn_cast<Function>(nodeVal)) {
out << toWxStr(fn->getName());
} else if (const ConstantInt* ci = dyn_cast<ConstantInt>(nodeVal)) {
SmallVector<char, 16> intVal;
ci->getValue().toString(intVal, 10, true);
out << toWxStr(StringRef(intVal.data(), intVal.size()));
} else {
out << _("???");
}
}