diff options
Diffstat (limited to 'lib/Frontend/StmtXML.cpp')
-rw-r--r-- | lib/Frontend/StmtXML.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/lib/Frontend/StmtXML.cpp b/lib/Frontend/StmtXML.cpp new file mode 100644 index 0000000..c861881 --- /dev/null +++ b/lib/Frontend/StmtXML.cpp @@ -0,0 +1,409 @@ +//===--- StmtXML.cpp - XML implementation for Stmt ASTs ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the Stmt::dumpXML methods, which dump out the +// AST to an XML document. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/DocumentXML.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclCXX.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/Support/Compiler.h" +using namespace clang; + +//===----------------------------------------------------------------------===// +// StmtXML Visitor +//===----------------------------------------------------------------------===// + +namespace { + class VISIBILITY_HIDDEN StmtXML : public StmtVisitor<StmtXML> { + DocumentXML& Doc; + + static const char *getOpcodeStr(UnaryOperator::Opcode Op); + static const char *getOpcodeStr(BinaryOperator::Opcode Op); + + public: + StmtXML(DocumentXML& doc) + : Doc(doc) { + } + + void DumpSubTree(Stmt *S) { + if (S) + { + Doc.addSubNode(S->getStmtClassName()); + Doc.addLocationRange(S->getSourceRange()); + if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) { + VisitDeclStmt(DS); + } else { + Visit(S); + for (Stmt::child_iterator i = S->child_begin(), e = S->child_end(); i != e; ++i) + { + DumpSubTree(*i); + } + } + Doc.toParent(); + } else { + Doc.addSubNode("NULL").toParent(); + } + } + + void DumpTypeExpr(const QualType& T) + { + Doc.addSubNode("TypeExpr"); + Doc.addTypeAttribute(T); + Doc.toParent(); + } + + void DumpExpr(const Expr *Node) { + Doc.addTypeAttribute(Node->getType()); + } + + // Stmts. + void VisitStmt(Stmt *Node); + void VisitDeclStmt(DeclStmt *Node); + void VisitLabelStmt(LabelStmt *Node); + void VisitGotoStmt(GotoStmt *Node); + + // Exprs + void VisitExpr(Expr *Node); + void VisitDeclRefExpr(DeclRefExpr *Node); + void VisitPredefinedExpr(PredefinedExpr *Node); + void VisitCharacterLiteral(CharacterLiteral *Node); + void VisitIntegerLiteral(IntegerLiteral *Node); + void VisitFloatingLiteral(FloatingLiteral *Node); + void VisitStringLiteral(StringLiteral *Str); + void VisitUnaryOperator(UnaryOperator *Node); + void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node); + void VisitMemberExpr(MemberExpr *Node); + void VisitExtVectorElementExpr(ExtVectorElementExpr *Node); + void VisitBinaryOperator(BinaryOperator *Node); + void VisitCompoundAssignOperator(CompoundAssignOperator *Node); + void VisitAddrLabelExpr(AddrLabelExpr *Node); + void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node); + + // C++ + void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); + void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node); + void VisitCXXThisExpr(CXXThisExpr *Node); + void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node); + + // ObjC + void VisitObjCEncodeExpr(ObjCEncodeExpr *Node); + void VisitObjCMessageExpr(ObjCMessageExpr* Node); + void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); + void VisitObjCProtocolExpr(ObjCProtocolExpr *Node); + void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node); + void VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node); + void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); + void VisitObjCSuperExpr(ObjCSuperExpr *Node); + }; +} + +//===----------------------------------------------------------------------===// +// Stmt printing methods. +//===----------------------------------------------------------------------===// + +void StmtXML::VisitStmt(Stmt *Node) +{ + // nothing special to do +} + +void StmtXML::VisitDeclStmt(DeclStmt *Node) +{ + for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end(); + DI != DE; ++DI) + { + Doc.PrintDecl(*DI); + } +} + +void StmtXML::VisitLabelStmt(LabelStmt *Node) +{ + Doc.addAttribute("name", Node->getName()); +} + +void StmtXML::VisitGotoStmt(GotoStmt *Node) +{ + Doc.addAttribute("name", Node->getLabel()->getName()); +} + +//===----------------------------------------------------------------------===// +// Expr printing methods. +//===----------------------------------------------------------------------===// + +void StmtXML::VisitExpr(Expr *Node) { + DumpExpr(Node); +} + +void StmtXML::VisitDeclRefExpr(DeclRefExpr *Node) { + DumpExpr(Node); + + const char* pKind; + switch (Node->getDecl()->getKind()) { + case Decl::Function: pKind = "FunctionDecl"; break; + case Decl::Var: pKind = "Var"; break; + case Decl::ParmVar: pKind = "ParmVar"; break; + case Decl::EnumConstant: pKind = "EnumConstant"; break; + case Decl::Typedef: pKind = "Typedef"; break; + case Decl::Record: pKind = "Record"; break; + case Decl::Enum: pKind = "Enum"; break; + case Decl::CXXRecord: pKind = "CXXRecord"; break; + case Decl::ObjCInterface: pKind = "ObjCInterface"; break; + case Decl::ObjCClass: pKind = "ObjCClass"; break; + default: pKind = "Decl"; break; + } + + Doc.addAttribute("kind", pKind); + Doc.addAttribute("name", Node->getDecl()->getNameAsString()); + Doc.addRefAttribute(Node->getDecl()); +} + +void StmtXML::VisitPredefinedExpr(PredefinedExpr *Node) { + DumpExpr(Node); + switch (Node->getIdentType()) { + default: assert(0 && "unknown case"); + case PredefinedExpr::Func: Doc.addAttribute("predefined", " __func__"); break; + case PredefinedExpr::Function: Doc.addAttribute("predefined", " __FUNCTION__"); break; + case PredefinedExpr::PrettyFunction: Doc.addAttribute("predefined", " __PRETTY_FUNCTION__");break; + } +} + +void StmtXML::VisitCharacterLiteral(CharacterLiteral *Node) { + DumpExpr(Node); + Doc.addAttribute("value", Node->getValue()); +} + +void StmtXML::VisitIntegerLiteral(IntegerLiteral *Node) { + DumpExpr(Node); + bool isSigned = Node->getType()->isSignedIntegerType(); + Doc.addAttribute("value", Node->getValue().toString(10, isSigned)); +} + +void StmtXML::VisitFloatingLiteral(FloatingLiteral *Node) { + DumpExpr(Node); + // FIXME: output float as written in source (no approximation or the like) + //Doc.addAttribute("value", Node->getValueAsApproximateDouble())); + Doc.addAttribute("value", "FIXME"); +} + +void StmtXML::VisitStringLiteral(StringLiteral *Str) { + DumpExpr(Str); + if (Str->isWide()) + Doc.addAttribute("is_wide", "1"); + + Doc.addAttribute("value", Doc.escapeString(Str->getStrData(), Str->getByteLength())); +} + + +const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op) { + switch (Op) { + default: assert(0 && "Unknown unary operator"); + case UnaryOperator::PostInc: return "postinc"; + case UnaryOperator::PostDec: return "postdec"; + case UnaryOperator::PreInc: return "preinc"; + case UnaryOperator::PreDec: return "predec"; + case UnaryOperator::AddrOf: return "addrof"; + case UnaryOperator::Deref: return "deref"; + case UnaryOperator::Plus: return "plus"; + case UnaryOperator::Minus: return "minus"; + case UnaryOperator::Not: return "not"; + case UnaryOperator::LNot: return "lnot"; + case UnaryOperator::Real: return "__real"; + case UnaryOperator::Imag: return "__imag"; + case UnaryOperator::Extension: return "__extension__"; + case UnaryOperator::OffsetOf: return "__builtin_offsetof"; + } +} + + +const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op) { + switch (Op) { + default: assert(0 && "Unknown binary operator"); + case BinaryOperator::PtrMemD: return "ptrmemd"; + case BinaryOperator::PtrMemI: return "ptrmemi"; + case BinaryOperator::Mul: return "mul"; + case BinaryOperator::Div: return "div"; + case BinaryOperator::Rem: return "rem"; + case BinaryOperator::Add: return "add"; + case BinaryOperator::Sub: return "sub"; + case BinaryOperator::Shl: return "shl"; + case BinaryOperator::Shr: return "shr"; + case BinaryOperator::LT: return "lt"; + case BinaryOperator::GT: return "gt"; + case BinaryOperator::LE: return "le"; + case BinaryOperator::GE: return "ge"; + case BinaryOperator::EQ: return "eq"; + case BinaryOperator::NE: return "ne"; + case BinaryOperator::And: return "and"; + case BinaryOperator::Xor: return "xor"; + case BinaryOperator::Or: return "or"; + case BinaryOperator::LAnd: return "land"; + case BinaryOperator::LOr: return "lor"; + case BinaryOperator::Assign: return "assign"; + case BinaryOperator::MulAssign: return "mulassign"; + case BinaryOperator::DivAssign: return "divassign"; + case BinaryOperator::RemAssign: return "remassign"; + case BinaryOperator::AddAssign: return "addassign"; + case BinaryOperator::SubAssign: return "subassign"; + case BinaryOperator::ShlAssign: return "shlassign"; + case BinaryOperator::ShrAssign: return "shrassign"; + case BinaryOperator::AndAssign: return "andassign"; + case BinaryOperator::XorAssign: return "xorassign"; + case BinaryOperator::OrAssign: return "orassign"; + case BinaryOperator::Comma: return "comma"; + } +} + +void StmtXML::VisitUnaryOperator(UnaryOperator *Node) { + DumpExpr(Node); + Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode())); +} + +void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof"); + Doc.addAttribute("is_type", Node->isArgumentType() ? "1" : "0"); + if (Node->isArgumentType()) + { + DumpTypeExpr(Node->getArgumentType()); + } +} + +void StmtXML::VisitMemberExpr(MemberExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("is_deref", Node->isArrow() ? "1" : "0"); + Doc.addAttribute("name", Node->getMemberDecl()->getNameAsString()); + Doc.addRefAttribute(Node->getMemberDecl()); +} + +void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("name", Node->getAccessor().getName()); +} + +void StmtXML::VisitBinaryOperator(BinaryOperator *Node) { + DumpExpr(Node); + Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode())); +} + +void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { + VisitBinaryOperator(Node); +/* FIXME: is this needed in the AST? + DumpExpr(Node); + CurrentNode = CurrentNode->addSubNode("ComputeLHSTy"); + DumpType(Node->getComputationLHSType()); + CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy"); + DumpType(Node->getComputationResultType()); + Doc.toParent(); +*/ +} + +// GNU extensions. + +void StmtXML::VisitAddrLabelExpr(AddrLabelExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("name", Node->getLabel()->getName()); +} + +void StmtXML::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { + DumpExpr(Node); + DumpTypeExpr(Node->getArgType1()); + DumpTypeExpr(Node->getArgType2()); +} + +//===----------------------------------------------------------------------===// +// C++ Expressions +//===----------------------------------------------------------------------===// + +void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("kind", Node->getCastName()); + DumpTypeExpr(Node->getTypeAsWritten()); +} + +void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("value", Node->getValue() ? "true" : "false"); +} + +void StmtXML::VisitCXXThisExpr(CXXThisExpr *Node) { + DumpExpr(Node); +} + +void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { + DumpExpr(Node); + DumpTypeExpr(Node->getTypeAsWritten()); +} + +//===----------------------------------------------------------------------===// +// Obj-C Expressions +//===----------------------------------------------------------------------===// + +void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr* Node) { + DumpExpr(Node); + Doc.addAttribute("selector", Node->getSelector().getAsString()); + IdentifierInfo* clsName = Node->getClassName(); + if (clsName) + Doc.addAttribute("class", clsName->getName()); +} + +void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { + DumpExpr(Node); + DumpTypeExpr(Node->getEncodedType()); +} + +void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("selector", Node->getSelector().getAsString()); +} + +void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("protocol", Node->getProtocol()->getNameAsString()); +} + +void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("property", Node->getProperty()->getNameAsString()); +} + +void StmtXML::VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node) { + DumpExpr(Node); + ObjCMethodDecl *Getter = Node->getGetterMethod(); + ObjCMethodDecl *Setter = Node->getSetterMethod(); + Doc.addAttribute("Getter", Getter->getSelector().getAsString()); + Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)"); +} + +void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("super", "1"); +} + +void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { + DumpExpr(Node); + Doc.addAttribute("kind", Node->getDecl()->getDeclKindName()); + Doc.addAttribute("decl", Node->getDecl()->getNameAsString()); + if (Node->isFreeIvar()) + Doc.addAttribute("isFreeIvar", "1"); +} + +//===----------------------------------------------------------------------===// +// Stmt method implementations +//===----------------------------------------------------------------------===// + +/// dumpAll - This does a dump of the specified AST fragment and all subtrees. +void DocumentXML::PrintStmt(const Stmt *S) { + StmtXML P(*this); + P.DumpSubTree(const_cast<Stmt*>(S)); +} + |