zcov: / lib/Frontend/StmtXML.cpp


Files: 1 Branches Taken: 75.0% 9 / 12
Generated: 2010-02-10 01:31 Branches Executed: 83.3% 10 / 12
Line Coverage: 86.7% 26 / 30


Programs: 1 Runs 2897


       1                 : //===--- StmtXML.cpp - XML implementation for Stmt ASTs ------------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This file implements the Stmt::dumpXML methods, which dump out the
      11                 : // AST to an XML document.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #include "clang/Frontend/DocumentXML.h"
      16                 : #include "clang/AST/StmtVisitor.h"
      17                 : #include "clang/AST/DeclObjC.h"
      18                 : #include "clang/AST/DeclCXX.h"
      19                 : #include "clang/Basic/SourceManager.h"
      20                 : using namespace clang;
      21                 : 
      22                 : //===----------------------------------------------------------------------===//
      23                 : // StmtXML Visitor
      24                 : //===----------------------------------------------------------------------===//
      25                 : 
      26                 : namespace  {
      27                 :   class StmtXML : public StmtVisitor<StmtXML> {
      28                 :     DocumentXML&  Doc;
      29                 : 
      30                 :     //static const char *getOpcodeStr(UnaryOperator::Opcode Op);
      31                 :     //static const char *getOpcodeStr(BinaryOperator::Opcode Op);
      32                 : 
      33                 : 
      34                1:   void addSpecialAttribute(const char* pName, StringLiteral* Str) {
      35                1:     Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
      36                1:   }
      37                 : 
      38                1:   void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S) {
                        1: branch 1 taken
                        0: branch 2 not taken
      39                1:     if (S->isArgumentType())
      40                1:       Doc.addAttribute(pName, S->getArgumentType());
      41                1:   }
      42                 : 
      43                0:   void addSpecialAttribute(const char* pName, CXXTypeidExpr* S) {
                        0: branch 1 not taken
                        0: branch 2 not taken
      44                0:     if (S->isTypeOperand())
      45                0:       Doc.addAttribute(pName, S->getTypeOperand());
      46                0:   }
      47                 : 
      48                 : 
      49                 :   public:
      50               48:     StmtXML(DocumentXML& doc)
      51               48:       : Doc(doc) {
      52               48:     }
      53                 : 
      54              274:     void DumpSubTree(Stmt *S) {
                      270: branch 0 taken
                        4: branch 1 taken
      55              274:       if (S) {
      56              270:         Visit(S);
                       54: branch 1 taken
                      216: branch 2 taken
      57              270:         if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
                       65: branch 1 taken
                       54: branch 2 taken
      58              173:           for (DeclStmt::decl_iterator DI = DS->decl_begin(),
      59               54:                  DE = DS->decl_end(); DI != DE; ++DI) {
      60               65:             Doc.PrintDecl(*DI);
      61                 :           }
      62                 :         } else {
                      226: branch 4 taken
                      216: branch 5 taken
      63              442:           for (Stmt::child_iterator i = S->child_begin(), e = S->child_end();
      64                 :                i != e; ++i)
      65              226:             DumpSubTree(*i);
      66                 :         }
      67              270:         Doc.toParent();
      68                 :       } else {
      69                4:         Doc.addSubNode("NULL").toParent();
      70                 :       }
      71              274:     }
      72                 : 
      73                 : 
      74                 : #define NODE_XML( CLASS, NAME )          \
      75                 :   void Visit##CLASS(CLASS* S)            \
      76                 :   {                                      \
      77                 :     typedef CLASS tStmtType;             \
      78                 :     Doc.addSubNode(NAME);
      79                 : 
      80                 : #define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, S->FN);
      81                 : #define TYPE_ATTRIBUTE_XML( FN )          ATTRIBUTE_XML(FN, "type")
      82                 : #define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, S->FN);
      83                 : #define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S);
      84                 : #define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocationRange(S->getSourceRange());
      85                 : 
      86                 : 
      87                 : #define ATTRIBUTE_ENUM_XML( FN, NAME )  \
      88                 :   {                                     \
      89                 :     const char* pAttributeName = NAME;  \
      90                 :     const bool optional = false;        \
      91                 :     switch (S->FN) {                    \
      92                 :     default: assert(0 && "unknown enum value");
      93                 : 
      94                 : #define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
      95                 :   {                                         \
      96                 :     const char* pAttributeName = NAME;      \
      97                 :     const bool optional = true;             \
      98                 :     switch (S->FN) {                        \
      99                 :     default: assert(0 && "unknown enum value");
     100                 : 
     101                 : #define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
     102                 : #define END_ENUM_XML                    } }
     103                 : #define END_NODE_XML                    }
     104                 : 
     105                 : #define ID_ATTRIBUTE_XML                Doc.addAttribute("id", S);
     106                 : #define SUB_NODE_XML( CLASS )
     107                 : #define SUB_NODE_SEQUENCE_XML( CLASS )
     108                 : #define SUB_NODE_OPT_XML( CLASS )
     109                 : 
     110                 : #include "clang/Frontend/StmtXML.def"
     111                 : 
     112                 : #if (0)
     113                 :     // Stmts.
     114                 :     void VisitStmt(Stmt *Node);
     115                 :     void VisitDeclStmt(DeclStmt *Node);
     116                 :     void VisitLabelStmt(LabelStmt *Node);
     117                 :     void VisitGotoStmt(GotoStmt *Node);
     118                 : 
     119                 :     // Exprs
     120                 :     void VisitExpr(Expr *Node);
     121                 :     void VisitDeclRefExpr(DeclRefExpr *Node);
     122                 :     void VisitPredefinedExpr(PredefinedExpr *Node);
     123                 :     void VisitCharacterLiteral(CharacterLiteral *Node);
     124                 :     void VisitIntegerLiteral(IntegerLiteral *Node);
     125                 :     void VisitFloatingLiteral(FloatingLiteral *Node);
     126                 :     void VisitStringLiteral(StringLiteral *Str);
     127                 :     void VisitUnaryOperator(UnaryOperator *Node);
     128                 :     void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
     129                 :     void VisitMemberExpr(MemberExpr *Node);
     130                 :     void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
     131                 :     void VisitBinaryOperator(BinaryOperator *Node);
     132                 :     void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
     133                 :     void VisitAddrLabelExpr(AddrLabelExpr *Node);
     134                 :     void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
     135                 : 
     136                 :     // C++
     137                 :     void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
     138                 :     void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
     139                 :     void VisitCXXThisExpr(CXXThisExpr *Node);
     140                 :     void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
     141                 : 
     142                 :     // ObjC
     143                 :     void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
     144                 :     void VisitObjCMessageExpr(ObjCMessageExpr* Node);
     145                 :     void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
     146                 :     void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
     147                 :     void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
     148                 :     void VisitObjCImplicitSetterGetterRefExpr(
     149                 :                         ObjCImplicitSetterGetterRefExpr *Node);
     150                 :     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
     151                 :     void VisitObjCSuperExpr(ObjCSuperExpr *Node);
     152                 : #endif
     153                 :   };
     154                 : }
     155                 : 
     156                 : //===----------------------------------------------------------------------===//
     157                 : //  Stmt printing methods.
     158                 : //===----------------------------------------------------------------------===//
     159                 : #if (0)
     160                 : void StmtXML::VisitStmt(Stmt *Node) {
     161                 :   // nothing special to do
     162                 : }
     163                 : 
     164                 : void StmtXML::VisitDeclStmt(DeclStmt *Node) {
     165                 :   for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
     166                 :        DI != DE; ++DI) {
     167                 :     Doc.PrintDecl(*DI);
     168                 :   }
     169                 : }
     170                 : 
     171                 : void StmtXML::VisitLabelStmt(LabelStmt *Node) {
     172                 :   Doc.addAttribute("name", Node->getName());
     173                 : }
     174                 : 
     175                 : void StmtXML::VisitGotoStmt(GotoStmt *Node) {
     176                 :   Doc.addAttribute("name", Node->getLabel()->getName());
     177                 : }
     178                 : 
     179                 : //===----------------------------------------------------------------------===//
     180                 : //  Expr printing methods.
     181                 : //===----------------------------------------------------------------------===//
     182                 : 
     183                 : void StmtXML::VisitExpr(Expr *Node) {
     184                 :   DumpExpr(Node);
     185                 : }
     186                 : 
     187                 : void StmtXML::VisitDeclRefExpr(DeclRefExpr *Node) {
     188                 :   DumpExpr(Node);
     189                 : 
     190                 :   const char* pKind;
     191                 :   switch (Node->getDecl()->getKind()) {
     192                 :   case Decl::Function: pKind = "FunctionDecl"; break;
     193                 :   case Decl::Var: pKind = "Var"; break;
     194                 :   case Decl::ParmVar: pKind = "ParmVar"; break;
     195                 :   case Decl::EnumConstant: pKind = "EnumConstant"; break;
     196                 :   case Decl::Typedef: pKind = "Typedef"; break;
     197                 :   case Decl::Record: pKind = "Record"; break;
     198                 :   case Decl::Enum: pKind = "Enum"; break;
     199                 :   case Decl::CXXRecord: pKind = "CXXRecord"; break;
     200                 :   case Decl::ObjCInterface: pKind = "ObjCInterface"; break;
     201                 :   case Decl::ObjCClass: pKind = "ObjCClass"; break;
     202                 :   default: pKind = "Decl"; break;
     203                 :   }
     204                 : 
     205                 :   Doc.addAttribute("kind", pKind);
     206                 :   Doc.addAttribute("name", Node->getDecl()->getNameAsString());
     207                 :   Doc.addRefAttribute(Node->getDecl());
     208                 : }
     209                 : 
     210                 : void StmtXML::VisitPredefinedExpr(PredefinedExpr *Node) {
     211                 :   DumpExpr(Node);
     212                 :   switch (Node->getIdentType()) {
     213                 :   default: assert(0 && "unknown case");
     214                 :   case PredefinedExpr::Func:           Doc.addAttribute("predefined", " __func__"); break;
     215                 :   case PredefinedExpr::Function:       Doc.addAttribute("predefined", " __FUNCTION__"); break;
     216                 :   case PredefinedExpr::PrettyFunction: Doc.addAttribute("predefined", " __PRETTY_FUNCTION__");break;
     217                 :   }
     218                 : }
     219                 : 
     220                 : void StmtXML::VisitCharacterLiteral(CharacterLiteral *Node) {
     221                 :   DumpExpr(Node);
     222                 :   Doc.addAttribute("value", Node->getValue());
     223                 : }
     224                 : 
     225                 : void StmtXML::VisitIntegerLiteral(IntegerLiteral *Node) {
     226                 :   DumpExpr(Node);
     227                 :   bool isSigned = Node->getType()->isSignedIntegerType();
     228                 :   Doc.addAttribute("value", Node->getValue().toString(10, isSigned));
     229                 : }
     230                 : 
     231                 : void StmtXML::VisitFloatingLiteral(FloatingLiteral *Node) {
     232                 :   DumpExpr(Node);
     233                 :   // FIXME: output float as written in source (no approximation or the like)
     234                 :   //Doc.addAttribute("value", Node->getValueAsApproximateDouble()));
     235                 :   Doc.addAttribute("value", "FIXME");
     236                 : }
     237                 : 
     238                 : void StmtXML::VisitStringLiteral(StringLiteral *Str) {
     239                 :   DumpExpr(Str);
     240                 :   if (Str->isWide())
     241                 :     Doc.addAttribute("is_wide", "1");
     242                 : 
     243                 :   Doc.addAttribute("value", Doc.escapeString(Str->getStrData(), Str->getByteLength()));
     244                 : }
     245                 : 
     246                 : 
     247                 : const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op) {
     248                 :   switch (Op) {
     249                 :   default: assert(0 && "Unknown unary operator");
     250                 :   case UnaryOperator::PostInc: return "postinc";
     251                 :   case UnaryOperator::PostDec: return "postdec";
     252                 :   case UnaryOperator::PreInc:  return "preinc";
     253                 :   case UnaryOperator::PreDec:  return "predec";
     254                 :   case UnaryOperator::AddrOf:  return "addrof";
     255                 :   case UnaryOperator::Deref:   return "deref";
     256                 :   case UnaryOperator::Plus:    return "plus";
     257                 :   case UnaryOperator::Minus:   return "minus";
     258                 :   case UnaryOperator::Not:     return "not";
     259                 :   case UnaryOperator::LNot:    return "lnot";
     260                 :   case UnaryOperator::Real:    return "__real";
     261                 :   case UnaryOperator::Imag:    return "__imag";
     262                 :   case UnaryOperator::Extension: return "__extension__";
     263                 :   case UnaryOperator::OffsetOf: return "__builtin_offsetof";
     264                 :   }
     265                 : }
     266                 : 
     267                 : 
     268                 : const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op) {
     269                 :   switch (Op) {
     270                 :   default: assert(0 && "Unknown binary operator");
     271                 :   case BinaryOperator::PtrMemD:   return "ptrmemd";
     272                 :   case BinaryOperator::PtrMemI:   return "ptrmemi";
     273                 :   case BinaryOperator::Mul:       return "mul";
     274                 :   case BinaryOperator::Div:       return "div";
     275                 :   case BinaryOperator::Rem:       return "rem";
     276                 :   case BinaryOperator::Add:       return "add";
     277                 :   case BinaryOperator::Sub:       return "sub";
     278                 :   case BinaryOperator::Shl:       return "shl";
     279                 :   case BinaryOperator::Shr:       return "shr";
     280                 :   case BinaryOperator::LT:        return "lt";
     281                 :   case BinaryOperator::GT:        return "gt";
     282                 :   case BinaryOperator::LE:        return "le";
     283                 :   case BinaryOperator::GE:        return "ge";
     284                 :   case BinaryOperator::EQ:        return "eq";
     285                 :   case BinaryOperator::NE:        return "ne";
     286                 :   case BinaryOperator::And:       return "and";
     287                 :   case BinaryOperator::Xor:       return "xor";
     288                 :   case BinaryOperator::Or:        return "or";
     289                 :   case BinaryOperator::LAnd:      return "land";
     290                 :   case BinaryOperator::LOr:       return "lor";
     291                 :   case BinaryOperator::Assign:    return "assign";
     292                 :   case BinaryOperator::MulAssign: return "mulassign";
     293                 :   case BinaryOperator::DivAssign: return "divassign";
     294                 :   case BinaryOperator::RemAssign: return "remassign";
     295                 :   case BinaryOperator::AddAssign: return "addassign";
     296                 :   case BinaryOperator::SubAssign: return "subassign";
     297                 :   case BinaryOperator::ShlAssign: return "shlassign";
     298                 :   case BinaryOperator::ShrAssign: return "shrassign";
     299                 :   case BinaryOperator::AndAssign: return "andassign";
     300                 :   case BinaryOperator::XorAssign: return "xorassign";
     301                 :   case BinaryOperator::OrAssign:  return "orassign";
     302                 :   case BinaryOperator::Comma:     return "comma";
     303                 :   }
     304                 : }
     305                 : 
     306                 : void StmtXML::VisitUnaryOperator(UnaryOperator *Node) {
     307                 :   DumpExpr(Node);
     308                 :   Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
     309                 : }
     310                 : 
     311                 : void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
     312                 :   DumpExpr(Node);
     313                 :   Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
     314                 :   Doc.addAttribute("is_type", Node->isArgumentType() ? "1" : "0");
     315                 :   if (Node->isArgumentType())
     316                 :     DumpTypeExpr(Node->getArgumentType());
     317                 : }
     318                 : 
     319                 : void StmtXML::VisitMemberExpr(MemberExpr *Node) {
     320                 :   DumpExpr(Node);
     321                 :   Doc.addAttribute("is_deref", Node->isArrow() ? "1" : "0");
     322                 :   Doc.addAttribute("name", Node->getMemberDecl()->getNameAsString());
     323                 :   Doc.addRefAttribute(Node->getMemberDecl());
     324                 : }
     325                 : 
     326                 : void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
     327                 :   DumpExpr(Node);
     328                 :   Doc.addAttribute("name", Node->getAccessor().getName());
     329                 : }
     330                 : 
     331                 : void StmtXML::VisitBinaryOperator(BinaryOperator *Node) {
     332                 :   DumpExpr(Node);
     333                 :   Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
     334                 : }
     335                 : 
     336                 : void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
     337                 :   VisitBinaryOperator(Node);
     338                 : /* FIXME: is this needed in the AST?
     339                 :   DumpExpr(Node);
     340                 :   CurrentNode = CurrentNode->addSubNode("ComputeLHSTy");
     341                 :   DumpType(Node->getComputationLHSType());
     342                 :   CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy");
     343                 :   DumpType(Node->getComputationResultType());
     344                 :   Doc.toParent();
     345                 : */
     346                 : }
     347                 : 
     348                 : // GNU extensions.
     349                 : 
     350                 : void StmtXML::VisitAddrLabelExpr(AddrLabelExpr *Node) {
     351                 :   DumpExpr(Node);
     352                 :   Doc.addAttribute("name", Node->getLabel()->getName());
     353                 : }
     354                 : 
     355                 : void StmtXML::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
     356                 :   DumpExpr(Node);
     357                 :   DumpTypeExpr(Node->getArgType1());
     358                 :   DumpTypeExpr(Node->getArgType2());
     359                 : }
     360                 : 
     361                 : //===----------------------------------------------------------------------===//
     362                 : // C++ Expressions
     363                 : //===----------------------------------------------------------------------===//
     364                 : 
     365                 : void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
     366                 :   DumpExpr(Node);
     367                 :   Doc.addAttribute("kind", Node->getCastName());
     368                 :   DumpTypeExpr(Node->getTypeAsWritten());
     369                 : }
     370                 : 
     371                 : void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
     372                 :   DumpExpr(Node);
     373                 :   Doc.addAttribute("value", Node->getValue() ? "true" : "false");
     374                 : }
     375                 : 
     376                 : void StmtXML::VisitCXXThisExpr(CXXThisExpr *Node) {
     377                 :   DumpExpr(Node);
     378                 : }
     379                 : 
     380                 : void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
     381                 :   DumpExpr(Node);
     382                 :   DumpTypeExpr(Node->getTypeAsWritten());
     383                 : }
     384                 : 
     385                 : //===----------------------------------------------------------------------===//
     386                 : // Obj-C Expressions
     387                 : //===----------------------------------------------------------------------===//
     388                 : 
     389                 : void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
     390                 :   DumpExpr(Node);
     391                 :   Doc.addAttribute("selector", Node->getSelector().getAsString());
     392                 :   IdentifierInfo* clsName = Node->getClassName();
     393                 :   if (clsName)
     394                 :     Doc.addAttribute("class", clsName->getName());
     395                 : }
     396                 : 
     397                 : void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
     398                 :   DumpExpr(Node);
     399                 :   DumpTypeExpr(Node->getEncodedType());
     400                 : }
     401                 : 
     402                 : void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
     403                 :   DumpExpr(Node);
     404                 :   Doc.addAttribute("selector", Node->getSelector().getAsString());
     405                 : }
     406                 : 
     407                 : void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
     408                 :   DumpExpr(Node);
     409                 :   Doc.addAttribute("protocol", Node->getProtocol()->getNameAsString());
     410                 : }
     411                 : 
     412                 : void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
     413                 :   DumpExpr(Node);
     414                 :   Doc.addAttribute("property", Node->getProperty()->getNameAsString());
     415                 : }
     416                 : 
     417                 : void StmtXML::VisitObjCImplicitSetterGetterRefExpr(
     418                 :                              ObjCImplicitSetterGetterRefExpr *Node) {
     419                 :   DumpExpr(Node);
     420                 :   ObjCMethodDecl *Getter = Node->getGetterMethod();
     421                 :   ObjCMethodDecl *Setter = Node->getSetterMethod();
     422                 :   Doc.addAttribute("Getter", Getter->getSelector().getAsString());
     423                 :   Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)");
     424                 : }
     425                 : 
     426                 : void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
     427                 :   DumpExpr(Node);
     428                 :   Doc.addAttribute("super", "1");
     429                 : }
     430                 : 
     431                 : void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
     432                 :   DumpExpr(Node);
     433                 :   Doc.addAttribute("kind", Node->getDecl()->getDeclKindName());
     434                 :   Doc.addAttribute("decl", Node->getDecl()->getNameAsString());
     435                 :   if (Node->isFreeIvar())
     436                 :     Doc.addAttribute("isFreeIvar", "1");
     437                 : }
     438                 : #endif
     439                 : //===----------------------------------------------------------------------===//
     440                 : // Stmt method implementations
     441                 : //===----------------------------------------------------------------------===//
     442                 : 
     443                 : /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
     444               48: void DocumentXML::PrintStmt(const Stmt *S) {
     445               48:   StmtXML P(*this);
     446               48:   P.DumpSubTree(const_cast<Stmt*>(S));
     447               48: }
     448                 : 

Generated: 2010-02-10 01:31 by zcov