LTP GCOV extension - code coverage report
Current view: directory - src - staptree.cxx
Test: stap.info
Date: 2008-03-12 Instrumented lines: 1291
Code covered: 88.4 % Executed lines: 1141

       1                 : // parse tree functions
       2                 : // Copyright (C) 2005-2008 Red Hat Inc.
       3                 : //
       4                 : // This file is part of systemtap, and is free software.  You can
       5                 : // redistribute it and/or modify it under the terms of the GNU General
       6                 : // Public License (GPL); either version 2, or (at your option) any
       7                 : // later version.
       8                 : 
       9                 : #include "config.h"
      10                 : #include "staptree.h"
      11                 : #include "parse.h"
      12                 : #include "util.h"
      13                 : 
      14                 : #include <iostream>
      15                 : #include <typeinfo>
      16                 : #include <sstream>
      17                 : #include <cassert>
      18                 : #include <cstring>
      19                 : #include <vector>
      20                 : #include <algorithm>
      21                 : #include <cstring>
      22                 : 
      23                 : using namespace std;
      24                 : 
      25                 : 
      26                 : 
      27        27577864 : expression::expression ():
      28        27577864 :   type (pe_unknown), tok (0)
      29                 : {
      30        27577864 : } 
      31                 : 
      32                 : 
      33              10 : expression::~expression ()
      34                 : {
      35              10 : }
      36                 : 
      37                 : 
      38        10275975 : statement::statement ():
      39        10275975 :   tok (0)
      40                 : {
      41        10275975 : } 
      42                 : 
      43                 : 
      44              97 : statement::~statement ()
      45                 : {
      46              97 : }
      47                 : 
      48                 : 
      49        10968930 : symbol::symbol ():
      50        10968930 :   referent (0)
      51                 : {
      52        10968930 : }
      53                 : 
      54                 : 
      55          549344 : arrayindex::arrayindex ():
      56          549344 :   base (0)
      57                 : {
      58          549344 : }
      59                 : 
      60                 : 
      61         2128495 : functioncall::functioncall ():
      62         2128495 :   referent (0)
      63                 : {
      64         2128495 : }
      65                 : 
      66                 : 
      67          907676 : symboldecl::symboldecl ():
      68                 :   tok (0),
      69          907676 :   type (pe_unknown)
      70                 : {
      71          907676 : } 
      72                 : 
      73                 : 
      74              97 : symboldecl::~symboldecl ()
      75                 : {
      76              97 : }
      77                 : 
      78                 : probe_point::probe_point (std::vector<component*> const & comps,
      79               0 :                           const token * t):
      80                 :   components(comps), tok(t), optional (false), sufficient (false),
      81               0 :   condition (0)
      82                 : {
      83               0 : }
      84                 : 
      85                 : // NB: shallow-copy of compoonents & condition!
      86          528246 : probe_point::probe_point (const probe_point& pp):
      87                 :   components(pp.components), tok(pp.tok), optional (pp.optional), sufficient (pp.sufficient),
      88          528246 :   condition (pp.condition)
      89                 : {
      90          528246 : }
      91                 : 
      92                 : 
      93         2983463 : probe_point::probe_point ():
      94         2983463 :   tok (0), optional (false), sufficient (false), condition (0)
      95                 : {
      96         2983463 : }
      97                 : 
      98                 : 
      99                 : unsigned probe::last_probeidx = 0;
     100         1687493 : probe::probe ():
     101         1687493 :   body (0), tok (0)
     102                 : {
     103         1687493 :   this->name = string ("probe_") + lex_cast<string>(last_probeidx ++);
     104         1687493 : }
     105                 : 
     106                 : 
     107         7963364 : probe_point::component::component ():
     108         7963364 :   arg (0)
     109                 : {
     110         7963364 : }
     111                 : 
     112                 : 
     113         1243662 : probe_point::component::component (std::string const & f, literal * a): 
     114         1243662 :   functor(f), arg(a) 
     115                 : {
     116         1243662 : }
     117                 : 
     118                 : 
     119          493379 : vardecl::vardecl ():
     120          493379 :   arity (-1), maxsize(0), init(NULL)
     121                 : {
     122          493379 : }
     123                 : 
     124                 : 
     125                 : void
     126          410058 : vardecl::set_arity (int a)
     127                 : {
     128          410058 :   if (a < 0)
     129              78 :     return;
     130                 : 
     131          409980 :   if ((arity != a && arity >= 0) || (a == 0 && maxsize > 0))
     132               0 :     throw semantic_error ("inconsistent arity", tok);
     133                 : 
     134          409980 :   if (arity != a)
     135                 :     {
     136           89897 :       arity = a;
     137           89897 :       index_types.resize (arity);
     138           90408 :       for (int i=0; i<arity; i++)
     139             511 :         index_types[i] = pe_unknown;
     140                 :     }
     141                 : }
     142                 : 
     143                 : bool 
     144          373602 : vardecl::compatible_arity (int a)
     145                 : {
     146          373602 :   if (a == 0 && maxsize > 0)
     147               4 :     return false;
     148          373598 :   if (arity == -1 || a == -1)
     149           86933 :     return true;
     150          286665 :   return arity == a;
     151                 : }
     152                 : 
     153                 : 
     154          414297 : functiondecl::functiondecl ():
     155          414297 :   body (0)
     156                 : {
     157          414297 : }
     158                 : 
     159                 : 
     160         1858812 : literal_number::literal_number (int64_t v)
     161                 : {
     162         1858812 :   value = v;
     163         1858812 :   type = pe_long;
     164         1858812 : }
     165                 : 
     166                 : 
     167         4672774 : literal_string::literal_string (const string& v)
     168                 : {
     169         4672774 :   value = v;
     170         4672774 :   type = pe_string;
     171         4672774 : }
     172                 : 
     173                 : 
     174                 : ostream&
     175          181571 : operator << (ostream& o, const exp_type& e)
     176                 : {
     177          181571 :   switch (e)
     178                 :     {
     179             424 :     case pe_unknown: o << "unknown"; break;
     180           93362 :     case pe_long: o << "long"; break;
     181           87709 :     case pe_string: o << "string"; break;
     182              76 :     case pe_stats: o << "stats"; break;
     183               0 :     default: o << "???"; break;
     184                 :     }
     185          181571 :   return o;
     186                 : }
     187                 : 
     188                 : 
     189                 : // ------------------------------------------------------------------------
     190                 : // parse tree printing
     191                 : 
     192         3117981 : ostream& operator << (ostream& o, const expression& k)
     193                 : {
     194         3117981 :   k.print (o);
     195         3117981 :   return o;
     196                 : }
     197                 : 
     198                 : 
     199         1850610 : void literal_string::print (ostream& o) const
     200                 : {
     201         1850610 :   o << '"';
     202        27442426 :   for (unsigned i=0; i<value.size(); i++)
     203        25591816 :     if (value[i] == '"') // or other escapeworthy characters?
     204               6 :       o << '\\' << '"';
     205                 :     else
     206        25591810 :       o << value[i];
     207         1850610 :   o << '"';
     208         1850610 : }
     209                 : 
     210                 : 
     211          158369 : void literal_number::print (ostream& o) const
     212                 : {
     213          158369 :   o << value;
     214          158369 : }
     215                 : 
     216                 : 
     217          303629 : void binary_expression::print (ostream& o) const
     218                 : {
     219                 :   o << "(" << *left << ") " 
     220                 :     << op 
     221          303629 :     << " (" << *right << ")";
     222          303629 : }
     223                 : 
     224                 : 
     225            4042 : void unary_expression::print (ostream& o) const
     226                 : {
     227            4042 :   o << op << '(' << *operand << ")"; 
     228            4042 : }
     229                 : 
     230             217 : void array_in::print (ostream& o) const
     231                 : {
     232             217 :   o << "[";
     233             489 :   for (unsigned i=0; i<operand->indexes.size(); i++)
     234                 :     {
     235             272 :       if (i > 0) o << ", ";
     236             272 :       operand->indexes[i]->print (o);
     237                 :     }
     238             217 :   o << "] in ";
     239             217 :   operand->base->print_indexable (o);
     240             217 : }
     241                 : 
     242           51443 : void post_crement::print (ostream& o) const
     243                 : {
     244           51443 :   o << '(' << *operand << ")" << op; 
     245           51443 : }
     246                 : 
     247                 : 
     248             119 : void ternary_expression::print (ostream& o) const
     249                 : {
     250                 :   o << "(" << *cond << ")?("
     251                 :     << *truevalue << "):("
     252             119 :     << *falsevalue << ")"; 
     253             119 : }
     254                 : 
     255                 : 
     256          597914 : void symbol::print (ostream& o) const
     257                 : {
     258          597914 :   o << name;
     259          597914 : }
     260                 : 
     261                 : 
     262            2772 : void target_symbol::print (std::ostream& o) const
     263                 : {
     264            2772 :   o << base_name;
     265            3447 :   for (unsigned i = 0; i < components.size(); ++i)
     266                 :     {
     267             675 :       switch (components[i].first)
     268                 :         {
     269                 :         case comp_literal_array_index:
     270               7 :           o << '[' << components[i].second << ']';
     271               7 :           break;
     272                 :         case comp_struct_member:
     273             668 :           o << "->" << components[i].second;
     274                 :           break;
     275                 :         }
     276                 :     }
     277            2772 : }
     278                 : 
     279                 : 
     280           17390 : void vardecl::print (ostream& o) const
     281                 : {
     282           17390 :   o << name;
     283           17390 :   if (maxsize > 0)
     284              17 :     o << "[" << maxsize << "]";
     285           17390 :   if (arity > 0 || index_types.size() > 0)
     286               0 :     o << "[...]";
     287           17390 :   if (init)
     288                 :     {
     289              15 :       o << " = ";
     290              15 :       init->print(o);
     291                 :     }
     292           17390 : }
     293                 : 
     294                 : 
     295           82842 : void vardecl::printsig (ostream& o) const
     296                 : {
     297           82842 :   o << name;
     298           82842 :   if (maxsize > 0)
     299              19 :     o << "[" << maxsize << "]";
     300           82842 :   o << ":" << type;
     301           82842 :   if (index_types.size() > 0)
     302                 :     {
     303             343 :       o << " [";
     304             804 :       for (unsigned i=0; i<index_types.size(); i++)
     305             461 :         o << (i>0 ? ", " : "") << index_types[i];
     306             343 :       o << "]";
     307                 :     }
     308           82842 : }
     309                 : 
     310                 : 
     311             385 : void functiondecl::print (ostream& o) const
     312                 : {
     313             385 :   o << "function " << name << " (";
     314             729 :   for (unsigned i=0; i<formal_args.size(); i++)
     315             344 :     o << (i>0 ? ", " : "") << *formal_args[i];
     316             385 :   o << ")" << endl;
     317             385 :   body->print(o);
     318             385 : }
     319                 : 
     320                 : 
     321           81500 : void functiondecl::printsig (ostream& o) const
     322                 : {
     323           81500 :   o << name << ":" << type << " (";
     324           98227 :   for (unsigned i=0; i<formal_args.size(); i++)
     325                 :     o << (i>0 ? ", " : "")
     326                 :       << *formal_args[i]
     327                 :       << ":"
     328           16727 :       << formal_args[i]->type;
     329           81500 :   o << ")";
     330           81500 : }
     331                 : 
     332                 : 
     333           59725 : void arrayindex::print (ostream& o) const
     334                 : {
     335           59725 :   base->print_indexable (o);
     336           59725 :   o << "[";
     337          121396 :   for (unsigned i=0; i<indexes.size(); i++)
     338           61671 :     o << (i>0 ? ", " : "") << *indexes[i];
     339           59725 :   o << "]";
     340           59725 : }
     341                 : 
     342                 : 
     343          273025 : void functioncall::print (ostream& o) const
     344                 : {
     345          273025 :   o << function << "(";
     346          338922 :   for (unsigned i=0; i<args.size(); i++)
     347           65897 :     o << (i>0 ? ", " : "") << *args[i];
     348          273025 :   o << ")";
     349          273025 : }  
     350                 : 
     351                 : 
     352                 : bool
     353                 : print_format::parse_print(const std::string &name,
     354        10996535 :   bool &stream, bool &format, bool &delim, bool &newline, bool &_char)
     355                 : {
     356        10996535 :   const char *n = name.c_str();
     357                 : 
     358        10996535 :   stream = true;
     359        10996535 :   format = delim = newline = _char = false;
     360                 : 
     361        10996535 :   if (strcmp(n, "print_char") == 0)
     362                 :     {
     363              14 :       _char = true;
     364              14 :       return true;
     365                 :     }
     366                 : 
     367        10996521 :   if (*n == 's')
     368                 :     {
     369         1128441 :       stream = false;
     370         1128441 :       ++n;
     371                 :     }
     372                 : 
     373        10996521 :   if (0 != strncmp(n, "print", 5))
     374        10401227 :     return false;
     375          595294 :   n += 5;
     376                 : 
     377          595294 :   if (*n == 'f')
     378                 :     {
     379          569404 :       format = true;
     380          569404 :       ++n;
     381                 :     }
     382                 :   else
     383                 :     {
     384           25890 :       if (*n == 'd')
     385                 :         {
     386              39 :           delim = true;
     387              39 :           ++n;
     388                 :         }
     389                 : 
     390           25890 :       if (*n == 'l' && *(n+1) == 'n')
     391                 :         {
     392             155 :           newline = true;
     393             155 :           n += 2;
     394                 :         }
     395                 :     }
     396                 : 
     397          595294 :   return (*n == '\0');
     398                 : }
     399                 : 
     400                 : 
     401                 : string 
     402            4577 : print_format::components_to_string(vector<format_component> const & components)
     403                 : {
     404            4577 :   ostringstream oss;
     405                 : 
     406           22581 :   for (vector<format_component>::const_iterator i = components.begin();
     407                 :        i != components.end(); ++i)
     408                 :     {
     409                 : 
     410           18004 :       assert (i->type != conv_unspecified);
     411                 : 
     412           18004 :       if (i->type == conv_literal)
     413                 :         {
     414            8520 :           assert(!i->literal_string.empty());
     415           35453 :           for (string::const_iterator j = i->literal_string.begin();
     416                 :                j != i->literal_string.end(); ++j)
     417                 :             {
     418                 :               // See also: c_unparser::visit_literal_string and lex_cast_qstring
     419           26933 :               if (*j == '%')
     420               8 :                 oss << '%';
     421           26925 :               else if(*j == '"')
     422              36 :                 oss << '\\';
     423           26933 :               oss << *j;
     424                 :             }
     425                 :         }
     426                 :       else
     427                 :         {
     428            9484 :           oss << '%';
     429                 : 
     430            9484 :           if (i->flags & static_cast<unsigned long>(fmt_flag_zeropad))
     431              33 :             oss << '0';
     432                 : 
     433            9484 :           if (i->flags & static_cast<unsigned long>(fmt_flag_plus))
     434               1 :             oss << '+';
     435                 : 
     436            9484 :           if (i->flags & static_cast<unsigned long>(fmt_flag_space))
     437               2 :             oss << ' ';
     438                 : 
     439            9484 :           if (i->flags & static_cast<unsigned long>(fmt_flag_left))
     440              61 :             oss << '-';
     441                 : 
     442            9484 :           if (i->flags & static_cast<unsigned long>(fmt_flag_special))
     443              34 :             oss << '#';
     444                 : 
     445            9484 :           if (i->widthtype == width_dynamic)
     446              13 :             oss << '*';
     447            9471 :           else if (i->widthtype != width_unspecified && i->width > 0)
     448             254 :             oss << i->width;
     449                 : 
     450            9484 :           if (i->prectype == prec_dynamic)
     451              14 :             oss << ".*";
     452            9470 :           else if (i->prectype != prec_unspecified && i->precision > 0)
     453              19 :             oss << '.' << i->precision;
     454                 : 
     455            9484 :           switch (i->type)   
     456                 :             {
     457                 :             case conv_binary:
     458              78 :               oss << "b";
     459              78 :               break;
     460                 : 
     461                 :             case conv_signed_decimal:
     462            2158 :               oss << "lld";
     463            2158 :               break;
     464                 : 
     465                 :             case conv_unsigned_decimal:
     466              24 :               oss << "llu";
     467              24 :               break;
     468                 : 
     469                 :             case conv_unsigned_octal:
     470              54 :               oss << "llo";
     471              54 :               break;
     472                 : 
     473                 :             case conv_unsigned_ptr:
     474             807 :               oss << "p";
     475             807 :               break;
     476                 : 
     477                 :             case conv_unsigned_uppercase_hex:
     478              11 :               oss << "llX";
     479              11 :               break;
     480                 : 
     481                 :             case conv_unsigned_lowercase_hex:
     482              89 :               oss << "llx";
     483              89 :               break;
     484                 : 
     485                 :             case conv_string:
     486            6246 :               oss << 's';
     487            6246 :               break;
     488                 :               
     489                 :             case conv_memory:
     490              17 :               oss << 'm';
     491              17 :               break;
     492                 :               
     493                 :             case conv_size:
     494               0 :               oss << 'n';
     495                 :               break;
     496                 : 
     497                 :             default:
     498                 :               break;
     499                 :             }
     500                 :         }
     501                 :     }
     502            4577 :   return oss.str ();
     503                 : }
     504                 :  
     505                 : vector<print_format::format_component> 
     506          569404 : print_format::string_to_components(string const & str)
     507                 : {
     508          569404 :   format_component curr;
     509          569404 :   vector<format_component> res;
     510                 : 
     511          569404 :   curr.clear();
     512                 : 
     513          569404 :   string::const_iterator i = str.begin();
     514                 :   
     515         4445189 :   while (i != str.end())
     516                 :     {
     517         3306381 :       if (*i != '%')
     518                 :         {
     519         1959366 :           assert (curr.type == conv_unspecified || curr.type == conv_literal);
     520         1959366 :           curr.type = conv_literal;
     521         1959366 :           curr.literal_string += *i;
     522         1959366 :           ++i;
     523         1959366 :           continue;
     524                 :         }
     525         1347015 :       else if (i+1 == str.end() || *(i+1) == '%')
     526                 :         {
     527            2164 :           assert(*i == '%');
     528                 :           // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
     529            2164 :           assert (curr.type == conv_unspecified || curr.type == conv_literal);
     530            2164 :           curr.type = conv_literal;
     531            2164 :           curr.literal_string += '%';
     532            2164 :           i += 2;
     533            2164 :           continue;
     534                 :         }
     535                 :       else 
     536                 :         {
     537         1344851 :           assert(*i == '%');
     538         1344851 :           if (curr.type != conv_unspecified)
     539                 :             {
     540                 :               // Flush any component we were previously accumulating
     541          811879 :               assert (curr.type == conv_literal);
     542          811879 :               res.push_back(curr);
     543          811879 :               curr.clear();
     544                 :             }
     545                 :         }
     546         1344851 :       ++i;
     547                 :       
     548         1344851 :       if (i == str.end())
     549               0 :         break;
     550                 : 
     551                 :       // Now we are definitely parsing a conversion. 
     552                 :       // Begin by parsing flags (which are optional).
     553                 : 
     554         1344851 :       switch (*i)
     555                 :         {
     556                 :         case '0':
     557            2201 :           curr.flags |= static_cast<unsigned long>(fmt_flag_zeropad);
     558            2201 :           ++i;
     559            2201 :           break;
     560                 :           
     561                 :         case '+':
     562               3 :           curr.flags |= static_cast<unsigned long>(fmt_flag_plus);
     563               3 :           ++i;
     564               3 :           break;
     565                 :           
     566                 :         case '-':
     567              59 :           curr.flags |= static_cast<unsigned long>(fmt_flag_left);
     568              59 :           ++i;
     569              59 :           break;
     570                 :           
     571                 :         case ' ':
     572               6 :           curr.flags |= static_cast<unsigned long>(fmt_flag_space);
     573               6 :           ++i;
     574               6 :           break;
     575                 :           
     576                 :         case '#':
     577            9741 :           curr.flags |= static_cast<unsigned long>(fmt_flag_special);
     578            9741 :           ++i;
     579                 :           break;
     580                 : 
     581                 :         default:
     582                 :           break;
     583                 :         }
     584                 : 
     585         1344851 :       if (i == str.end())
     586               0 :         break;
     587                 : 
     588                 :       // Parse optional width
     589         1344851 :       if (*i == '*')
     590                 :         {
     591              13 :           curr.widthtype = width_dynamic;
     592              13 :           ++i;
     593                 :         }
     594         1344838 :       else if (isdigit(*i))
     595                 :         {
     596            3509 :           curr.widthtype = width_static;
     597            3509 :           curr.width = 0;
     598            3610 :           do
     599                 :             {
     600            3610 :               curr.width *= 10;
     601            3610 :               curr.width += (*i - '0');
     602            3610 :               ++i;
     603                 :             }
     604                 :           while (i != str.end() && isdigit(*i));
     605                 :         }
     606                 : 
     607         1344851 :       if (i == str.end())
     608               0 :         break;
     609                 : 
     610                 :       // Parse optional precision
     611         1344851 :       if (*i == '.')
     612                 :         {
     613              37 :           ++i;
     614              37 :           if (i == str.end())
     615               0 :             break;
     616              37 :           if (*i == '*')
     617                 :             {
     618              14 :               curr.prectype = prec_dynamic;
     619              14 :               ++i;
     620                 :             }
     621              23 :           else if (isdigit(*i))
     622                 :             {
     623              23 :               curr.prectype = prec_static;
     624              23 :               curr.precision = 0;
     625              23 :               do
     626                 :                 {
     627              23 :                   curr.precision *= 10;
     628              23 :                   curr.precision += (*i - '0');
     629              23 :                   ++i;
     630                 :                 }
     631                 :               while (i != str.end() && isdigit(*i));
     632                 :             }
     633                 :         }
     634                 : 
     635         1344851 :       if (i == str.end())
     636               0 :         break;
     637                 : 
     638                 :       // Parse the actual conversion specifier (sdiouxX)
     639         1344851 :       switch (*i)
     640                 :         {
     641                 :           // Valid conversion types
     642                 :         case 'b':
     643              78 :           curr.type = conv_binary;
     644              78 :           break;
     645                 :           
     646                 :         case 's':
     647          304890 :           curr.type = conv_string;
     648          304890 :           break;
     649                 :           
     650                 :         case 'm':
     651              17 :           curr.type = conv_memory;
     652              17 :           break;
     653                 :           
     654                 :         case 'd':
     655                 :         case 'i':
     656          727002 :           curr.type = conv_signed_decimal;
     657          727002 :           break;
     658                 :           
     659                 :         case 'o':
     660            9761 :           curr.type = conv_unsigned_octal;
     661            9761 :           break;
     662                 :           
     663                 :         case 'u':
     664              26 :           curr.type = conv_unsigned_decimal;
     665              26 :           break;
     666                 :           
     667                 :         case 'p':
     668          280268 :           curr.type = conv_unsigned_ptr;
     669          280268 :           break;
     670                 : 
     671                 :         case 'X':
     672              13 :           curr.type = conv_unsigned_uppercase_hex;
     673              13 :           break;
     674                 :           
     675                 :         case 'x':
     676           22796 :           curr.type = conv_unsigned_lowercase_hex;
     677           22796 :           break;
     678                 : 
     679                 :         case 'n':
     680               0 :           curr.type = conv_size;
     681                 :           break;
     682                 :           
     683                 :         default:
     684                 :           break;
     685                 :         }
     686                 :       
     687         1344851 :       if (curr.type == conv_unspecified)
     688               0 :         throw parse_error("invalid or missing conversion specifier");
     689                 :       
     690         1344851 :       ++i;
     691         1344851 :       res.push_back(curr);
     692         1344851 :       curr.clear();      
     693                 :     }
     694                 : 
     695                 :   // If there's a remaining partly-composed conversion, fail.
     696          569404 :   if (!curr.is_empty())
     697                 :     {
     698           12032 :       if (curr.type == conv_literal)
     699           12032 :         res.push_back(curr);      
     700                 :       else
     701               0 :         throw parse_error("trailing incomplete print format conversion");
     702                 :     }
     703                 : 
     704          569404 :   return res;
     705                 : }
     706                 : 
     707                 : 
     708          132528 : void print_format::print (ostream& o) const
     709                 : {
     710          132528 :   o << tok->content << "(";
     711          132528 :   if (print_with_format)
     712          128547 :     o << lex_cast_qstring (raw_components);
     713          132528 :   if (print_with_delim)
     714              89 :     o << lex_cast_qstring (delimiter.literal_string);
     715          132528 :   if (hist)
     716             275 :     hist->print(o);
     717          386745 :   for (vector<expression*>::const_iterator i = args.begin();
     718                 :        i != args.end(); ++i)
     719                 :     {
     720          254217 :       if (i != args.begin() || print_with_format || print_with_delim)
     721          250600 :         o << ", ";
     722          254217 :       (*i)->print(o);
     723                 :     }
     724          132528 :   o << ")";
     725          132528 : }
     726                 : 
     727             767 : void stat_op::print (ostream& o) const
     728                 : {
     729             767 :   o << '@';
     730             767 :   switch (ctype)
     731                 :     {
     732                 :     case sc_average:
     733             121 :       o << "avg(";
     734             121 :       break;
     735                 : 
     736                 :     case sc_count:
     737             322 :       o << "count(";
     738             322 :       break;
     739                 : 
     740                 :     case sc_sum:
     741             134 :       o << "sum(";
     742             134 :       break;
     743                 : 
     744                 :     case sc_min:
     745              95 :       o << "min(";
     746              95 :       break;
     747                 :       
     748                 :     case sc_max:
     749              95 :       o << "max(";
     750                 :       break;
     751                 :     }
     752             767 :   stat->print(o);
     753             767 :   o << ")";
     754             767 : }
     755                 : 
     756                 : void 
     757             366 : hist_op::print (ostream& o) const
     758                 : {
     759             366 :   o << '@';
     760             366 :   switch (htype)
     761                 :     {
     762                 :     case hist_linear:
     763             163 :       assert(params.size() == 3);
     764             163 :       o << "hist_linear(";
     765             163 :       stat->print(o);
     766             652 :       for (size_t i = 0; i < params.size(); ++i)
     767                 :         {
     768             489 :           o << ", " << params[i];
     769                 :         }
     770             163 :       o << ")";
     771             163 :       break;
     772                 : 
     773                 :     case hist_log:
     774             203 :       assert(params.size() == 0);
     775             203 :       o << "hist_log(";
     776             203 :       stat->print(o);
     777             203 :       o << ")";
     778                 :       break;
     779                 :     }
     780             366 : }
     781                 : 
     782          740369 : ostream& operator << (ostream& o, const statement& k)
     783                 : {
     784          740369 :   k.print (o);
     785          740369 :   return o;
     786                 : }
     787                 : 
     788                 : 
     789           76841 : void embeddedcode::print (ostream &o) const
     790                 : {
     791           76841 :   o << "%{";
     792           76841 :   o << code;
     793           76841 :   o << "%}";
     794           76841 : }
     795                 : 
     796          127198 : void block::print (ostream& o) const
     797                 : {
     798          127198 :   o << "{" << endl;
     799          645442 :   for (unsigned i=0; i<statements.size(); i++)
     800          518244 :     o << *statements [i] << endl;
     801          127198 :   o << "}";
     802          127198 : }
     803                 : 
     804                 : 
     805             565 : void for_loop::print (ostream& o) const
     806                 : {
     807             565 :   o << "for (";
     808             565 :   if (init) init->print (o);
     809             565 :   o << "; ";
     810             565 :   cond->print (o);
     811             565 :   o << "; ";
     812             565 :   if (incr) incr->print (o);
     813             565 :   o << ") ";
     814             565 :   block->print (o);
     815             565 : }
     816                 : 
     817                 : 
     818             407 : void foreach_loop::print (ostream& o) const
     819                 : {
     820             407 :   o << "foreach ([";
     821             915 :   for (unsigned i=0; i<indexes.size(); i++)
     822                 :     {
     823             508 :       if (i > 0) o << ", ";
     824             508 :       indexes[i]->print (o);
     825             508 :       if (sort_direction != 0 && sort_column == i+1)
     826              57 :         o << (sort_direction > 0 ? "+" : "-");
     827                 :     }
     828             407 :   o << "] in ";
     829             407 :   base->print_indexable (o);
     830             407 :   if (sort_direction != 0 && sort_column == 0)
     831              88 :     o << (sort_direction > 0 ? "+" : "-");
     832             407 :   if (limit)
     833                 :     {
     834              72 :       o << " limit ";
     835              72 :       limit->print (o);
     836                 :     }
     837             407 :   o << ") ";
     838             407 :   block->print (o);
     839             407 : }
     840                 : 
     841                 : 
     842          104150 : void null_statement::print (ostream& o) const
     843                 : {
     844          104150 :   o << ";"; 
     845          104150 : }
     846                 : 
     847                 : 
     848          329111 : void expr_statement::print (ostream& o) const
     849                 : {
     850          329111 :   o << *value;
     851          329111 : }
     852                 : 
     853                 : 
     854           62955 : void return_statement::print (ostream& o) const
     855                 : {
     856           62955 :   o << "return " << *value;
     857           62955 : }
     858                 : 
     859                 : 
     860            1737 : void delete_statement::print (ostream& o) const
     861                 : {
     862            1737 :   o << "delete " << *value;
     863            1737 : }
     864                 : 
     865            2037 : void next_statement::print (ostream& o) const
     866                 : {
     867            2037 :   o << "next";
     868            2037 : }
     869                 : 
     870              29 : void break_statement::print (ostream& o) const
     871                 : {
     872              29 :   o << "break";
     873              29 : }
     874                 : 
     875              28 : void continue_statement::print (ostream& o) const
     876                 : {
     877              28 :   o << "continue";
     878              28 : }
     879                 : 
     880          191558 : void if_statement::print (ostream& o) const
     881                 : {
     882                 :   o << "if (" << *condition << ") "
     883          191558 :     << *thenblock << endl;
     884          191558 :   if (elseblock)
     885           28530 :     o << "else " << *elseblock << endl;
     886          191558 : }
     887                 : 
     888                 : 
     889             554 : void stapfile::print (ostream& o) const
     890                 : {
     891             554 :   o << "# file " << name << endl;
     892                 : 
     893             585 :   for (unsigned i=0; i<embeds.size(); i++)
     894              31 :     embeds[i]->print (o);
     895                 : 
     896             873 :   for (unsigned i=0; i<globals.size(); i++)
     897                 :     {
     898             319 :       o << "global ";
     899             319 :       globals[i]->print (o);
     900             319 :       o << endl;
     901                 :     }
     902                 : 
     903            1693 :   for (unsigned i=0; i<aliases.size(); i++)
     904                 :     {
     905            1139 :       aliases[i]->print (o);
     906            1139 :       o << endl;
     907                 :     }
     908                 : 
     909            1452 :   for (unsigned i=0; i<probes.size(); i++)
     910                 :     {
     911             898 :       probes[i]->print (o);
     912             898 :       o << endl;
     913                 :     }
     914                 : 
     915             939 :   for (unsigned j = 0; j < functions.size(); j++)
     916                 :     {
     917             385 :       functions[j]->print (o);
     918             385 :       o << endl;
     919                 :     }
     920             554 : }
     921                 : 
     922                 : 
     923            2037 : void probe::print (ostream& o) const
     924                 : {
     925            2037 :   o << "probe ";
     926            2037 :   printsig (o);
     927            2037 :   o << *body;
     928            2037 : }
     929                 : 
     930                 : 
     931          539893 : void probe::printsig (ostream& o) const
     932                 : {
     933         1139663 :   for (unsigned i=0; i<locations.size(); i++)
     934                 :     {
     935          599770 :       if (i > 0) o << ",";
     936          599770 :       locations[i]->print (o);
     937                 :     }
     938          539893 : }
     939                 : 
     940                 : 
     941                 : void
     942           40973 : probe::collect_derivation_chain (std::vector<probe*> &probes_list)
     943                 : {
     944           40973 :   probes_list.push_back(this);
     945           40973 : }
     946                 : 
     947                 : 
     948         1108035 : void probe_point::print (ostream& o) const
     949                 : {
     950         3891747 :   for (unsigned i=0; i<components.size(); i++)
     951                 :     {
     952         2783712 :       if (i>0) o << ".";
     953         2783712 :       probe_point::component* c = components[i];
     954         2783712 :       o << c->functor;
     955         2783712 :       if (c->arg)
     956         1741887 :         o << "(" << *c->arg << ")";
     957                 :     }
     958         1108035 :   if (sufficient)
     959              83 :     o << "!";
     960         1107952 :   else if (optional) // sufficient implies optional
     961          163432 :     o << "?";
     962         1108035 :   if (condition)
     963              65 :     o<< " if (" << *condition << ")";
     964         1108035 : }
     965                 : 
     966               0 : string probe_point::str ()
     967                 : {
     968               0 :   ostringstream o;
     969               0 :   for (unsigned i=0; i<components.size(); i++)
     970                 :     {
     971               0 :       if (i>0) o << ".";
     972               0 :       probe_point::component* c = components[i];
     973               0 :       o << c->functor;
     974               0 :       if (c->arg)
     975               0 :         o << "(" << *c->arg << ")";
     976                 :     }
     977               0 :   if (sufficient)
     978               0 :     o << "!";
     979               0 :   else if (optional) // sufficient implies optional
     980               0 :     o << "?";
     981               0 :   if (condition)
     982               0 :     o<< " if (" << *condition << ")";
     983               0 :   return o.str();
     984                 : }
     985                 : 
     986                 : 
     987         1150295 : probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
     988         1150295 :   probe (), alias_names (aliases)
     989                 : {
     990         1150295 : }
     991                 : 
     992            1140 : void probe_alias::printsig (ostream& o) const
     993                 : {
     994            2280 :   for (unsigned i=0; i<alias_names.size(); i++)
     995                 :     {
     996            1140 :       o << (i>0 ? " = " : "");
     997            1140 :       alias_names[i]->print (o);
     998                 :     }
     999            1140 :   o << " = ";
    1000            2918 :   for (unsigned i=0; i<locations.size(); i++)
    1001                 :     {
    1002            1778 :       if (i > 0) o << ", ";
    1003            1778 :       locations[i]->print (o);
    1004                 :     }
    1005            1140 : }
    1006                 : 
    1007                 : 
    1008           18183 : ostream& operator << (ostream& o, const probe_point& k)
    1009                 : {
    1010           18183 :   k.print (o);
    1011           18183 :   return o;
    1012                 : }
    1013                 : 
    1014                 : 
    1015           17071 : ostream& operator << (ostream& o, const symboldecl& k)
    1016                 : {
    1017           17071 :   k.print (o);
    1018           17071 :   return o;
    1019                 : }
    1020                 : 
    1021                 : 
    1022                 : 
    1023                 : // ------------------------------------------------------------------------
    1024                 : // visitors
    1025                 : 
    1026                 : 
    1027                 : void
    1028         7417538 : block::visit (visitor* u)
    1029                 : {
    1030         7417538 :   u->visit_block (this);
    1031         7417531 : }
    1032                 : 
    1033                 : 
    1034                 : void
    1035         2055137 : embeddedcode::visit (visitor* u)
    1036                 : {
    1037         2055137 :   u->visit_embeddedcode (this);
    1038         2055137 : }
    1039                 : 
    1040                 : 
    1041                 : void
    1042            4083 : for_loop::visit (visitor* u)
    1043                 : {
    1044            4083 :   u->visit_for_loop (this);
    1045            4083 : }
    1046                 : 
    1047                 : void
    1048            2538 : foreach_loop::visit (visitor* u)
    1049                 : {
    1050            2538 :   u->visit_foreach_loop (this);
    1051            2538 : }
    1052                 : 
    1053                 : void
    1054         1415791 : null_statement::visit (visitor* u)
    1055                 : {
    1056         1415791 :   u->visit_null_statement (this);
    1057         1415791 : }
    1058                 : 
    1059                 : void
    1060         7939589 : expr_statement::visit (visitor* u)
    1061                 : {
    1062         7939589 :   u->visit_expr_statement (this);
    1063         7939529 : }
    1064                 : 
    1065                 : void
    1066          762967 : return_statement::visit (visitor* u)
    1067                 : {
    1068          762967 :   u->visit_return_statement (this);
    1069          762967 : }
    1070                 : 
    1071                 : void
    1072           14253 : delete_statement::visit (visitor* u)
    1073                 : {
    1074           14253 :   u->push_active_lvalue (this->value);
    1075           14253 :   u->visit_delete_statement (this);
    1076           14253 :   u->pop_active_lvalue ();
    1077           14253 : }
    1078                 : 
    1079                 : void
    1080         3855728 : if_statement::visit (visitor* u)
    1081                 : {
    1082         3855728 :   u->visit_if_statement (this);
    1083         3855726 : }
    1084                 : 
    1085                 : void
    1086           13199 : next_statement::visit (visitor* u)
    1087                 : {
    1088           13199 :   u->visit_next_statement (this);
    1089           13199 : }
    1090                 : 
    1091                 : void
    1092             131 : break_statement::visit (visitor* u)
    1093                 : {
    1094             131 :   u->visit_break_statement (this);
    1095             130 : }
    1096                 : 
    1097                 : void
    1098             138 : continue_statement::visit (visitor* u)
    1099                 : {
    1100             138 :   u->visit_continue_statement (this);
    1101             137 : }
    1102                 : 
    1103                 : void
    1104         1657282 : literal_string::visit(visitor* u)
    1105                 : {
    1106         1657282 :   u->visit_literal_string (this);
    1107         1657282 : }
    1108                 : 
    1109                 : void
    1110         2499287 : literal_number::visit(visitor* u)
    1111                 : {
    1112         2499287 :   u->visit_literal_number (this);
    1113         2499286 : }
    1114                 : 
    1115                 : void
    1116          135152 : binary_expression::visit (visitor* u)
    1117                 : {
    1118          135152 :   u->visit_binary_expression (this);
    1119          135152 : }
    1120                 : 
    1121                 : void
    1122           24261 : unary_expression::visit (visitor* u)
    1123                 : {
    1124           24261 :   u->visit_unary_expression (this);
    1125           24261 : }
    1126                 : 
    1127                 : void
    1128           13018 : pre_crement::visit (visitor* u)
    1129                 : {
    1130           13018 :   u->push_active_lvalue (this->operand);
    1131           13018 :   u->visit_pre_crement (this);
    1132           13018 :   u->pop_active_lvalue ();
    1133           13018 : }
    1134                 : 
    1135                 : void
    1136         1234227 : post_crement::visit (visitor* u)
    1137                 : {
    1138         1234227 :   u->push_active_lvalue (this->operand);
    1139         1234227 :   u->visit_post_crement (this);
    1140         1234227 :   u->pop_active_lvalue ();
    1141         1234227 : }
    1142                 : 
    1143                 : void
    1144            3004 : logical_or_expr::visit (visitor* u)
    1145                 : {
    1146            3004 :   u->visit_logical_or_expr (this);
    1147            3004 : }
    1148                 : 
    1149                 : void
    1150            2447 : logical_and_expr::visit (visitor* u)
    1151                 : {
    1152            2447 :   u->visit_logical_and_expr (this);
    1153            2447 : }
    1154                 : 
    1155                 : void
    1156            2340 : array_in::visit (visitor* u)
    1157                 : {
    1158            2340 :   u->visit_array_in (this);
    1159            2340 : }
    1160                 : 
    1161                 : void
    1162         1785500 : comparison::visit (visitor* u)
    1163                 : {
    1164         1785500 :   u->visit_comparison (this);
    1165         1785497 : }
    1166                 : 
    1167                 : void
    1168           88528 : concatenation::visit (visitor* u)
    1169                 : {
    1170           88528 :   u->visit_concatenation (this);
    1171           88528 : }
    1172                 : 
    1173                 : void
    1174            1870 : ternary_expression::visit (visitor* u)
    1175                 : {
    1176            1870 :   u->visit_ternary_expression (this);
    1177            1870 : }
    1178                 : 
    1179                 : void
    1180         4095831 : assignment::visit (visitor* u)
    1181                 : {
    1182         4095831 :   u->push_active_lvalue (this->left);
    1183         4095831 :   u->visit_assignment (this);
    1184         4095787 :   u->pop_active_lvalue ();
    1185         4095787 : }
    1186                 : 
    1187                 : void
    1188        12904638 : symbol::visit (visitor* u)
    1189                 : {
    1190        12904638 :   u->visit_symbol (this);
    1191        12904637 : }
    1192                 : 
    1193                 : void 
    1194          328566 : target_symbol::visit (visitor* u)
    1195                 : {
    1196          328566 :   u->visit_target_symbol(this);
    1197          328506 : }
    1198                 : 
    1199                 : void
    1200         1310557 : arrayindex::visit (visitor* u)
    1201                 : {
    1202         1310557 :   u->visit_arrayindex (this);
    1203         1310557 : }
    1204                 : 
    1205                 : void
    1206         5560535 : functioncall::visit (visitor* u)
    1207                 : {
    1208         5560535 :   u->visit_functioncall (this);
    1209         5560533 : }
    1210                 : 
    1211                 : void
    1212         3025646 : print_format::visit (visitor *u)
    1213                 : {
    1214         3025646 :   u->visit_print_format (this);
    1215         3025632 : }
    1216                 : 
    1217                 : void
    1218            4312 : stat_op::visit (visitor *u)
    1219                 : {
    1220            4312 :   u->visit_stat_op (this);
    1221            4311 : }
    1222                 : 
    1223                 : void
    1224            1884 : hist_op::visit (visitor *u)
    1225                 : {
    1226            1884 :   u->visit_hist_op (this);
    1227            1884 : }
    1228                 : 
    1229                 : void 
    1230           60349 : indexable::print_indexable (std::ostream& o) const
    1231                 : {
    1232                 :   const symbol *sym;
    1233                 :   const hist_op *hist;
    1234           60349 :   classify_const_indexable(this, sym, hist);
    1235           60349 :   if (sym)
    1236           60258 :     sym->print (o);
    1237                 :   else
    1238                 :     {
    1239              91 :       assert (hist);
    1240              91 :       hist->print (o);
    1241                 :     }  
    1242           60349 : }
    1243                 : 
    1244                 : void 
    1245            5285 : indexable::visit_indexable (visitor* u)
    1246                 : {
    1247                 :   symbol *sym;
    1248                 :   hist_op *hist;
    1249            5285 :   classify_indexable(this, sym, hist);
    1250            5285 :   if (sym)
    1251            5285 :     sym->visit (u);
    1252                 :   else
    1253                 :     {
    1254               0 :       assert (hist);
    1255               0 :       hist->visit (u);
    1256                 :     }
    1257            5285 : }
    1258                 : 
    1259                 : 
    1260                 : bool 
    1261             574 : indexable::is_symbol(symbol *& sym_out)
    1262                 : {
    1263             574 :   sym_out = NULL;
    1264             574 :   return false;
    1265                 : }
    1266                 : 
    1267                 : bool 
    1268               0 : indexable::is_hist_op(hist_op *& hist_out)
    1269                 : {
    1270               0 :   hist_out = NULL;
    1271               0 :   return false;
    1272                 : }
    1273                 : 
    1274                 : bool 
    1275              91 : indexable::is_const_symbol(const symbol *& sym_out) const
    1276                 : {
    1277              91 :   sym_out = NULL;
    1278              91 :   return false;
    1279                 : }
    1280                 : 
    1281                 : bool 
    1282               0 : indexable::is_const_hist_op(const hist_op *& hist_out) const
    1283                 : {
    1284               0 :   hist_out = NULL;
    1285               0 :   return false;
    1286                 : }
    1287                 : 
    1288                 : bool 
    1289         1771884 : symbol::is_symbol(symbol *& sym_out)
    1290                 : {
    1291         1771884 :   sym_out = this;
    1292         1771884 :   return true;
    1293                 : }
    1294                 : 
    1295                 : bool 
    1296           60258 : symbol::is_const_symbol(const symbol *& sym_out) const
    1297                 : {
    1298           60258 :   sym_out = this;
    1299           60258 :   return true;
    1300                 : }
    1301                 : 
    1302                 : const token *
    1303           14151 : symbol::get_tok() const
    1304                 : {
    1305           14151 :   return tok;
    1306                 : }
    1307                 : 
    1308                 : bool 
    1309             574 : hist_op::is_hist_op(hist_op *& hist_out)
    1310                 : {
    1311             574 :   hist_out = this;
    1312             574 :   return true;
    1313                 : }
    1314                 : 
    1315                 : bool 
    1316              91 : hist_op::is_const_hist_op(const hist_op *& hist_out) const
    1317                 : {
    1318              91 :   hist_out = this;
    1319              91 :   return true;
    1320                 : }
    1321                 : 
    1322                 : const token *
    1323               3 : hist_op::get_tok() const
    1324                 : {
    1325               3 :   return tok;
    1326                 : }
    1327                 : 
    1328                 : void
    1329                 : classify_indexable(indexable* ix,
    1330                 :                    symbol *& array_out,
    1331         1772416 :                    hist_op *& hist_out) 
    1332                 : {
    1333         1772416 :   array_out = NULL;
    1334         1772416 :   hist_out = NULL;
    1335         1772416 :   if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
    1336               0 :     throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
    1337         1772416 :   if (ix && !(hist_out || array_out))
    1338               0 :     throw semantic_error("Failed to classify indexable", ix->get_tok());
    1339         1772416 : }
    1340                 : 
    1341                 : void
    1342                 : classify_const_indexable(const indexable* ix,
    1343                 :                          const symbol *& array_out,
    1344           60349 :                          const hist_op *& hist_out) 
    1345                 : {
    1346           60349 :   array_out = NULL;
    1347           60349 :   hist_out = NULL;
    1348           60349 :   if (!(ix->is_const_symbol(array_out) || ix->is_const_hist_op(hist_out)))
    1349               0 :     throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
    1350           60349 : }
    1351                 : 
    1352                 : // ------------------------------------------------------------------------
    1353                 : 
    1354                 : bool 
    1355          164773 : visitor::is_active_lvalue(expression *e)
    1356                 : {
    1357          280578 :   for (unsigned i = 0; i < active_lvalues.size(); ++i)
    1358                 :     {
    1359          119631 :       if (active_lvalues[i] == e)
    1360            3826 :         return true;
    1361                 :     }
    1362          160947 :   return false;
    1363                 : }
    1364                 : 
    1365                 : void 
    1366         5357329 : visitor::push_active_lvalue(expression *e)
    1367                 : {
    1368         5357329 :   active_lvalues.push_back(e);
    1369         5357329 : }
    1370                 : 
    1371                 : void 
    1372         5357285 : visitor::pop_active_lvalue()
    1373                 : {
    1374         5357285 :   assert(!active_lvalues.empty());
    1375         5357285 :   active_lvalues.pop_back();
    1376         5357285 : }
    1377                 : 
    1378                 : 
    1379                 : 
    1380                 : // ------------------------------------------------------------------------
    1381                 : 
    1382                 : void
    1383         4131178 : traversing_visitor::visit_block (block* s)
    1384                 : {
    1385        10391987 :   for (unsigned i=0; i<s->statements.size(); i++)
    1386         6260810 :     s->statements[i]->visit (this);
    1387         4131177 : }
    1388                 : 
    1389                 : void
    1390          837965 : traversing_visitor::visit_embeddedcode (embeddedcode*)
    1391                 : {
    1392          837965 : }
    1393                 : 
    1394                 : void
    1395         1100518 : traversing_visitor::visit_null_statement (null_statement*)
    1396                 : {
    1397         1100518 : }
    1398                 : 
    1399                 : void
    1400         3914414 : traversing_visitor::visit_expr_statement (expr_statement* s)
    1401                 : {
    1402         3914414 :   s->value->visit (this);
    1403         3914413 : }
    1404                 : 
    1405                 : void
    1406         2469445 : traversing_visitor::visit_if_statement (if_statement* s)
    1407                 : {
    1408         2469445 :   s->condition->visit (this);
    1409         2469445 :   s->thenblock->visit (this);
    1410         2469445 :   if (s->elseblock)
    1411          400843 :     s->elseblock->visit (this);
    1412         2469445 : }
    1413                 : 
    1414                 : void
    1415            2587 : traversing_visitor::visit_for_loop (for_loop* s)
    1416                 : {
    1417            2587 :   if (s->init) s->init->visit (this);
    1418            2587 :   s->cond->visit (this);
    1419            2587 :   if (s->incr) s->incr->visit (this);
    1420            2587 :   s->block->visit (this);
    1421            2587 : }
    1422                 : 
    1423                 : void
    1424            1395 : traversing_visitor::visit_foreach_loop (foreach_loop* s)
    1425                 : {
    1426            1395 :   symbol *array = NULL;  
    1427            1395 :   hist_op *hist = NULL;
    1428            1395 :   classify_indexable (s->base, array, hist);
    1429            1395 :   if (array)
    1430            1335 :     array->visit(this);
    1431                 :   else
    1432              60 :     hist->visit(this);
    1433                 : 
    1434            3111 :   for (unsigned i=0; i<s->indexes.size(); i++)
    1435            1716 :     s->indexes[i]->visit (this);
    1436                 : 
    1437            1395 :   if (s->limit)
    1438             206 :     s->limit->visit (this);
    1439                 : 
    1440            1395 :   s->block->visit (this);
    1441            1395 : }
    1442                 : 
    1443                 : void
    1444          676890 : traversing_visitor::visit_return_statement (return_statement* s)
    1445                 : {
    1446          676890 :   s->value->visit (this);
    1447          676890 : }
    1448                 : 
    1449                 : void
    1450           10039 : traversing_visitor::visit_delete_statement (delete_statement* s)
    1451                 : {
    1452           10039 :   s->value->visit (this);
    1453           10039 : }
    1454                 : 
    1455                 : void
    1456            9194 : traversing_visitor::visit_next_statement (next_statement*)
    1457                 : {
    1458            9194 : }
    1459                 : 
    1460                 : void
    1461             100 : traversing_visitor::visit_break_statement (break_statement*)
    1462                 : {
    1463             100 : }
    1464                 : 
    1465                 : void
    1466             109 : traversing_visitor::visit_continue_statement (continue_statement*)
    1467                 : {
    1468             109 : }
    1469                 : 
    1470                 : void
    1471         1294788 : traversing_visitor::visit_literal_string (literal_string*)
    1472                 : {
    1473         1294788 : }
    1474                 : 
    1475                 : void
    1476         1857395 : traversing_visitor::visit_literal_number (literal_number*)
    1477                 : {
    1478         1857395 : }
    1479                 : 
    1480                 : void
    1481          111659 : traversing_visitor::visit_binary_expression (binary_expression* e)
    1482                 : {
    1483          111659 :   e->left->visit (this);
    1484          111659 :   e->right->visit (this);
    1485          111659 : }
    1486                 : 
    1487                 : void
    1488           18769 : traversing_visitor::visit_unary_expression (unary_expression* e)
    1489                 : {
    1490           18769 :   e->operand->visit (this);
    1491           18769 : }
    1492                 : 
    1493                 : void
    1494            9053 : traversing_visitor::visit_pre_crement (pre_crement* e)
    1495                 : {
    1496            9053 :   e->operand->visit (this);
    1497            9053 : }
    1498                 : 
    1499                 : void
    1500          880680 : traversing_visitor::visit_post_crement (post_crement* e)
    1501                 : {
    1502          880680 :   e->operand->visit (this);
    1503          880680 : }
    1504                 : 
    1505                 : 
    1506                 : void
    1507            2750 : traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
    1508                 : {
    1509            2750 :   e->left->visit (this);
    1510            2750 :   e->right->visit (this);
    1511            2750 : }
    1512                 : 
    1513                 : void
    1514            1728 : traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
    1515                 : {
    1516            1728 :   e->left->visit (this);
    1517            1728 :   e->right->visit (this);
    1518            1728 : }
    1519                 : 
    1520                 : void
    1521            1902 : traversing_visitor::visit_array_in (array_in* e)
    1522                 : {
    1523            1902 :   e->operand->visit (this);
    1524            1902 : }
    1525                 : 
    1526                 : void
    1527         1336354 : traversing_visitor::visit_comparison (comparison* e)
    1528                 : {
    1529         1336354 :   e->left->visit (this);
    1530         1336353 :   e->right->visit (this);
    1531         1336353 : }
    1532                 : 
    1533                 : void
    1534           75166 : traversing_visitor::visit_concatenation (concatenation* e)
    1535                 : {
    1536           75166 :   e->left->visit (this);
    1537           75166 :   e->right->visit (this);
    1538           75166 : }
    1539                 : 
    1540                 : void
    1541            1628 : traversing_visitor::visit_ternary_expression (ternary_expression* e)
    1542                 : {
    1543            1628 :   e->cond->visit (this);
    1544            1628 :   e->truevalue->visit (this);
    1545            1628 :   e->falsevalue->visit (this);
    1546            1628 : }
    1547                 : 
    1548                 : void
    1549         2455323 : traversing_visitor::visit_assignment (assignment* e)
    1550                 : {
    1551         2455323 :   e->left->visit (this);
    1552         2455323 :   e->right->visit (this);
    1553         2455323 : }
    1554                 : 
    1555                 : void
    1556         3907822 : traversing_visitor::visit_symbol (symbol*)
    1557                 : {
    1558         3907822 : }
    1559                 : 
    1560                 : void
    1561             214 : traversing_visitor::visit_target_symbol (target_symbol*)
    1562                 : {
    1563             214 : }
    1564                 : 
    1565                 : void
    1566          883674 : traversing_visitor::visit_arrayindex (arrayindex* e)
    1567                 : {
    1568         1778514 :   for (unsigned i=0; i<e->indexes.size(); i++)
    1569          894840 :     e->indexes[i]->visit (this);
    1570                 : 
    1571          883674 :   symbol *array = NULL;
    1572          883674 :   hist_op *hist = NULL;
    1573          883674 :   classify_indexable(e->base, array, hist);
    1574          883674 :   if (array)
    1575          883464 :     return array->visit(this);
    1576                 :   else
    1577             210 :     return hist->visit(this);
    1578                 : }
    1579                 : 
    1580                 : void
    1581         3762263 : traversing_visitor::visit_functioncall (functioncall* e)
    1582                 : {
    1583         4566718 :   for (unsigned i=0; i<e->args.size(); i++)
    1584          804455 :     e->args[i]->visit (this);
    1585         3762263 : }
    1586                 : 
    1587                 : void
    1588         2150738 : traversing_visitor::visit_print_format (print_format* e)
    1589                 : {
    1590         6256715 :   for (unsigned i=0; i<e->args.size(); i++)
    1591         4105978 :     e->args[i]->visit (this);
    1592         2150737 :   if (e->hist)
    1593            1134 :     e->hist->visit(this);
    1594         2150737 : }
    1595                 : 
    1596                 : void
    1597            2636 : traversing_visitor::visit_stat_op (stat_op* e)
    1598                 : {
    1599            2636 :   e->stat->visit (this);
    1600            2636 : }
    1601                 : 
    1602                 : void
    1603            1317 : traversing_visitor::visit_hist_op (hist_op* e)
    1604                 : {
    1605            1317 :   e->stat->visit (this);
    1606            1317 : }
    1607                 : 
    1608                 : 
    1609                 : void
    1610         2938824 : functioncall_traversing_visitor::visit_functioncall (functioncall* e) 
    1611                 : {
    1612         2938824 :   traversing_visitor::visit_functioncall (e);
    1613                 : 
    1614                 :   // prevent infinite recursion
    1615         2938824 :   if (traversed.find (e->referent) == traversed.end ())
    1616                 :     {
    1617         1318450 :       traversed.insert (e->referent);
    1618                 :       // recurse
    1619         1318450 :       functiondecl* last_current_function = current_function;
    1620         1318450 :       current_function = e->referent;
    1621         1318450 :       e->referent->body->visit (this);
    1622         1318450 :       current_function = last_current_function;
    1623                 :     }
    1624         2938824 : }
    1625                 : 
    1626                 : 
    1627                 : void
    1628          956687 : varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
    1629                 : {
    1630                 :   // We want to elide embedded-C functions when possible.  For
    1631                 :   // example, each $target variable access is expanded to an
    1632                 :   // embedded-C function call.  Yet, for safety reasons, we should
    1633                 :   // presume that embedded-C functions have intentional side-effects.
    1634                 :   //
    1635                 :   // To tell these two types of functions apart, we apply a
    1636                 :   // Kludge(tm): we look for a magic string within the function body.
    1637                 :   // $target variables as rvalues will have this; lvalues won't.
    1638                 :   // Also, explicit side-effect-free tapset functions will have this.
    1639                 :   
    1640          956687 :   assert (current_function); // only they get embedded code
    1641          956687 :   if (s->code.find ("/* pure */") != string::npos)
    1642          948847 :     return;
    1643                 : 
    1644            7840 :   embedded_seen = true;
    1645                 : }
    1646                 : 
    1647                 : void
    1648             299 : varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
    1649                 : {
    1650                 :   // Still-unresolved target symbol assignments get treated as
    1651                 :   // generating side-effects like embedded-C, to prevent premature
    1652                 :   // elision and later error message suppression (PR5516).  rvalue use
    1653                 :   // of unresolved target symbols is OTOH not considered a side-effect.
    1654                 : 
    1655             299 :   if (is_active_lvalue (e))
    1656               3 :     embedded_seen = true;
    1657             299 : }
    1658                 : 
    1659                 : void
    1660         1055915 : varuse_collecting_visitor::visit_print_format (print_format* e)
    1661                 : {
    1662                 :   // NB: Instead of being top-level statements, "print" and "printf"
    1663                 :   // are implemented as statement-expressions containing a
    1664                 :   // print_format.  They have side-effects, but not via the
    1665                 :   // embedded-code detection method above. 
    1666                 :   //
    1667                 :   // But sprint and sprintf don't have side-effects.
    1668                 : 
    1669         1055915 :   if (e->print_to_stream)
    1670          836027 :     embedded_seen = true; // a proxy for "has unknown side-effects"
    1671                 : 
    1672         1055915 :   functioncall_traversing_visitor::visit_print_format (e);
    1673         1055915 : }
    1674                 : 
    1675                 : 
    1676                 : void
    1677         1376206 : varuse_collecting_visitor::visit_assignment (assignment *e)
    1678                 : {
    1679         1376206 :   if (e->op == "=" || e->op == "<<<") // pure writes
    1680                 :     {
    1681         1374196 :       expression* last_lvalue = current_lvalue;
    1682         1374196 :       current_lvalue = e->left; // leave a mark for ::visit_symbol
    1683         1374196 :       functioncall_traversing_visitor::visit_assignment (e);
    1684         1374196 :       current_lvalue = last_lvalue;
    1685                 :     }
    1686                 :   else // read-modify-writes
    1687                 :     {
    1688            2010 :       expression* last_lrvalue = current_lrvalue;
    1689            2010 :       current_lrvalue = e->left; // leave a mark for ::visit_symbol
    1690            2010 :       functioncall_traversing_visitor::visit_assignment (e);
    1691            2010 :       current_lrvalue = last_lrvalue;
    1692                 :     }
    1693         1376206 : }
    1694                 : 
    1695                 : void
    1696         4535009 : varuse_collecting_visitor::visit_symbol (symbol *e)
    1697                 : {
    1698         4535009 :   if (e->referent == 0)
    1699               0 :     throw semantic_error ("symbol without referent", e->tok);
    1700                 : 
    1701         4535009 :   if (current_lvalue == e || current_lrvalue == e)
    1702                 :     {
    1703         1804313 :       written.insert (e->referent);
    1704                 :       // clog << "write ";
    1705                 :     }
    1706         4535009 :   if (current_lvalue != e || current_lrvalue == e)
    1707                 :     {
    1708         3160820 :       read.insert (e->referent);
    1709                 :       // clog << "read ";
    1710                 :     }
    1711                 :   // clog << *e->tok << endl;
    1712         4535009 : }
    1713                 : 
    1714                 : // NB: stat_op need not be overridden, since it will get to
    1715                 : // visit_symbol and only as a possible rvalue.
    1716                 : 
    1717                 : 
    1718                 : void
    1719          451974 : varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
    1720                 : {
    1721                 :   // Hooking this callback is necessary because of the hacky
    1722                 :   // statistics representation.  For the expression "i[4] = 5", the
    1723                 :   // incoming lvalue will point to this arrayindex.  However, the
    1724                 :   // symbol corresponding to the "i[4]" is multiply inherited with
    1725                 :   // arrayindex.  If the symbol base part of this object is not at
    1726                 :   // offset 0, then static_cast<symbol*>(e) may result in a different
    1727                 :   // address, and not match lvalue by number when we recurse that way.
    1728                 :   // So we explicitly override the incoming lvalue/lrvalue values to
    1729                 :   // point at the embedded objects' actual base addresses.
    1730                 : 
    1731          451974 :   expression* last_lrvalue = current_lrvalue;
    1732          451974 :   expression* last_lvalue = current_lvalue;
    1733                 : 
    1734          451974 :   symbol *array = NULL;
    1735          451974 :   hist_op *hist = NULL;
    1736          451974 :   classify_indexable(e->base, array, hist);
    1737                 : 
    1738          451974 :   if (array)
    1739                 :     {
    1740          451874 :       if (current_lrvalue == e) current_lrvalue = array;
    1741          451874 :       if (current_lvalue == e) current_lvalue = array;
    1742          451874 :       functioncall_traversing_visitor::visit_arrayindex (e);
    1743                 :     }
    1744                 :   else // if (hist)
    1745                 :     {
    1746             100 :       if (current_lrvalue == e) current_lrvalue = hist->stat;
    1747             100 :       if (current_lvalue == e) current_lvalue = hist->stat;
    1748             100 :       functioncall_traversing_visitor::visit_arrayindex (e);
    1749                 :     }
    1750                 : 
    1751          451974 :   current_lrvalue = last_lrvalue;
    1752          451974 :   current_lvalue = last_lvalue;
    1753          451974 : }
    1754                 : 
    1755                 : 
    1756                 : void
    1757            3933 : varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
    1758                 : {
    1759            3933 :   expression* last_lrvalue = current_lrvalue;
    1760            3933 :   current_lrvalue = e->operand; // leave a mark for ::visit_symbol
    1761            3933 :   functioncall_traversing_visitor::visit_pre_crement (e);
    1762            3933 :   current_lrvalue = last_lrvalue;
    1763            3933 : }
    1764                 : 
    1765                 : void
    1766          419495 : varuse_collecting_visitor::visit_post_crement (post_crement *e)
    1767                 : {
    1768          419495 :   expression* last_lrvalue = current_lrvalue;
    1769          419495 :   current_lrvalue = e->operand; // leave a mark for ::visit_symbol
    1770          419495 :   functioncall_traversing_visitor::visit_post_crement (e);
    1771          419495 :   current_lrvalue = last_lrvalue;
    1772          419495 : }
    1773                 : 
    1774                 : void
    1775             590 : varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
    1776                 : {
    1777             590 :   functioncall_traversing_visitor::visit_foreach_loop (s);
    1778                 :   // If the collection is sorted, imply a "write" access to the
    1779                 :   // array in addition to the "read" one already noted in the
    1780                 :   // base class call above.
    1781             590 :   if (s->sort_direction)
    1782                 :     {
    1783             200 :       symbol *array = NULL;  
    1784             200 :       hist_op *hist = NULL;
    1785             200 :       classify_indexable (s->base, array, hist);
    1786             200 :       if (array) this->written.insert (array->referent);
    1787                 :       // XXX: Can hist_op iterations be sorted?
    1788                 :     }
    1789             590 : }
    1790                 : 
    1791                 : 
    1792                 : void
    1793            4686 : varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
    1794                 : {
    1795                 :   // Ideally, this would be treated like an assignment: a plain write
    1796                 :   // to the underlying value ("lvalue").  XXX: However, the
    1797                 :   // optimization pass is not smart enough to remove an unneeded
    1798                 :   // "delete" yet, so we pose more like a *crement ("lrvalue").  This
    1799                 :   // should protect the underlying value from optimizional mischief.
    1800            4686 :   expression* last_lrvalue = current_lrvalue;
    1801            4686 :   current_lrvalue = s->value; // leave a mark for ::visit_symbol
    1802            4686 :   functioncall_traversing_visitor::visit_delete_statement (s);
    1803            4686 :   current_lrvalue = last_lrvalue;
    1804            4686 : }
    1805                 : 
    1806                 : bool
    1807           78285 : varuse_collecting_visitor::side_effect_free ()
    1808                 : {
    1809           78285 :   return (written.empty() && !embedded_seen);
    1810                 : }
    1811                 : 
    1812                 : 
    1813                 : bool
    1814          891457 : varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
    1815                 : {
    1816                 :   // A looser notion of side-effect-freeness with respect to a given
    1817                 :   // list of variables.
    1818                 : 
    1819                 :   // That's useful because the written list may consist of local
    1820                 :   // variables of called functions.  But visible side-effects only
    1821                 :   // occur if the client's locals, or any globals are written-to.
    1822                 : 
    1823          891457 :   set<vardecl*> intersection;
    1824          891457 :   insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
    1825                 :   set_intersection (written.begin(), written.end(),
    1826                 :                     vars.begin(), vars.end(),
    1827          891457 :                     int_it);
    1828                 : 
    1829          891457 :   return (intersection.empty() && !embedded_seen);
    1830                 : }
    1831                 : 
    1832                 : 
    1833                 : 
    1834                 : 
    1835                 : // ------------------------------------------------------------------------
    1836                 : 
    1837                 : 
    1838            9056 : throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
    1839          474942 : throwing_visitor::throwing_visitor (): msg ("invalid element") {}
    1840                 : 
    1841                 : 
    1842                 : void
    1843               0 : throwing_visitor::throwone (const token* t)
    1844                 : {
    1845               0 :   throw semantic_error (msg, t);
    1846                 : }
    1847                 : 
    1848                 : void
    1849               0 : throwing_visitor::visit_block (block* s)
    1850                 : {
    1851               0 :   throwone (s->tok);
    1852               0 : }
    1853                 : 
    1854                 : void
    1855               0 : throwing_visitor::visit_embeddedcode (embeddedcode* s)
    1856                 : {
    1857               0 :   throwone (s->tok);
    1858               0 : }
    1859                 : 
    1860                 : void
    1861               0 : throwing_visitor::visit_null_statement (null_statement* s)
    1862                 : {
    1863               0 :   throwone (s->tok);
    1864               0 : }
    1865                 : 
    1866                 : void
    1867               0 : throwing_visitor::visit_expr_statement (expr_statement* s)
    1868                 : {
    1869               0 :   throwone (s->tok);
    1870               0 : }
    1871                 : 
    1872                 : void
    1873               0 : throwing_visitor::visit_if_statement (if_statement* s)
    1874                 : {
    1875               0 :   throwone (s->tok);
    1876               0 : }
    1877                 : 
    1878                 : void
    1879               0 : throwing_visitor::visit_for_loop (for_loop* s)
    1880                 : {
    1881               0 :   throwone (s->tok);
    1882               0 : }
    1883                 : 
    1884                 : void
    1885               0 : throwing_visitor::visit_foreach_loop (foreach_loop* s)
    1886                 : {
    1887               0 :   throwone (s->tok);
    1888               0 : }
    1889                 : 
    1890                 : void
    1891               0 : throwing_visitor::visit_return_statement (return_statement* s)
    1892                 : {
    1893               0 :   throwone (s->tok);
    1894               0 : }
    1895                 : 
    1896                 : void
    1897               0 : throwing_visitor::visit_delete_statement (delete_statement* s)
    1898                 : {
    1899               0 :   throwone (s->tok);
    1900               0 : }
    1901                 : 
    1902                 : void
    1903               0 : throwing_visitor::visit_next_statement (next_statement* s)
    1904                 : {
    1905               0 :   throwone (s->tok);
    1906               0 : }
    1907                 : 
    1908                 : void
    1909               0 : throwing_visitor::visit_break_statement (break_statement* s)
    1910                 : {
    1911               0 :   throwone (s->tok);
    1912               0 : }
    1913                 : 
    1914                 : void
    1915               0 : throwing_visitor::visit_continue_statement (continue_statement* s)
    1916                 : {
    1917               0 :   throwone (s->tok);
    1918               0 : }
    1919                 : 
    1920                 : void
    1921               0 : throwing_visitor::visit_literal_string (literal_string* e)
    1922                 : {
    1923               0 :   throwone (e->tok);
    1924               0 : }
    1925                 : 
    1926                 : void
    1927               1 : throwing_visitor::visit_literal_number (literal_number* e)
    1928                 : {
    1929               1 :   throwone (e->tok);
    1930               0 : }
    1931                 : 
    1932                 : void
    1933               0 : throwing_visitor::visit_binary_expression (binary_expression* e)
    1934                 : {
    1935               0 :   throwone (e->tok);
    1936               0 : }
    1937                 : 
    1938                 : void
    1939               0 : throwing_visitor::visit_unary_expression (unary_expression* e)
    1940                 : {
    1941               0 :   throwone (e->tok);
    1942               0 : }
    1943                 : 
    1944                 : void
    1945               0 : throwing_visitor::visit_pre_crement (pre_crement* e)
    1946                 : {
    1947               0 :   throwone (e->tok);
    1948               0 : }
    1949                 : 
    1950                 : void
    1951               0 : throwing_visitor::visit_post_crement (post_crement* e)
    1952                 : {
    1953               0 :   throwone (e->tok);
    1954               0 : }
    1955                 : 
    1956                 : 
    1957                 : void
    1958               0 : throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
    1959                 : {
    1960               0 :   throwone (e->tok);
    1961               0 : }
    1962                 : 
    1963                 : void
    1964               0 : throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
    1965                 : {
    1966               0 :   throwone (e->tok);
    1967               0 : }
    1968                 : 
    1969                 : void
    1970               0 : throwing_visitor::visit_array_in (array_in* e)
    1971                 : {
    1972               0 :   throwone (e->tok);
    1973               0 : }
    1974                 : 
    1975                 : void
    1976               0 : throwing_visitor::visit_comparison (comparison* e)
    1977                 : {
    1978               0 :   throwone (e->tok);
    1979               0 : }
    1980                 : 
    1981                 : void
    1982               0 : throwing_visitor::visit_concatenation (concatenation* e)
    1983                 : {
    1984               0 :   throwone (e->tok);
    1985               0 : }
    1986                 : 
    1987                 : void
    1988               0 : throwing_visitor::visit_ternary_expression (ternary_expression* e)
    1989                 : {
    1990               0 :   throwone (e->tok);
    1991               0 : }
    1992                 : 
    1993                 : void
    1994               0 : throwing_visitor::visit_assignment (assignment* e)
    1995                 : {
    1996               0 :   throwone (e->tok);
    1997               0 : }
    1998                 : 
    1999                 : void
    2000               0 : throwing_visitor::visit_symbol (symbol* e)
    2001                 : {
    2002               0 :   throwone (e->tok);
    2003               0 : }
    2004                 : 
    2005                 : void
    2006               0 : throwing_visitor::visit_target_symbol (target_symbol* e)
    2007                 : {
    2008               0 :   throwone (e->tok);
    2009               0 : }
    2010                 : 
    2011                 : void
    2012               0 : throwing_visitor::visit_arrayindex (arrayindex* e)
    2013                 : {
    2014               0 :   throwone (e->tok);
    2015               0 : }
    2016                 : 
    2017                 : void
    2018               0 : throwing_visitor::visit_functioncall (functioncall* e)
    2019                 : {
    2020               0 :   throwone (e->tok);
    2021               0 : }
    2022                 : 
    2023                 : void
    2024               0 : throwing_visitor::visit_print_format (print_format* e)
    2025                 : {
    2026               0 :   throwone (e->tok);
    2027               0 : }
    2028                 : 
    2029                 : void
    2030               0 : throwing_visitor::visit_stat_op (stat_op* e)
    2031                 : {
    2032               0 :   throwone (e->tok);
    2033               0 : }
    2034                 : 
    2035                 : void
    2036               0 : throwing_visitor::visit_hist_op (hist_op* e)
    2037                 : {
    2038               0 :   throwone (e->tok);
    2039               0 : }
    2040                 : 
    2041                 : 
    2042                 : // ------------------------------------------------------------------------
    2043                 : 
    2044                 : 
    2045                 : void
    2046         1181993 : deep_copy_visitor::visit_block (block* s)
    2047                 : {
    2048         1181993 :   block* n = new block;
    2049         1181993 :   n->tok = s->tok;
    2050         2227425 :   for (unsigned i = 0; i < s->statements.size(); ++i)
    2051                 :     {
    2052                 :       statement* ns;
    2053         1045437 :       require <statement*> (this, &ns, s->statements[i]);
    2054         1045432 :       n->statements.push_back(ns);
    2055                 :     }
    2056         1181988 :   provide <block*> (this, n);
    2057         1181988 : }
    2058                 : 
    2059                 : void
    2060               0 : deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
    2061                 : {
    2062               0 :   embeddedcode* n = new embeddedcode;
    2063               0 :   n->tok = s->tok;
    2064               0 :   n->code = s->code;
    2065               0 :   provide <embeddedcode*> (this, n);
    2066               0 : }
    2067                 : 
    2068                 : void
    2069            1245 : deep_copy_visitor::visit_null_statement (null_statement* s)
    2070                 : {
    2071            1245 :   null_statement* n = new null_statement;
    2072            1245 :   n->tok = s->tok;
    2073            1245 :   provide <null_statement*> (this, n);
    2074            1245 : }
    2075                 : 
    2076                 : void
    2077         1139893 : deep_copy_visitor::visit_expr_statement (expr_statement* s)
    2078                 : {
    2079         1139893 :   expr_statement* n = new expr_statement;
    2080         1139893 :   n->tok = s->tok;
    2081         1139893 :   require <expression*> (this, &(n->value), s->value);
    2082         1139888 :   provide <expr_statement*> (this, n);
    2083         1139888 : }
    2084                 : 
    2085                 : void
    2086          421819 : deep_copy_visitor::visit_if_statement (if_statement* s)
    2087                 : {
    2088          421819 :   if_statement* n = new if_statement;
    2089          421819 :   n->tok = s->tok;
    2090          421819 :   require <expression*> (this, &(n->condition), s->condition);
    2091          421819 :   require <statement*> (this, &(n->thenblock), s->thenblock);
    2092          421819 :   require <statement*> (this, &(n->elseblock), s->elseblock);
    2093          421819 :   provide <if_statement*> (this, n);
    2094          421819 : }
    2095                 : 
    2096                 : void
    2097             207 : deep_copy_visitor::visit_for_loop (for_loop* s)
    2098                 : {
    2099             207 :   for_loop* n = new for_loop;
    2100             207 :   n->tok = s->tok;
    2101             207 :   require <expr_statement*> (this, &(n->init), s->init);
    2102             207 :   require <expression*> (this, &(n->cond), s->cond);
    2103             207 :   require <expr_statement*> (this, &(n->incr), s->incr);
    2104             207 :   require <statement*> (this, &(n->block), s->block);  
    2105             207 :   provide <for_loop*> (this, n);
    2106             207 : }
    2107                 : 
    2108                 : void
    2109             116 : deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
    2110                 : {
    2111             116 :   foreach_loop* n = new foreach_loop;
    2112             116 :   n->tok = s->tok;
    2113             251 :   for (unsigned i = 0; i < s->indexes.size(); ++i)
    2114                 :     {
    2115                 :       symbol* sym;
    2116             135 :       require <symbol*> (this, &sym, s->indexes[i]);
    2117             135 :       n->indexes.push_back(sym);
    2118                 :     }
    2119                 : 
    2120             116 :   require <indexable*> (this, &(n->base), s->base);
    2121                 : 
    2122             116 :   n->sort_direction = s->sort_direction;
    2123             116 :   n->sort_column = s->sort_column;
    2124             116 :   require <expression*> (this, &(n->limit), s->limit);
    2125                 : 
    2126             116 :   require <statement*> (this, &(n->block), s->block);
    2127             116 :   provide <foreach_loop*> (this, n);
    2128             116 : }
    2129                 : 
    2130                 : void
    2131               0 : deep_copy_visitor::visit_return_statement (return_statement* s)
    2132                 : {
    2133               0 :   return_statement* n = new return_statement;
    2134               0 :   n->tok = s->tok;
    2135               0 :   require <expression*> (this, &(n->value), s->value);
    2136               0 :   provide <return_statement*> (this, n);
    2137               0 : }
    2138                 : 
    2139                 : void
    2140             784 : deep_copy_visitor::visit_delete_statement (delete_statement* s)
    2141                 : {
    2142             784 :   delete_statement* n = new delete_statement;
    2143             784 :   n->tok = s->tok;
    2144             784 :   require <expression*> (this, &(n->value), s->value);
    2145             784 :   provide <delete_statement*> (this, n);
    2146             784 : }
    2147                 : 
    2148                 : void
    2149            1312 : deep_copy_visitor::visit_next_statement (next_statement* s)
    2150                 : {
    2151            1312 :   next_statement* n = new next_statement;
    2152            1312 :   n->tok = s->tok;
    2153            1312 :   provide <next_statement*> (this, n);
    2154            1312 : }
    2155                 : 
    2156                 : void
    2157               6 : deep_copy_visitor::visit_break_statement (break_statement* s)
    2158                 : {
    2159               6 :   break_statement* n = new break_statement;
    2160               6 :   n->tok = s->tok;
    2161               6 :   provide <break_statement*> (this, n);
    2162               6 : }
    2163                 : 
    2164                 : void
    2165               5 : deep_copy_visitor::visit_continue_statement (continue_statement* s)
    2166                 : {
    2167               5 :   continue_statement* n = new continue_statement;
    2168               5 :   n->tok = s->tok;
    2169               5 :   provide <continue_statement*> (this, n);
    2170               5 : }
    2171                 : 
    2172                 : void
    2173          152969 : deep_copy_visitor::visit_literal_string (literal_string* e)
    2174                 : {
    2175          152969 :   literal_string* n = new literal_string(e->value);
    2176          152969 :   n->tok = e->tok;
    2177          152969 :   provide <literal_string*> (this, n);
    2178          152969 : }
    2179                 : 
    2180                 : void
    2181          248006 : deep_copy_visitor::visit_literal_number (literal_number* e)
    2182                 : {
    2183          248006 :   literal_number* n = new literal_number(e->value);
    2184          248006 :   n->tok = e->tok;
    2185          248006 :   provide <literal_number*> (this, n);
    2186          248006 : }
    2187                 : 
    2188                 : void
    2189            2675 : deep_copy_visitor::visit_binary_expression (binary_expression* e)
    2190                 : {
    2191            2675 :   binary_expression* n = new binary_expression;
    2192            2675 :   n->op = e->op;
    2193            2675 :   n->tok = e->tok;
    2194            2675 :   require <expression*> (this, &(n->left), e->left);
    2195            2675 :   require <expression*> (this, &(n->right), e->right);
    2196            2675 :   provide <binary_expression*> (this, n);
    2197            2675 : }
    2198                 : 
    2199                 : void
    2200            1380 : deep_copy_visitor::visit_unary_expression (unary_expression* e)
    2201                 : {
    2202            1380 :   unary_expression* n = new unary_expression;
    2203            1380 :   n->op = e->op;
    2204            1380 :   n->tok = e->tok;
    2205            1380 :   require <expression*> (this, &(n->operand), e->operand);
    2206            1380 :   provide <unary_expression*> (this, n);
    2207            1380 : }
    2208                 : 
    2209                 : void
    2210            1435 : deep_copy_visitor::visit_pre_crement (pre_crement* e)
    2211                 : {
    2212            1435 :   pre_crement* n = new pre_crement;
    2213            1435 :   n->op = e->op;
    2214            1435 :   n->tok = e->tok;
    2215            1435 :   require <expression*> (this, &(n->operand), e->operand);
    2216            1435 :   provide <pre_crement*> (this, n);
    2217            1435 : }
    2218                 : 
    2219                 : void
    2220          168862 : deep_copy_visitor::visit_post_crement (post_crement* e)
    2221                 : {
    2222          168862 :   post_crement* n = new post_crement;
    2223          168862 :   n->op = e->op;
    2224          168862 :   n->tok = e->tok;
    2225          168862 :   require <expression*> (this, &(n->operand), e->operand);
    2226          168862 :   provide <post_crement*> (this, n);
    2227          168862 : }
    2228                 : 
    2229                 : 
    2230                 : void
    2231               3 : deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
    2232                 : {
    2233               3 :   logical_or_expr* n = new logical_or_expr;
    2234               3 :   n->op = e->op;
    2235               3 :   n->tok = e->tok;
    2236               3 :   require <expression*> (this, &(n->left), e->left);
    2237               3 :   require <expression*> (this, &(n->right), e->right);
    2238               3 :   provide <logical_or_expr*> (this, n);
    2239               3 : }
    2240                 : 
    2241                 : void
    2242             263 : deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
    2243                 : {
    2244             263 :   logical_and_expr* n = new logical_and_expr;
    2245             263 :   n->op = e->op;
    2246             263 :   n->tok = e->tok;
    2247             263 :   require <expression*> (this, &(n->left), e->left);
    2248             263 :   require <expression*> (this, &(n->right), e->right);
    2249             263 :   provide <logical_and_expr*> (this, n);
    2250             263 : }
    2251                 : 
    2252                 : void
    2253             108 : deep_copy_visitor::visit_array_in (array_in* e)
    2254                 : {
    2255             108 :   array_in* n = new array_in;
    2256             108 :   n->tok = e->tok;
    2257             108 :   require <arrayindex*> (this, &(n->operand), e->operand);
    2258             108 :   provide <array_in*> (this, n);
    2259             108 : }
    2260                 : 
    2261                 : void
    2262          174927 : deep_copy_visitor::visit_comparison (comparison* e)
    2263                 : {
    2264          174927 :   comparison* n = new comparison;
    2265          174927 :   n->op = e->op;
    2266          174927 :   n->tok = e->tok;
    2267          174927 :   require <expression*> (this, &(n->left), e->left);
    2268          174927 :   require <expression*> (this, &(n->right), e->right);
    2269          174927 :   provide <comparison*> (this, n);
    2270          174927 : }
    2271                 : 
    2272                 : void
    2273             207 : deep_copy_visitor::visit_concatenation (concatenation* e)
    2274                 : {
    2275             207 :   concatenation* n = new concatenation;
    2276             207 :   n->op = e->op;
    2277             207 :   n->tok = e->tok;
    2278             207 :   require <expression*> (this, &(n->left), e->left);
    2279             207 :   require <expression*> (this, &(n->right), e->right);
    2280             207 :   provide <concatenation*> (this, n);
    2281             207 : }
    2282                 : 
    2283                 : void
    2284              71 : deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
    2285                 : {
    2286              71 :   ternary_expression* n = new ternary_expression;
    2287              71 :   n->tok = e->tok;
    2288              71 :   require <expression*> (this, &(n->cond), e->cond);
    2289              71 :   require <expression*> (this, &(n->truevalue), e->truevalue);
    2290              71 :   require <expression*> (this, &(n->falsevalue), e->falsevalue);
    2291              71 :   provide <ternary_expression*> (this, n);
    2292              71 : }
    2293                 : 
    2294                 : void
    2295          419471 : deep_copy_visitor::visit_assignment (assignment* e)
    2296                 : {
    2297          419471 :   assignment* n = new assignment;
    2298          419471 :   n->op = e->op;
    2299          419471 :   n->tok = e->tok;
    2300          419471 :   require <expression*> (this, &(n->left), e->left);
    2301          419471 :   require <expression*> (this, &(n->right), e->right);
    2302          419471 :   provide <assignment*> (this, n);
    2303          419471 : }
    2304                 : 
    2305                 : void
    2306         1757920 : deep_copy_visitor::visit_symbol (symbol* e)
    2307                 : {
    2308         1757920 :   symbol* n = new symbol;
    2309         1757920 :   n->tok = e->tok;
    2310         1757920 :   n->name = e->name;
    2311         1757920 :   n->referent = NULL;
    2312         1757920 :   provide <symbol*> (this, n);
    2313         1757920 : }
    2314                 : 
    2315                 : void
    2316          212503 : deep_copy_visitor::visit_target_symbol (target_symbol* e)
    2317                 : {
    2318          212503 :   target_symbol* n = new target_symbol;
    2319          212503 :   n->tok = e->tok;
    2320          212503 :   n->base_name = e->base_name;
    2321          212503 :   n->components = e->components;
    2322          212503 :   provide <target_symbol*> (this, n);
    2323          212503 : }
    2324                 : 
    2325                 : void
    2326          173276 : deep_copy_visitor::visit_arrayindex (arrayindex* e)
    2327                 : {
    2328          173276 :   arrayindex* n = new arrayindex;
    2329          173276 :   n->tok = e->tok;
    2330                 : 
    2331          173276 :   require <indexable*> (this, &(n->base), e->base);
    2332                 : 
    2333          347583 :   for (unsigned i = 0; i < e->indexes.size(); ++i)
    2334                 :     {
    2335                 :       expression* ne;
    2336          174307 :       require <expression*> (this, &ne, e->indexes[i]);
    2337          174307 :       n->indexes.push_back(ne);
    2338                 :     }
    2339          173276 :   provide <arrayindex*> (this, n);
    2340          173276 : }
    2341                 : 
    2342                 : void
    2343          584677 : deep_copy_visitor::visit_functioncall (functioncall* e)
    2344                 : {
    2345          584677 :   functioncall* n = new functioncall;
    2346          584677 :   n->tok = e->tok;
    2347          584677 :   n->function = e->function;
    2348          584677 :   n->referent = NULL;
    2349          742083 :   for (unsigned i = 0; i < e->args.size(); ++i)
    2350                 :     {
    2351                 :       expression* na;
    2352          157406 :       require <expression*> (this, &na, e->args[i]);
    2353          157406 :       n->args.push_back(na);
    2354                 :     }
    2355          584677 :   provide <functioncall*> (this, n);
    2356          584677 : }
    2357                 : 
    2358                 : void
    2359          404868 : deep_copy_visitor::visit_print_format (print_format* e)
    2360                 : {
    2361          404868 :   print_format* n = new print_format;
    2362          404868 :   n->tok = e->tok;
    2363          404868 :   n->print_to_stream = e->print_to_stream;
    2364          404868 :   n->print_with_format = e->print_with_format;
    2365          404868 :   n->print_with_delim = e->print_with_delim;
    2366          404868 :   n->print_with_newline = e->print_with_newline;
    2367          404868 :   n->print_char = e->print_char;
    2368          404868 :   n->raw_components = e->raw_components;
    2369          404868 :   n->components = e->components;
    2370          404868 :   n->delimiter = e->delimiter;
    2371         1182522 :   for (unsigned i = 0; i < e->args.size(); ++i)
    2372                 :     {
    2373                 :       expression* na;
    2374          777656 :       require <expression*> (this, &na, e->args[i]);
    2375          777654 :       n->args.push_back(na);
    2376                 :     }
    2377          404866 :   if (e->hist)
    2378              87 :     require <hist_op*> (this, &n->hist, e->hist);
    2379          404866 :   provide <print_format*> (this, n);
    2380          404866 : }
    2381                 : 
    2382                 : void
    2383             250 : deep_copy_visitor::visit_stat_op (stat_op* e)
    2384                 : {
    2385             250 :   stat_op* n = new stat_op;
    2386             250 :   n->tok = e->tok;
    2387             250 :   n->ctype = e->ctype;
    2388             250 :   require <expression*> (this, &(n->stat), e->stat);
    2389             250 :   provide <stat_op*> (this, n);
    2390             250 : }
    2391                 : 
    2392                 : void
    2393             112 : deep_copy_visitor::visit_hist_op (hist_op* e)
    2394                 : {
    2395             112 :   hist_op* n = new hist_op;
    2396             112 :   n->tok = e->tok;
    2397             112 :   n->htype = e->htype;
    2398             112 :   n->params = e->params;
    2399             112 :   require <expression*> (this, &(n->stat), e->stat);
    2400             112 :   provide <hist_op*> (this, n);
    2401             112 : }
    2402                 : 
    2403                 : block* 
    2404          529755 : deep_copy_visitor::deep_copy (block* b)
    2405                 : {
    2406                 :   block* n;
    2407          529755 :   deep_copy_visitor v;
    2408          529755 :   require <block*> (&v, &n, b);
    2409          529755 :   return n;
    2410                 : }
    2411                 : 
    2412                 : statement* 
    2413          174188 : deep_copy_visitor::deep_copy (statement* s)
    2414                 : {
    2415                 :   statement* n;
    2416          174188 :   deep_copy_visitor v;
    2417          174188 :   require <statement*> (&v, &n, s);
    2418          174188 :   return n;
    2419                 : }
    2420                 : 
    2421                 : expression*
    2422              10 : deep_copy_visitor::deep_copy (expression* s)
    2423                 : {
    2424                 :   expression* n;
    2425              10 :   deep_copy_visitor v;
    2426              10 :   require <expression*> (&v, &n, s);
    2427              10 :   return n;
    2428                 : }
    2429                 : 
    2430                 : template <> void
    2431          173392 : require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src)
    2432                 : {
    2433          173392 :   if (src != NULL)
    2434                 :     {
    2435          173392 :       symbol *array_src=NULL, *array_dst=NULL;
    2436          173392 :       hist_op *hist_src=NULL, *hist_dst=NULL;
    2437                 : 
    2438          173392 :       classify_indexable(src, array_src, hist_src);
    2439                 : 
    2440          173392 :       *dst = NULL;
    2441                 : 
    2442          173392 :       if (array_src)
    2443                 :         {
    2444          173367 :           require <symbol*> (v, &array_dst, array_src);
    2445          173367 :           *dst = array_dst;
    2446                 :         }
    2447                 :       else
    2448                 :         {
    2449              25 :           require <hist_op*> (v, &hist_dst, hist_src);
    2450              25 :           *dst = hist_dst;
    2451                 :         }
    2452          173392 :       assert (*dst);
    2453                 :     }
    2454          175580 : }
    2455            1094 : 

Generated by: LTP GCOV extension version 1.5