forked from OSchip/llvm-project
450 lines
15 KiB
C++
450 lines
15 KiB
C++
//===--- 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);
|
|
|
|
|
|
void addSpecialAttribute(const char* pName, StringLiteral* Str) {
|
|
Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
|
|
}
|
|
|
|
void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S) {
|
|
if (S->isArgumentType())
|
|
Doc.addAttribute(pName, S->getArgumentType());
|
|
}
|
|
|
|
void addSpecialAttribute(const char* pName, CXXTypeidExpr* S) {
|
|
if (S->isTypeOperand())
|
|
Doc.addAttribute(pName, S->getTypeOperand());
|
|
}
|
|
|
|
|
|
public:
|
|
StmtXML(DocumentXML& doc)
|
|
: Doc(doc) {
|
|
}
|
|
|
|
void DumpSubTree(Stmt *S) {
|
|
if (S) {
|
|
Visit(S);
|
|
if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
|
|
for (DeclStmt::decl_iterator DI = DS->decl_begin(),
|
|
DE = DS->decl_end(); DI != DE; ++DI) {
|
|
Doc.PrintDecl(*DI);
|
|
}
|
|
} else {
|
|
for (Stmt::child_iterator i = S->child_begin(), e = S->child_end();
|
|
i != e; ++i)
|
|
DumpSubTree(*i);
|
|
}
|
|
Doc.toParent();
|
|
} else {
|
|
Doc.addSubNode("NULL").toParent();
|
|
}
|
|
}
|
|
|
|
|
|
#define NODE_XML( CLASS, NAME ) \
|
|
void Visit##CLASS(CLASS* S) \
|
|
{ \
|
|
typedef CLASS tStmtType; \
|
|
Doc.addSubNode(NAME);
|
|
|
|
#define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, S->FN);
|
|
#define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
|
|
#define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, S->FN);
|
|
#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S);
|
|
#define ATTRIBUTE_FILE_LOCATION_XML Doc.addLocationRange(S->getSourceRange());
|
|
|
|
|
|
#define ATTRIBUTE_ENUM_XML( FN, NAME ) \
|
|
{ \
|
|
const char* pAttributeName = NAME; \
|
|
const bool optional = false; \
|
|
switch (S->FN) { \
|
|
default: assert(0 && "unknown enum value");
|
|
|
|
#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
|
|
{ \
|
|
const char* pAttributeName = NAME; \
|
|
const bool optional = true; \
|
|
switch (S->FN) { \
|
|
default: assert(0 && "unknown enum value");
|
|
|
|
#define ENUM_XML( VALUE, NAME ) case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
|
|
#define END_ENUM_XML } }
|
|
#define END_NODE_XML }
|
|
|
|
#define ID_ATTRIBUTE_XML Doc.addAttribute("id", S);
|
|
#define SUB_NODE_XML( CLASS )
|
|
#define SUB_NODE_SEQUENCE_XML( CLASS )
|
|
#define SUB_NODE_OPT_XML( CLASS )
|
|
|
|
#include "clang/Frontend/StmtXML.def"
|
|
|
|
#if (0)
|
|
// 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 VisitObjCImplicitSetterGetterRefExpr(
|
|
ObjCImplicitSetterGetterRefExpr *Node);
|
|
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
|
|
void VisitObjCSuperExpr(ObjCSuperExpr *Node);
|
|
#endif
|
|
};
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Stmt printing methods.
|
|
//===----------------------------------------------------------------------===//
|
|
#if (0)
|
|
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::VisitObjCImplicitSetterGetterRefExpr(
|
|
ObjCImplicitSetterGetterRefExpr *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");
|
|
}
|
|
#endif
|
|
//===----------------------------------------------------------------------===//
|
|
// 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));
|
|
}
|
|
|