#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/InlineAsm.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
-#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
#include <algorithm>
using namespace llvm;
}
}
+// PrintEscapedString - Print each character of the specified string, escaping
+// it if it is not printable or if it is an escape char.
+static void PrintEscapedString(const std::string &Str, std::ostream &Out) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ unsigned char C = Str[i];
+ if (isprint(C) && C != '"' && C != '\\') {
+ Out << C;
+ } else {
+ Out << '\\'
+ << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
+ << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+ }
+ }
+}
+
/// @brief Internal constant writer.
static void WriteConstantInt(std::ostream &Out, const Constant *CV,
bool PrintName,
std::map<const Type *, std::string> &TypeTable,
SlotMachine *Machine) {
+ const int IndentSize = 4;
+ static std::string Indent = "\n";
if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
Out << (CB == ConstantBool::True ? "true" : "false");
} else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) {
// Otherwise we could not reparse it to exactly the same value, so we must
// output the string in hexadecimal format!
- //
- // Behave nicely in the face of C TBAA rules... see:
- // http://www.nullstone.com/htmls/category/aliastyp.htm
- //
- union {
- double D;
- uint64_t U;
- } V;
- V.D = CFP->getValue();
assert(sizeof(double) == sizeof(uint64_t) &&
"assuming that double is 64 bits!");
- Out << "0x" << utohexstr(V.U);
+ Out << "0x" << utohexstr(DoubleToBits(CFP->getValue()));
} else if (isa<ConstantAggregateZero>(CV)) {
Out << "zeroinitializer";
// ubytes or an array of sbytes with positive values.
//
const Type *ETy = CA->getType()->getElementType();
- bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
-
- if (ETy == Type::SByteTy)
- for (unsigned i = 0; i < CA->getNumOperands(); ++i)
- if (cast<ConstantSInt>(CA->getOperand(i))->getValue() < 0) {
- isString = false;
- break;
- }
-
- if (isString) {
+ if (CA->isString()) {
Out << "c\"";
- for (unsigned i = 0; i < CA->getNumOperands(); ++i) {
- unsigned char C =
- (unsigned char)cast<ConstantInt>(CA->getOperand(i))->getRawValue();
-
- if (isprint(C) && C != '"' && C != '\\') {
- Out << C;
- } else {
- Out << '\\'
- << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
- << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
- }
- }
+ PrintEscapedString(CA->getAsString(), Out);
Out << "\"";
} else { // Cannot output in string format...
}
} else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
Out << '{';
- if (CS->getNumOperands()) {
- Out << ' ';
+ unsigned N = CS->getNumOperands();
+ if (N) {
+ if (N > 2) {
+ Indent += std::string(IndentSize, ' ');
+ Out << Indent;
+ } else {
+ Out << ' ';
+ }
printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable);
WriteAsOperandInternal(Out, CS->getOperand(0),
PrintName, TypeTable, Machine);
- for (unsigned i = 1; i < CS->getNumOperands(); i++) {
+ for (unsigned i = 1; i < N; i++) {
Out << ", ";
+ if (N > 2) Out << Indent;
printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable);
WriteAsOperandInternal(Out, CS->getOperand(i),
PrintName, TypeTable, Machine);
}
+ if (N > 2) Indent.resize(Indent.size() - IndentSize);
}
-
+
Out << " }";
} else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
const Type *ETy = CP->getType()->getElementType();
Out << getLLVMName(V->getName());
else {
const Constant *CV = dyn_cast<Constant>(V);
- if (CV && !isa<GlobalValue>(CV))
+ if (CV && !isa<GlobalValue>(CV)) {
WriteConstantInt(Out, CV, PrintName, TypeTable, Machine);
- else {
+ } else if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+ Out << "asm ";
+ if (IA->hasSideEffects())
+ Out << "sideeffect ";
+ Out << '"';
+ PrintEscapedString(IA->getAsmString(), Out);
+ Out << "\", \"";
+ PrintEscapedString(IA->getConstraintString(), Out);
+ Out << '"';
+ } else {
int Slot;
if (Machine) {
Slot = Machine->getSlot(V);
if (!M->getTargetTriple().empty())
Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
+ if (!M->getModuleInlineAsm().empty()) {
+ // Split the string into lines, to make it easier to read the .ll file.
+ std::string Asm = M->getModuleInlineAsm();
+ size_t CurPos = 0;
+ size_t NewLine = Asm.find_first_of('\n', CurPos);
+ while (NewLine != std::string::npos) {
+ // We found a newline, print the portion of the asm string from the
+ // last newline up to this newline.
+ Out << "module asm \"";
+ PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.begin()+NewLine),
+ Out);
+ Out << "\"\n";
+ CurPos = NewLine+1;
+ NewLine = Asm.find_first_of('\n', CurPos);
+ }
+ Out << "module asm \"";
+ PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out);
+ Out << "\"\n";
+ }
+
// Loop over the dependent libraries and emit them.
Module::lib_iterator LI = M->lib_begin();
Module::lib_iterator LE = M->lib_end();
assert(C && "GlobalVar initializer isn't constant?");
writeOperand(GV->getInitializer(), false, isa<GlobalValue>(C));
}
-
+
+ if (GV->hasSection())
+ Out << ", section \"" << GV->getSection() << '"';
+ if (GV->getAlignment())
+ Out << ", align " << GV->getAlignment();
+
printInfoComment(*GV);
Out << "\n";
}
}
Out << ')';
+ if (F->hasSection())
+ Out << " section \"" << F->getSection() << '"';
+ if (F->getAlignment())
+ Out << " align " << F->getAlignment();
+
if (F->isExternal()) {
Out << "\n";
} else {
Out << ',';
writeOperand(AI->getArraySize(), true);
}
+ if (AI->getAlignment()) {
+ Out << ", align " << AI->getAlignment();
+ }
} else if (isa<CastInst>(I)) {
if (Operand) writeOperand(Operand, true); // Work with broken code
Out << " to ";
if (Operand) writeOperand(Operand, true); // Work with broken code
Out << ", ";
printType(I.getType());
- } else if (const VANextInst *VAN = dyn_cast<VANextInst>(&I)) {
- if (Operand) writeOperand(Operand, true); // Work with broken code
- Out << ", ";
- printType(VAN->getArgType());
} else if (Operand) { // Print the normal way...
// PrintAllTypes - Instructions who have operands of all the same type
W.write(this);
}
+void InlineAsm::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
+ WriteAsOperand(o, this, true, true, 0);
+}
+
void BasicBlock::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
SlotMachine SlotTable(getParent());
AssemblyWriter W(o, SlotTable,
if (this == 0) { o << "<null> constant value\n"; return; }
o << ' ' << getType()->getDescription() << ' ';
-
- std::map<const Type *, std::string> TypeTable;
- WriteConstantInt(o, this, false, TypeTable, 0);
}
void Type::print(std::ostream &o) const {