//===-- AsmWriter.cpp - Printing LLVM as an assembly file -----------------===//
//
// This library implements the functionality defined in llvm/Assembly/Writer.h
//
// Note that these routines must be extremely tolerant of various errors in the
// LLVM code, because it can be used for debugging transformations.
//
//===----------------------------------------------------------------------===//
#include "llvm/Assembly/CachedWriter.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/SlotCalculator.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instruction.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/SymbolTable.h"
#include "llvm/Support/CFG.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include <algorithm>
static RegisterPass<PrintModulePass>
X("printm", "Print module to stderr",PassInfo::Analysis|PassInfo::Optimization);
static RegisterPass<PrintFunctionPass>
Y("print","Print function to stderr",PassInfo::Analysis|PassInfo::Optimization);
static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
bool PrintName,
std::map<const Type *, std::string> &TypeTable,
SlotCalculator *Table);
static const Module *getModuleFromVal(const Value *V) {
if (const Argument *MA = dyn_cast<Argument>(V))
return MA->getParent() ? MA->getParent()->getParent() : 0;
else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
return BB->getParent() ? BB->getParent()->getParent() : 0;
else if (const Instruction *I = dyn_cast<Instruction>(V)) {
const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
return M ? M->getParent() : 0;
} else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return GV->getParent();
return 0;
}
static SlotCalculator *createSlotCalculator(const Value *V) {
assert(!isa<Type>(V) && "Can't create an SC for a type!");
if (const Argument *FA = dyn_cast<Argument>(V)) {
return new SlotCalculator(FA->getParent(), true);
} else if (const Instruction *I = dyn_cast<Instruction>(V)) {
return new SlotCalculator(I->getParent()->getParent(), true);
} else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
return new SlotCalculator(BB->getParent(), true);
} else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
return new SlotCalculator(GV->getParent(), true);
} else if (const Function *Func = dyn_cast<Function>(V)) {
return new SlotCalculator(Func, true);
}
return 0;
}
// If the module has a symbol table, take all global types and stuff their
// names into the TypeNames map.
//
static void fillTypeNameTable(const Module *M,
std::map<const Type *, std::string> &TypeNames) {
if (!M) return;
const SymbolTable &ST = M->getSymbolTable();
SymbolTable::const_iterator PI = ST.find(Type::TypeTy);
if (PI != ST.end()) {
SymbolTable::type_const_iterator I = PI->second.begin();
for (; I != PI->second.end(); ++I) {
// As a heuristic, don't insert pointer to primitive types, because
// they are used too often to have a single useful name.
//
const Type *Ty = cast<Type>(I->second);
if (!isa<PointerType>(Ty) ||
!cast<PointerType>(Ty)->getElementType()->isPrimitiveType())
TypeNames.insert(std::make_pair(Ty, "%"+I->first));
}
}
}
static std::string calcTypeName(const Type