blob: f5a493075bc8c4a1636be962a23d93ed3d0dc508 [file] [log] [blame]
//===-- AST XML Writer Implementation -----------------------*- C++ -*-===//
//
// High Level Virtual Machine (HLVM)
//
// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
//
// This software is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or (at
// your option) any later version.
//
// This software is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
// more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library in the file named LICENSE.txt; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301 USA
//
//===----------------------------------------------------------------------===//
/// @file hlvm/Writer/XMLWriter.cpp
/// @author Reid Spencer <rspencer@reidspencer.com>
/// @date 2006/05/12
/// @since 0.1.0
/// @brief Provides the interface to hlvm::XMLWriter
//===----------------------------------------------------------------------===//
#include <hlvm/Writer/XMLWriter.h>
#include <hlvm/AST/AST.h>
#include <hlvm/AST/Bundle.h>
#include <hlvm/AST/Documentation.h>
#include <hlvm/AST/ContainerType.h>
#include <hlvm/AST/Linkables.h>
#include <hlvm/AST/Constants.h>
#include <hlvm/AST/Block.h>
#include <hlvm/AST/ControlFlow.h>
#include <hlvm/AST/MemoryOps.h>
#include <hlvm/AST/InputOutput.h>
#include <hlvm/AST/Arithmetic.h>
#include <hlvm/AST/BooleanOps.h>
#include <hlvm/AST/RealMath.h>
#include <hlvm/AST/StringOps.h>
#include <hlvm/Base/Assert.h>
#include <hlvm/Pass/Pass.h>
#include <llvm/ADT/StringExtras.h>
#include <llvm/Support/Casting.h>
#include <libxml/xmlwriter.h>
#include <iostream>
using namespace hlvm;
using namespace llvm;
namespace {
class XMLWriterImpl : public XMLWriter {
public:
XMLWriterImpl(const char* fname) : pass(fname) { }
virtual ~XMLWriterImpl() { }
virtual void write(AST* node);
#ifdef HLVM_DEBUG
void writeNode(Node* node);
#endif
private:
class WriterPass : public Pass
{
public:
WriterPass(const char* fname) :
Pass(0,Pass::PreAndPostOrderTraversal), writer(0), buffer(0)
{
if (fname == 0) {
buffer = xmlOutputBufferCreateFd(2,0);
writer = xmlNewTextWriter(buffer);
} else {
writer = xmlNewTextWriterFilename(fname,0);
}
hlvmAssert(writer && "Can't allocate writer");
xmlTextWriterSetIndent(writer,1);
xmlTextWriterSetIndentString(writer,
reinterpret_cast<const xmlChar*>(" "));
}
~WriterPass() {
xmlFreeTextWriter(writer);
}
inline void writeComment(const char* cmt)
{ xmlTextWriterWriteComment(writer,
reinterpret_cast<const xmlChar*>(cmt)); }
inline void startElement(const char* elem)
{ xmlTextWriterStartElement(writer,
reinterpret_cast<const xmlChar*>(elem)); }
inline void endElement()
{ xmlTextWriterEndElement(writer); }
inline void writeAttribute(const char*name, const char*val)
{ xmlTextWriterWriteAttribute(writer,
reinterpret_cast<const xmlChar*>(name),
reinterpret_cast<const xmlChar*>(val)); }
inline void writeAttribute(const char* name, const std::string& val)
{ writeAttribute(name, val.c_str()); }
inline void writeAttribute(const char* name, const Type* t)
{ writeAttribute(name, t->getName()); }
inline void writeAttribute(const char* name, uint64_t val)
{ writeAttribute(name, llvm::utostr(val)); }
inline void writeAttribute(const char* name, int64_t val)
{ writeAttribute(name, llvm::itostr(val)); }
inline void writeElement(const char* elem, const char* body)
{ xmlTextWriterWriteElement(writer,
reinterpret_cast<const xmlChar*>(elem),
reinterpret_cast<const xmlChar*>(body)); }
inline void writeString(const std::string& str) ;
inline void putHeader(AST* ast);
inline void putFooter();
inline void putDoc(const Documentable* node);
void putConstantValue(const ConstantValue* CV,bool nested);
template<class NodeClass>
inline void put(const NodeClass* nc);
template<class NodeClass>
inline void put(const NodeClass* nc, bool nested);
virtual void handle(Node* n,Pass::TraversalKinds mode);
private:
xmlTextWriterPtr writer;
xmlOutputBufferPtr buffer;
friend class XMLWriterImpl;
};
private:
WriterPass pass;
};
inline const char*
getLinkageKind(LinkageKinds lk)
{
switch (lk) {
case WeakLinkage: return "weak";
case ExternalLinkage: return "external";
case InternalLinkage: return "internal";
case LinkOnceLinkage: return "linkonce";
case AppendingLinkage: return "appending";
default:
hlvmDeadCode("Bad LinkageKinds");
break;
}
return "error";
}
void
XMLWriterImpl::WriterPass::writeString(const std::string& str)
{
const xmlChar* str_to_write = // xmlEncodeSpecialChars(
reinterpret_cast<const xmlChar*>(str.c_str()); // );
xmlTextWriterWriteString(writer, str_to_write);
// xmlMemFree(str_to_write);
}
void
XMLWriterImpl::WriterPass::putHeader(AST* ast)
{
xmlTextWriterStartDocument(writer,0,"UTF-8",0);
startElement("hlvm");
writeAttribute("xmlns","http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng");
writeAttribute("pubid",ast->getPublicID());
}
void
XMLWriterImpl::WriterPass::putFooter()
{
endElement();
xmlTextWriterEndDocument(writer);
}
template<> void
XMLWriterImpl::WriterPass::put(const Documentation* b)
{
startElement("doc");
const std::string& data = b->getDoc();
xmlTextWriterWriteRawLen(writer,
reinterpret_cast<const xmlChar*>(data.c_str()),data.length());
endElement();
}
inline void
XMLWriterImpl::WriterPass::putDoc(const Documentable* node)
{
Documentation* theDoc = node->getDoc();
if (theDoc) {
this->put<Documentation>(theDoc);
}
}
template<> void
XMLWriterImpl::WriterPass::put(const NamedType* t)
{
startElement("alias");
writeAttribute("id",t->getName());
writeAttribute("is",t->getType()->getName());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const AnyType* t)
{
if (t->isIntrinsic())
return;
startElement("any");
writeAttribute("id",t->getName());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const StringType* t)
{
if (t->isIntrinsic())
return;
startElement("string");
writeAttribute("id",t->getName());
writeAttribute("encoding",t->getEncoding());
putDoc(t);
endElement();
}
template<>void
XMLWriterImpl::WriterPass::put(const BooleanType* t)
{
if (t->isIntrinsic())
return;
startElement("boolean");
writeAttribute("id",t->getName());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const CharacterType* t)
{
if (t->isIntrinsic())
return;
startElement("character");
writeAttribute("id",t->getName());
writeAttribute("encoding",t->getEncoding());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const IntegerType* t)
{
if (t->isIntrinsic())
return;
if (t->isSigned()) {
startElement("signed");
writeAttribute("id",t->getName());
writeAttribute("bits", llvm::utostr(t->getBits()));
} else {
startElement("unsigned");
writeAttribute("id",t->getName());
writeAttribute("bits", llvm::utostr(t->getBits()));
}
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const RangeType* t)
{
if (t->isIntrinsic())
return;
startElement("range");
writeAttribute("id",t->getName());
writeAttribute("min",t->getMin());
writeAttribute("max",t->getMax());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const EnumerationType* t)
{
if (t->isIntrinsic())
return;
startElement("enumeration");
writeAttribute("id",t->getName());
putDoc(t);
for (EnumerationType::const_iterator I = t->begin(), E = t->end();
I != E; ++I)
{
startElement("enumerator");
writeAttribute("id",*I);
endElement();
}
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const RealType* t)
{
if (t->isIntrinsic())
return;
startElement("real");
writeAttribute("id",t->getName());
writeAttribute("mantissa", llvm::utostr(t->getMantissa()));
writeAttribute("exponent", llvm::utostr(t->getExponent()));
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const RationalType* t)
{
if (t->isIntrinsic())
return;
startElement("rational");
writeAttribute("id",t->getName());
writeAttribute("numerator", llvm::utostr(t->getNumeratorBits()));
writeAttribute("denominator", llvm::utostr(t->getDenominatorBits()));
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const OpaqueType* op)
{
if (op->isIntrinsic())
return;
startElement("opaque");
writeAttribute("id",op->getName());
putDoc(op);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const PointerType* t)
{
if (t->isIntrinsic())
return;
startElement("pointer");
writeAttribute("id", t->getName());
writeAttribute("to", t->getElementType());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ArrayType* t)
{
if (t->isIntrinsic())
return;
startElement("array");
writeAttribute("id", t->getName());
writeAttribute("of", t->getElementType());
writeAttribute("length", t->getMaxSize());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const VectorType* t)
{
if (t->isIntrinsic())
return;
startElement("vector");
writeAttribute("id", t->getName());
writeAttribute("of", t->getElementType());
writeAttribute("length", t->getSize());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const StructureType* t)
{
if (t->isIntrinsic())
return;
startElement("structure");
writeAttribute("id",t->getName());
putDoc(t);
for (StructureType::const_iterator I = t->begin(), E = t->end();
I != E; ++I) {
startElement("field");
Field* field = cast<Field>(*I);
writeAttribute("id",field->getName());
writeAttribute("type",field->getType());
putDoc(field);
endElement();
}
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ContinuationType* t)
{
if (t->isIntrinsic())
return;
startElement("continuation");
writeAttribute("id",t->getName());
putDoc(t);
for (ContinuationType::const_iterator I = t->begin(), E = t->end();
I != E; ++I) {
startElement("field");
Field* field = cast<Field>(*I);
writeAttribute("id",field->getName());
writeAttribute("type",field->getType());
putDoc(field);
endElement();
}
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const SignatureType* t)
{
if (t->isIntrinsic())
return;
startElement("signature");
writeAttribute("id",t->getName());
writeAttribute("result",t->getResultType());
if (t->isVarArgs())
writeAttribute("varargs","true");
putDoc(t);
for (SignatureType::const_iterator I = t->begin(), E = t->end(); I != E; ++I)
{
startElement("arg");
Parameter* param = cast<Parameter>(*I);
writeAttribute("id",param->getName());
writeAttribute("type",param->getType());
putDoc(param);
endElement();
}
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const StreamType* t)
{
if (t->isIntrinsic())
return;
startElement("stream");
writeAttribute("id",t->getName());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const TextType* t)
{
if (t->isIntrinsic())
return;
startElement("text");
writeAttribute("id",t->getName());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const BufferType* t)
{
if (t->isIntrinsic())
return;
startElement("buffer");
writeAttribute("id",t->getName());
putDoc(t);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put<ConstantAny>(const ConstantAny* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
putConstantValue(i->getValue(),true);
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantBoolean* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
if (i->getValue())
startElement("true");
else
startElement("false");
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantCharacter* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("char");
writeString(i->getValue());
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantEnumerator* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("enum");
writeString(i->getValue());
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantInteger* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
switch (i->getBase()) {
case 2: startElement("bin"); break;
case 8: startElement("oct"); break;
case 16: startElement("hex"); break;
default: startElement("dec"); break;
}
writeString(i->getValue());
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantReal* r, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",r->getName());
writeAttribute("type",r->getType()->getName());
putDoc(r);
}
const RealType* RT = cast<RealType>(r->getType());
if (RT->getBits() <= 32)
startElement("flt");
else
startElement("dbl");
writeString(r->getValue());
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantString* t, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",t->getName());
writeAttribute("type",t->getType()->getName());
putDoc(t);
}
startElement("str");
writeString(t->getValue());
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantPointer* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("ptr");
writeAttribute("to",i->getValue()->getName());
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantArray* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("arr");
for (ConstantArray::const_iterator I = i->begin(), E = i->end(); I != E; ++I)
putConstantValue(*I,true);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantVector* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("vect");
for (ConstantArray::const_iterator I = i->begin(), E = i->end(); I != E; ++I)
putConstantValue(*I,true);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantStructure* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("struct");
for (ConstantStructure::const_iterator I = i->begin(), E = i->end();
I != E; ++I)
putConstantValue(*I,true);
endElement();
}
template<> void
XMLWriterImpl::WriterPass::put(const ConstantContinuation* i, bool nested)
{
if (!nested) {
startElement("constant");
writeAttribute("id",i->getName());
writeAttribute("type",i->getType()->getName());
putDoc(i);
}
startElement("cont");
for (ConstantContinuation::const_iterator I = i->begin(), E = i->end();
I != E; ++I)
putConstantValue(*I,true);
endElement();
}
inline void
XMLWriterImpl::WriterPass::putConstantValue(const ConstantValue* V, bool nstd)
{
switch (V->getID()) {
case ConstantAnyID: put(cast<ConstantAny>(V),nstd); break;
case ConstantBooleanID: put(cast<ConstantBoolean>(V),nstd); break;
case ConstantCharacterID: put(cast<ConstantCharacter>(V),nstd); break;
case ConstantEnumeratorID: put(cast<ConstantEnumerator>(V),nstd); break;
case ConstantIntegerID: put(cast<ConstantInteger>(V),nstd); break;
case ConstantRealID: put(cast<ConstantReal>(V),nstd); break;
case ConstantStringID: put(cast<ConstantString>(V),nstd); break;
case ConstantPointerID: put(cast<ConstantPointer>(V),nstd); break;
case ConstantArrayID: put(cast<ConstantArray>(V),nstd); break;
case ConstantVectorID: put(cast<ConstantVector>(V),nstd); break;
case ConstantStructureID: put(cast<ConstantStructure>(V),nstd); break;
case ConstantContinuationID: put(cast<ConstantContinuation>(V),nstd); break;
default:
hlvmAssert(!"Invalid ConstantValue kind");
}
}
template<> void
XMLWriterImpl::WriterPass::put(const Variable* v)
{
startElement("variable");
writeAttribute("id",v->getName());
writeAttribute("type",v->getType()->getName());
if (v->hasInitializer()) {
Constant* C = llvm::cast<Constant>(v->getInitializer());
writeAttribute("init",C->getName());
}
putDoc(v);
}
template<> void
XMLWriterImpl::WriterPass::put(const Function* f)
{
startElement("function");
writeAttribute("id",f->getName());
writeAttribute("type",f->getSignature()->getName());
writeAttribute("linkage",getLinkageKind(f->getLinkageKind()));
putDoc(f);
}
template<> void
XMLWriterImpl::WriterPass::put(const Program* p)
{
startElement("program");
writeAttribute("id",p->getName());
putDoc(p);
}
template<> void
XMLWriterImpl::WriterPass::put(const Block* b)
{
startElement("block");
if (!b->getLabel().empty())
writeAttribute("label",b->getLabel());
putDoc(b);
}
template<> void
XMLWriterImpl::WriterPass::put(const AutoVarOp* av)
{
startElement("autovar");
writeAttribute("id",av->getName());
writeAttribute("type",av->getType()->getName());
putDoc(av);
}
template<> void
XMLWriterImpl::WriterPass::put(const NegateOp* op)
{
startElement("neg");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const ComplementOp* op)
{
startElement("cmpl");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const PreIncrOp* op)
{
startElement("preinc");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const PreDecrOp* op)
{
startElement("predec");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const PostIncrOp* op)
{
startElement("postinc");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const PostDecrOp* op)
{
startElement("postdec");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const AddOp* op)
{
startElement("add");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const SubtractOp* op)
{
startElement("sub");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const MultiplyOp* op)
{
startElement("mul");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const DivideOp* op)
{
startElement("div");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const ModuloOp* op)
{
startElement("mod");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const BAndOp* op)
{
startElement("band");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const BOrOp* op)
{
startElement("bor");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const BXorOp* op)
{
startElement("bxor");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const BNorOp* op)
{
startElement("bnor");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const NotOp* op)
{
startElement("not");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const AndOp* op)
{
startElement("and");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const OrOp* op)
{
startElement("or");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const XorOp* op)
{
startElement("xor");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const NorOp* op)
{
startElement("nor");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const EqualityOp* op)
{
startElement("eq");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const InequalityOp* op)
{
startElement("ne");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const LessThanOp* op)
{
startElement("lt");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const GreaterThanOp* op)
{
startElement("gt");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const LessEqualOp* op)
{
startElement("le");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const GreaterEqualOp* op)
{
startElement("ge");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const IsPInfOp* op)
{
startElement("ispinf");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const IsNInfOp* op)
{
startElement("isninf");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const IsNanOp* op)
{
startElement("isnan");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const TruncOp* op)
{
startElement("trunc");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const RoundOp* op)
{
startElement("round");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const FloorOp* op)
{
startElement("floor");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const CeilingOp* op)
{
startElement("ceiling");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const LogEOp* op)
{
startElement("loge");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const Log2Op* op)
{
startElement("log2");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const Log10Op* op)
{
startElement("log10");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const SquareRootOp* op)
{
startElement("squareroot");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const CubeRootOp* op)
{
startElement("cuberoot");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const FactorialOp* op)
{
startElement("factorial");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const PowerOp* op)
{
startElement("power");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const RootOp* op)
{
startElement("root");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const GCDOp* op)
{
startElement("GCD");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const LCMOp* op)
{
startElement("LCM");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const SelectOp* op)
{
startElement("select");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const SwitchOp* op)
{
startElement("switch");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const WhileOp* op)
{
startElement("while");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const UnlessOp* op)
{
startElement("unless");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const UntilOp* op)
{
startElement("until");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const LoopOp* op)
{
startElement("loop");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const BreakOp* op)
{
startElement("break");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const ContinueOp* op)
{
startElement("continue");
putDoc(op);
}
template<> void
XMLWriterImpl::WriterPass::put(const ReturnOp* r)
{
startElement("ret");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const ResultOp* r)
{
startElement("result");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const CallOp* r)
{
startElement("call");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const StoreOp* r)
{
startElement("store");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const GetFieldOp* r)
{
startElement("getfld");
writeAttribute("field",r->getFieldName());
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const GetIndexOp* r)
{
startElement("getidx");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const LoadOp* r)
{
startElement("load");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const GetOp* r)
{
startElement("get");
const Documentable* ref = r->getReferent();
std::string name;
if (isa<AutoVarOp>(ref))
name = cast<AutoVarOp>(ref)->getName();
else if (isa<Argument>(ref))
name = cast<Argument>(ref)->getName();
else if (isa<Constant>(ref))
name = cast<Constant>(ref)->getName();
else if (isa<Type>(ref))
name = cast<Type>(ref)->getName();
else
name = "oops";
writeAttribute("id",name);
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const OpenOp* r)
{
startElement("open");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const WriteOp* r)
{
startElement("write");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const CloseOp* r)
{
startElement("close");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const ConvertOp* r)
{
startElement("convert");
writeAttribute("type",r->getType()->getName());
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const StrInsertOp* r)
{
startElement("sinsert");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const StrEraseOp* r)
{
startElement("serase");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const StrReplaceOp* r)
{
startElement("sreplace");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const StrConcatOp* r)
{
startElement("sconcat");
putDoc(r);
}
template<> void
XMLWriterImpl::WriterPass::put(const Bundle* b)
{
startElement("bundle");
writeAttribute("id",b->getName());
putDoc(b);
}
void
XMLWriterImpl::WriterPass::handle(Node* n,Pass::TraversalKinds mode)
{
if (mode & Pass::PreOrderTraversal) {
switch (n->getID())
{
case BundleID: put(cast<Bundle>(n)); break;
/* TYPES */
case AnyTypeID: put(cast<AnyType>(n)); break;
case ArrayTypeID: put(cast<ArrayType>(n)); break;
case BooleanTypeID: put(cast<BooleanType>(n)); break;
case BufferTypeID: put(cast<BufferType>(n)); break;
case CharacterTypeID: put(cast<CharacterType>(n)); break;
case ContinuationTypeID: put(cast<ContinuationType>(n)); break;
case EnumerationTypeID: put(cast<EnumerationType>(n)); break;
case IntegerTypeID: put(cast<IntegerType>(n)); break;
case NamedTypeID: put(cast<NamedType>(n)); break;
case OpaqueTypeID: put(cast<OpaqueType>(n)); break;
case PointerTypeID: put(cast<PointerType>(n)); break;
case RangeTypeID: put(cast<RangeType>(n)); break;
case RealTypeID: put(cast<RealType>(n)); break;
case RationalTypeID: put(cast<RationalType>(n)); break;
case SignatureTypeID: put(cast<SignatureType>(n)); break;
case StreamTypeID: put(cast<StreamType>(n)); break;
case StringTypeID: put(cast<StringType>(n)); break;
case StructureTypeID: put(cast<StructureType>(n)); break;
case TextTypeID: put(cast<TextType>(n)); break;
case VectorTypeID: put(cast<VectorType>(n)); break;
/* CONSTANTS */
case ConstantAnyID:
case ConstantBooleanID:
case ConstantCharacterID:
case ConstantEnumeratorID:
case ConstantIntegerID:
case ConstantRealID:
case ConstantStringID:
case ConstantPointerID:
case ConstantArrayID:
case ConstantVectorID:
case ConstantStructureID:
case ConstantContinuationID:
putConstantValue(cast<ConstantValue>(n),false); break;
/* LINKABLES */
case VariableID: put(cast<Variable>(n)); break;
case FunctionID: put(cast<Function>(n)); break;
case ProgramID: put(cast<Program>(n)); break;
case BlockID: put(cast<Block>(n)); break;
/* OPERATORS */
case AutoVarOpID: put(cast<AutoVarOp>(n)); break;
case NegateOpID: put(cast<NegateOp>(n)); break;
case ComplementOpID: put(cast<ComplementOp>(n)); break;
case PreIncrOpID: put(cast<PreIncrOp>(n)); break;
case PreDecrOpID: put(cast<PreDecrOp>(n)); break;
case PostIncrOpID: put(cast<PostIncrOp>(n)); break;
case PostDecrOpID: put(cast<PostDecrOp>(n)); break;
case AddOpID: put(cast<AddOp>(n)); break;
case SubtractOpID: put(cast<SubtractOp>(n)); break;
case MultiplyOpID: put(cast<MultiplyOp>(n)); break;
case DivideOpID: put(cast<DivideOp>(n)); break;
case ModuloOpID: put(cast<ModuloOp>(n)); break;
case BAndOpID: put(cast<BAndOp>(n)); break;
case BOrOpID: put(cast<BOrOp>(n)); break;
case BXorOpID: put(cast<BXorOp>(n)); break;
case BNorOpID: put(cast<BNorOp>(n)); break;
case NotOpID: put(cast<NotOp>(n)); break;
case AndOpID: put(cast<AndOp>(n)); break;
case OrOpID: put(cast<OrOp>(n)); break;
case XorOpID: put(cast<XorOp>(n)); break;
case NorOpID: put(cast<NorOp>(n)); break;
case EqualityOpID: put(cast<EqualityOp>(n)); break;
case InequalityOpID: put(cast<InequalityOp>(n)); break;
case LessThanOpID: put(cast<LessThanOp>(n)); break;
case GreaterThanOpID: put(cast<GreaterThanOp>(n)); break;
case LessEqualOpID: put(cast<LessEqualOp>(n)); break;
case GreaterEqualOpID: put(cast<GreaterEqualOp>(n)); break;
case SelectOpID: put(cast<SelectOp>(n)); break;
case SwitchOpID: put(cast<SwitchOp>(n)); break;
case WhileOpID: put(cast<WhileOp>(n)); break;
case UnlessOpID: put(cast<UnlessOp>(n)); break;
case UntilOpID: put(cast<UntilOp>(n)); break;
case LoopOpID: put(cast<LoopOp>(n)); break;
case BreakOpID: put(cast<BreakOp>(n)); break;
case ContinueOpID: put(cast<ContinueOp>(n)); break;
case ReturnOpID: put(cast<ReturnOp>(n)); break;
case ResultOpID: put(cast<ResultOp>(n)); break;
case CallOpID: put(cast<CallOp>(n)); break;
case StoreOpID: put(cast<StoreOp>(n)); break;
case GetFieldOpID: put(cast<GetFieldOp>(n)); break;
case GetIndexOpID: put(cast<GetIndexOp>(n)); break;
case LoadOpID: put(cast<LoadOp>(n)); break;
case GetOpID: put(cast<GetOp>(n)); break;
case OpenOpID: put(cast<OpenOp>(n)); break;
case CloseOpID: put(cast<CloseOp>(n)); break;
case WriteOpID: put(cast<WriteOp>(n)); break;
case ConvertOpID: put(cast<ConvertOp>(n)); break;
case StrInsertOpID: put(cast<StrInsertOp>(n)); break;
case StrEraseOpID: put(cast<StrEraseOp>(n)); break;
case StrReplaceOpID: put(cast<StrReplaceOp>(n)); break;
case StrConcatOpID: put(cast<StrConcatOp>(n)); break;
case IsPInfOpID: put(cast<IsPInfOp>(n)); break;
case IsNInfOpID: put(cast<IsNInfOp>(n)); break;
case IsNanOpID: put(cast<IsNanOp>(n)); break;
case TruncOpID: put(cast<TruncOp>(n)); break;
case RoundOpID: put(cast<RoundOp>(n)); break;
case FloorOpID: put(cast<FloorOp>(n)); break;
case CeilingOpID: put(cast<CeilingOp>(n)); break;
case LogEOpID: put(cast<LogEOp>(n)); break;
case Log2OpID: put(cast<Log2Op>(n)); break;
case Log10OpID: put(cast<Log10Op>(n)); break;
case SquareRootOpID: put(cast<SquareRootOp>(n)); break;
case CubeRootOpID: put(cast<CubeRootOp>(n)); break;
case FactorialOpID: put(cast<FactorialOp>(n)); break;
case PowerOpID: put(cast<PowerOp>(n)); break;
case RootOpID: put(cast<RootOp>(n)); break;
case GCDOpID: put(cast<GCDOp>(n)); break;
case LCMOpID: put(cast<LCMOp>(n)); break;
default:
hlvmDeadCode("Unknown Type");
break;
}
}
if (mode & Pass::PostOrderTraversal) {
// The types print their own end element because intrinsic types
// don't print at all so we can't assume a startElement.
switch (n->getID())
{
case AnyTypeID:
case ArrayTypeID:
case BooleanTypeID:
case BufferTypeID:
case CharacterTypeID:
case EnumerationTypeID:
case IntegerTypeID:
case NamedTypeID:
case OpaqueTypeID:
case PointerTypeID:
case RangeTypeID:
case RealTypeID:
case StringTypeID:
case StreamTypeID:
case StructureTypeID:
case SignatureTypeID:
case TextTypeID:
case VectorTypeID:
break;
default:
// For everything else, there was a startElement, so just end it now
endElement();
}
}
}
void
XMLWriterImpl::write(AST* ast)
{
pass.putHeader(ast);
PassManager* PM = PassManager::create();
PM->addPass(&pass);
PM->runOn(ast);
pass.putFooter();
}
#ifdef HLVM_DEBUG
void
XMLWriterImpl::writeNode(Node* node)
{
if (!node)
return;
PassManager* PM = PassManager::create();
PM->addPass(&pass);
PM->runOnNode(node);
}
#endif
}
namespace hlvm {
XMLWriter*
XMLWriter::create(const char* fname)
{
return new XMLWriterImpl(fname);
}
#ifdef HLVM_DEBUG
void
dump(Node* n)
{
XMLWriterImpl writer(0);
writer.writeNode(n);
}
#endif
}