LCOV - code coverage report
Current view: top level - src - Type.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 419 940 44.6 %
Date: 2010-12-13 Functions: 66 155 42.6 %
Branches: 326 1045 31.2 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Type.cc 6916 2009-09-24 20:48:36Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include "Type.h"
       8                 :            : #include "Attr.h"
       9                 :            : #include "Expr.h"
      10                 :            : #include "Scope.h"
      11                 :            : #include "Serializer.h"
      12                 :            : 
      13                 :            : RecordType* init_global_attrs();
      14                 :            : 
      15                 :            : bool in_global_attr_decl = false;
      16                 :          3 : RecordType* global_attributes_type = init_global_attrs();
      17                 :            : 
      18                 :          3 : RecordType* init_global_attrs()
      19                 :            :         {
      20                 :          3 :         in_global_attr_decl = true;
      21                 :          3 :         RecordType* rt = new RecordType(new type_decl_list);
      22                 :          3 :         in_global_attr_decl = false;
      23                 :          3 :         rt->MakeGlobalAttributeType();
      24                 :          3 :         return rt;
      25                 :            :         }
      26                 :            : 
      27                 :         44 : const char* type_name(TypeTag t)
      28                 :            :         {
      29                 :            :         static char errbuf[512];
      30                 :            : 
      31                 :            :         static const char* type_names[int(NUM_TYPES)] = {
      32                 :            :                 "void",
      33                 :            :                 "bool", "int", "count", "counter",
      34                 :            :                 "double", "time", "interval",
      35                 :            :                 "string", "pattern",
      36                 :            :                 "enum",
      37                 :            :                 "timer",
      38                 :            :                 "port", "addr", "net", "subnet",
      39                 :            :                 "any",
      40                 :            :                 "table", "union", "record", "types",
      41                 :            :                 "func",
      42                 :            :                 "file",
      43                 :            :                 "vector",
      44                 :            :                 "error",
      45                 :            :         };
      46                 :            : 
      47         [ -  + ]:         44 :         if ( int(t) >= NUM_TYPES )
      48                 :            :                 {
      49                 :          0 :                 snprintf(errbuf, sizeof(errbuf), "%d: not a type tag", int(t));
      50                 :          0 :                 return errbuf;
      51                 :            :                 }
      52                 :            : 
      53                 :         44 :         return type_names[int(t)];
      54                 :            :         }
      55                 :            : 
      56                 :     164578 : BroType::BroType(TypeTag t, bool arg_base_type)
      57                 :            :         {
      58                 :     164578 :         tag = t;
      59                 :     164578 :         is_network_order = 0;
      60                 :     164578 :         base_type = arg_base_type;
      61                 :     164578 :         is_global_attributes_type = false;
      62                 :            : 
      63 [ +  +  +  +  + :     164578 :         switch ( tag ) {
          +  +  +  +  -  
          -  -  +  -  -  
          -  -  -  -  +  
                   -  - ]
      64                 :            :         case TYPE_VOID:
      65                 :          3 :                 internal_tag = TYPE_INTERNAL_VOID;
      66                 :          3 :                 break;
      67                 :            : 
      68                 :            :         case TYPE_BOOL:
      69                 :            :         case TYPE_INT:
      70                 :            :         case TYPE_ENUM:
      71                 :        108 :                 internal_tag = TYPE_INTERNAL_INT;
      72                 :        108 :                 break;
      73                 :            : 
      74                 :            :         case TYPE_COUNT:
      75                 :            :         case TYPE_COUNTER:
      76                 :          3 :                 internal_tag = TYPE_INTERNAL_UNSIGNED;
      77                 :          3 :                 break;
      78                 :            : 
      79                 :            :         case TYPE_PORT:
      80                 :          3 :                 internal_tag = TYPE_INTERNAL_UNSIGNED;
      81                 :          3 :                 is_network_order = 1;
      82                 :          3 :                 break;
      83                 :            : 
      84                 :            :         case TYPE_DOUBLE:
      85                 :            :         case TYPE_TIME:
      86                 :            :         case TYPE_INTERVAL:
      87                 :          9 :                 internal_tag = TYPE_INTERNAL_DOUBLE;
      88                 :          9 :                 break;
      89                 :            : 
      90                 :            :         case TYPE_STRING:
      91                 :          3 :                 internal_tag = TYPE_INTERNAL_STRING;
      92                 :          3 :                 break;
      93                 :            : 
      94                 :            :         case TYPE_ADDR:
      95                 :            :         case TYPE_NET:
      96                 :          6 :                 internal_tag = TYPE_INTERNAL_ADDR;
      97                 :          6 :                 break;
      98                 :            : 
      99                 :            :         case TYPE_SUBNET:
     100                 :          3 :                 internal_tag = TYPE_INTERNAL_SUBNET;
     101                 :          3 :                 break;
     102                 :            : 
     103                 :            :         case TYPE_PATTERN:
     104                 :            :         case TYPE_TIMER:
     105                 :            :         case TYPE_ANY:
     106                 :            :         case TYPE_TABLE:
     107                 :            :         case TYPE_UNION:
     108                 :            :         case TYPE_RECORD:
     109                 :            :         case TYPE_LIST:
     110                 :            :         case TYPE_FUNC:
     111                 :            :         case TYPE_FILE:
     112                 :            :         case TYPE_VECTOR:
     113                 :     164440 :                 internal_tag = TYPE_INTERNAL_OTHER;
     114                 :     164440 :                 break;
     115                 :            : 
     116                 :            :         case TYPE_ERROR:
     117                 :          0 :                 internal_tag = TYPE_INTERNAL_ERROR;
     118                 :            :                 break;
     119                 :            :         }
     120                 :            : 
     121                 :            :         // Kind of hacky; we don't want an error while we're defining
     122                 :            :         // the global attrs!
     123 [ -  + ][ +  + ]:     164578 :         if ( in_global_attr_decl )
     124                 :            :                 {
     125                 :          3 :                 attributes_type = 0;
     126                 :          3 :                 return;
     127                 :            :                 }
     128                 :            : 
     129 [ -  + ][ -  + ]:     164575 :         if ( ! global_attributes_type )
     130                 :          0 :                 SetError();
     131                 :            :         else
     132                 :     164578 :                 attributes_type = global_attributes_type;
     133                 :            :         }
     134                 :            : 
     135                 :          0 : bool BroType::SetAttributesType(type_decl_list* attr_types)
     136                 :            :         {
     137                 :          0 :         TypeList* global = new TypeList();
     138                 :          0 :         global->Append(global_attributes_type);
     139                 :            : 
     140                 :          0 :         attributes_type = refine_type(global, attr_types)->AsRecordType();
     141                 :            : 
     142                 :          0 :         return (attributes_type != 0);
     143                 :            :         }
     144                 :            : 
     145                 :          0 : int BroType::MatchesIndex(ListExpr*& /* index */) const
     146                 :            :         {
     147                 :          0 :         return DOES_NOT_MATCH_INDEX;
     148                 :            :         }
     149                 :            : 
     150                 :          0 : BroType* BroType::YieldType()
     151                 :            :         {
     152                 :          0 :         return 0;
     153                 :            :         }
     154                 :            : 
     155                 :          0 : int BroType::HasField(const char* /* field */) const
     156                 :            :         {
     157                 :          0 :         return 0;
     158                 :            :         }
     159                 :            : 
     160                 :          0 : BroType* BroType::FieldType(const char* /* field */) const
     161                 :            :         {
     162                 :          0 :         return 0;
     163                 :            :         }
     164                 :            : 
     165                 :          0 : void BroType::Describe(ODesc* d) const
     166                 :            :         {
     167         [ #  # ]:          0 :         if ( d->IsBinary() )
     168                 :          0 :                 d->Add(int(Tag()));
     169                 :            :         else
     170                 :            :                 {
     171                 :          0 :                 TypeTag t = Tag();
     172         [ #  # ]:          0 :                 if ( IsSet() )
     173                 :          0 :                         d->Add("set");
     174                 :            :                 else
     175                 :          0 :                         d->Add(type_name(t));
     176                 :            :                 }
     177                 :          0 :         }
     178                 :            : 
     179                 :          0 : void BroType::SetError()
     180                 :            :         {
     181                 :          0 :         tag = TYPE_ERROR;
     182                 :          0 :         }
     183                 :            : 
     184                 :          0 : unsigned int BroType::MemoryAllocation() const
     185                 :            :         {
     186                 :          0 :         return padded_sizeof(*this);
     187                 :            :         }
     188                 :            : 
     189                 :         52 : bool BroType::Serialize(SerialInfo* info) const
     190                 :            :         {
     191                 :            :         // We always send full types (see below).
     192                 :         52 :         SERIALIZE(true);
     193                 :            : 
     194                 :         52 :         bool ret = SerialObj::Serialize(info);
     195                 :         52 :         return ret;
     196                 :            :         }
     197                 :            : 
     198                 :          0 : BroType* BroType::Unserialize(UnserialInfo* info, TypeTag want)
     199                 :            :         {
     200                 :            :         // To avoid external Broccoli clients needing to always send full type
     201                 :            :         // objects, we allow them to give us only the name of a type. To
     202                 :            :         // differentiate between the two cases, we exchange a flag first.
     203                 :          0 :         bool full_type = true;;
     204         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&full_type) )
     205                 :          0 :                 return 0;
     206                 :            : 
     207         [ #  # ]:          0 :         if ( ! full_type )
     208                 :            :                 {
     209                 :            :                 const char* name;
     210         [ #  # ]:          0 :                 if ( ! UNSERIALIZE_STR(&name, 0) )
     211                 :          0 :                         return 0;
     212                 :            : 
     213                 :          0 :                 ID* id = global_scope()->Lookup(name);
     214         [ #  # ]:          0 :                 if ( ! id )
     215                 :            :                         {
     216                 :          0 :                         info->s->Error(fmt("unknown type %s", name));
     217                 :          0 :                         return 0;
     218                 :            :                         }
     219                 :            : 
     220                 :          0 :                 BroType* t = id->AsType();
     221         [ #  # ]:          0 :                 if ( ! t )
     222                 :            :                         {
     223                 :          0 :                         info->s->Error(fmt("%s is not a type", name));
     224                 :          0 :                         return 0;
     225                 :            :                         }
     226                 :            : 
     227                 :          0 :                 return t->Ref();
     228                 :            :                 }
     229                 :            : 
     230                 :          0 :         BroType* t = (BroType*) SerialObj::Unserialize(info, SER_BRO_TYPE);
     231                 :            : 
     232         [ #  # ]:          0 :         if ( ! t )
     233                 :          0 :                 return 0;
     234                 :            : 
     235                 :            :         // For base types, we return our current instance.
     236         [ #  # ]:          0 :         if ( t->base_type )
     237                 :            :                 {
     238                 :          0 :                 BroType* t2 = ::base_type(TypeTag(t->tag));
     239                 :          0 :                 Unref(t);
     240         [ #  # ]:          0 :                 assert(t2);
     241                 :          0 :                 return t2;
     242                 :            :                 }
     243                 :            : 
     244                 :            :         // For the global_attribute_type, we also return our current instance.
     245         [ #  # ]:          0 :         if ( t->is_global_attributes_type )
     246                 :            :                 {
     247                 :          0 :                 BroType* t2 = global_attributes_type;
     248                 :          0 :                 Unref(t);
     249                 :          0 :                 t2->Ref();
     250         [ #  # ]:          0 :                 assert(t2);
     251                 :          0 :                 return t2;
     252                 :            :                 }
     253                 :            : 
     254         [ #  # ]:          0 :         assert(t);
     255                 :          0 :         return t;
     256                 :            :         }
     257                 :            : 
     258                 :          9 : IMPLEMENT_SERIAL(BroType, SER_BRO_TYPE)
     259                 :            : 
     260                 :         12 : bool BroType::DoSerialize(SerialInfo* info) const
     261                 :            :         {
     262 [ +  + ][ -  + ]:         12 :         DO_SERIALIZE(SER_BRO_TYPE, BroObj);
     263                 :            : 
     264                 :         12 :         info->s->WriteOpenTag("Type");
     265                 :            : 
     266   [ +  -  -  + ]:         12 :         if ( ! (SERIALIZE(char(tag)) && SERIALIZE(char(internal_tag))) )
                 [ -  + ]
     267                 :          0 :                 return false;
     268                 :            : 
     269 [ +  - ][ +  - ]:         12 :         if ( ! (SERIALIZE(is_network_order) && SERIALIZE(base_type) &&
         [ -  + ][ -  + ]
     270                 :            :                 SERIALIZE(is_global_attributes_type)) )
     271                 :          0 :                 return false;
     272                 :            : 
     273 [ +  + ][ +  - ]:         12 :         SERIALIZE_OPTIONAL(attributes_type);
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     274                 :            : 
     275                 :         12 :         info->s->WriteCloseTag("Type");
     276                 :            : 
     277                 :         12 :         return true;
     278                 :            :         }
     279                 :            : 
     280                 :          0 : bool BroType::DoUnserialize(UnserialInfo* info)
     281                 :            :         {
     282         [ #  # ]:          0 :         DO_UNSERIALIZE(BroObj);
     283                 :            : 
     284                 :            :         char c1, c2;
     285 [ #  # ][ #  # ]:          0 :         if ( ! (UNSERIALIZE(&c1) && UNSERIALIZE(&c2) ) )
                 [ #  # ]
     286                 :          0 :                 return 0;
     287                 :            : 
     288                 :          0 :         tag = (TypeTag) c1;
     289                 :          0 :         internal_tag = (InternalTypeTag) c2;
     290                 :            : 
     291 [ #  # ][ #  # ]:          0 :         if ( ! (UNSERIALIZE(&is_network_order) && UNSERIALIZE(&base_type)
         [ #  # ][ #  # ]
     292                 :            :                         && UNSERIALIZE(&is_global_attributes_type)) )
     293                 :          0 :                 return 0;
     294                 :            : 
     295                 :            :         BroType* type;
     296 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(type, BroType::Unserialize(info, TYPE_RECORD));
                 [ #  # ]
     297                 :          0 :         attributes_type = (RecordType*) type;
     298                 :            : 
     299                 :          0 :         return true;
     300                 :            :         }
     301                 :            : 
     302                 :     144772 : TypeList::~TypeList()
     303                 :            :         {
     304 [ +  + ][ #  # ]:     298089 :         loop_over_list(types, i)
                 [ #  # ]
     305                 :     153317 :                 Unref(types[i]);
     306                 :            : 
     307                 :     144772 :         Unref(pure_type);
     308 [ +  - ][ #  # ]:     144772 :         }
                 [ #  # ]
     309                 :            : 
     310                 :       2061 : int TypeList::AllMatch(const BroType* t, int is_init) const
     311                 :            :         {
     312         [ +  + ]:       5027 :         loop_over_list(types, i)
     313         [ +  + ]:       3644 :                 if ( ! same_type(types[i], t, is_init) )
     314                 :        678 :                         return 0;
     315                 :       2061 :         return 1;
     316                 :            :         }
     317                 :            : 
     318                 :     176247 : void TypeList::Append(BroType* t)
     319                 :            :         {
     320 [ +  + ][ -  + ]:     176247 :         if ( pure_type && ! same_type(t, pure_type) )
                 [ -  + ]
     321                 :          0 :                 internal_error("pure type-list violation");
     322                 :            : 
     323                 :     176247 :         types.append(t);
     324                 :     176247 :         }
     325                 :            : 
     326                 :        117 : void TypeList::AppendEvenIfNotPure(BroType* t)
     327                 :            :         {
     328 [ +  + ][ +  + ]:        117 :         if ( pure_type && ! same_type(t, pure_type) )
                 [ +  + ]
     329                 :            :                 {
     330                 :         60 :                 Unref(pure_type);
     331                 :         60 :                 pure_type = 0;
     332                 :            :                 }
     333                 :            : 
     334                 :        117 :         types.append(t);
     335                 :        117 :         }
     336                 :            : 
     337                 :          0 : void TypeList::Describe(ODesc* d) const
     338                 :            :         {
     339         [ #  # ]:          0 :         if ( d->IsReadable() )
     340                 :          0 :                 d->AddSP("list of");
     341                 :            :         else
     342                 :            :                 {
     343                 :          0 :                 d->Add(int(Tag()));
     344                 :          0 :                 d->Add(IsPure());
     345         [ #  # ]:          0 :                 if ( IsPure() )
     346                 :          0 :                         pure_type->Describe(d);
     347                 :          0 :                 d->Add(types.length());
     348                 :            :                 }
     349                 :            : 
     350         [ #  # ]:          0 :         if ( IsPure() )
     351                 :          0 :                 pure_type->Describe(d);
     352                 :            :         else
     353                 :            :                 {
     354         [ #  # ]:          0 :                 loop_over_list(types, i)
     355                 :            :                         {
     356 [ #  # ][ #  # ]:          0 :                         if ( i > 0 && ! d->IsBinary() )
                 [ #  # ]
     357                 :          0 :                                 d->Add(",");
     358                 :            : 
     359                 :          0 :                         types[i]->Describe(d);
     360                 :            :                         }
     361                 :            :                 }
     362                 :          0 :         }
     363                 :            : 
     364                 :          9 : IMPLEMENT_SERIAL(TypeList, SER_TYPE_LIST);
     365                 :            : 
     366                 :          3 : bool TypeList::DoSerialize(SerialInfo* info) const
     367                 :            :         {
     368 [ +  - ][ -  + ]:          3 :         DO_SERIALIZE(SER_TYPE_LIST, BroType);
     369                 :            : 
     370 [ +  + ][ +  - ]:          3 :         SERIALIZE_OPTIONAL(pure_type);
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     371                 :            : 
     372         [ -  + ]:          3 :         if ( ! SERIALIZE(types.length()) )
     373                 :          0 :                 return false;
     374                 :            : 
     375         [ +  + ]:          7 :         loop_over_list(types, j)
     376                 :            :                 {
     377         [ -  + ]:          4 :                 if ( ! types[j]->Serialize(info) )
     378                 :          0 :                         return false;
     379                 :            :                 }
     380                 :            : 
     381                 :          3 :         return true;
     382                 :            :         }
     383                 :            : 
     384                 :          0 : bool TypeList::DoUnserialize(UnserialInfo* info)
     385                 :            :         {
     386         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
     387                 :            : 
     388 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(pure_type, BroType::Unserialize(info));
                 [ #  # ]
     389                 :            : 
     390                 :            :         int len;
     391         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&len) )
     392                 :          0 :                 return false;
     393                 :            : 
     394         [ #  # ]:          0 :         while ( len-- )
     395                 :            :                 {
     396                 :          0 :                 BroType* t = BroType::Unserialize(info);
     397         [ #  # ]:          0 :                 if ( ! t )
     398                 :          0 :                         return false;
     399                 :            : 
     400                 :          0 :                 types.append(t);
     401                 :            :                 }
     402                 :          0 :         return true;
     403                 :            :         }
     404                 :            : 
     405                 :        361 : IndexType::~IndexType()
     406                 :            :         {
     407                 :        361 :         Unref(indices);
     408                 :        361 :         Unref(yield_type);
     409 [ #  # ][ #  # ]:        361 :         }
                 [ -  + ]
     410                 :            : 
     411                 :       1863 : int IndexType::MatchesIndex(ListExpr*& index) const
     412                 :            :         {
     413                 :            :         // If we have a type indexed by subnets, addresses are ok.
     414                 :       1863 :         const type_list* types = indices->Types();
     415                 :       1863 :         const expr_list& exprs = index->Exprs();
     416                 :            : 
     417   [ +  +  +  + ]:       1863 :         if ( types->length() == 1 && (*types)[0]->Tag() == TYPE_SUBNET &&
         [ +  - ][ +  - ]
                 [ +  + ]
     418                 :            :              exprs.length() == 1 && exprs[0]->Type()->Tag() == TYPE_ADDR )
     419                 :          1 :                 return MATCHES_INDEX_SCALAR;
     420                 :            : 
     421                 :            :         return check_and_promote_exprs(index, Indices()) ?
     422         [ +  - ]:       1863 :                         MATCHES_INDEX_SCALAR : DOES_NOT_MATCH_INDEX;
     423                 :            :         }
     424                 :            : 
     425                 :      72966 : BroType* IndexType::YieldType()
     426                 :            :         {
     427                 :      72966 :         return yield_type;
     428                 :            :         }
     429                 :            : 
     430                 :          0 : void IndexType::Describe(ODesc* d) const
     431                 :            :         {
     432                 :          0 :         BroType::Describe(d);
     433         [ #  # ]:          0 :         if ( ! d->IsBinary() )
     434                 :          0 :                 d->Add("[");
     435         [ #  # ]:          0 :         loop_over_list(*IndexTypes(), i)
     436                 :            :                 {
     437 [ #  # ][ #  # ]:          0 :                 if ( ! d->IsBinary() && i > 0 )
                 [ #  # ]
     438                 :          0 :                         d->Add(",");
     439                 :          0 :                 (*IndexTypes())[i]->Describe(d);
     440                 :            :                 }
     441         [ #  # ]:          0 :         if ( ! d->IsBinary() )
     442                 :          0 :                 d->Add("]");
     443                 :            : 
     444         [ #  # ]:          0 :         if ( yield_type )
     445                 :            :                 {
     446         [ #  # ]:          0 :                 if ( ! d->IsBinary() )
     447                 :          0 :                         d->Add(" of ");
     448                 :          0 :                 yield_type->Describe(d);
     449                 :            :                 }
     450                 :          0 :         }
     451                 :            : 
     452                 :      14894 : bool IndexType::IsSubNetIndex() const
     453                 :            :         {
     454                 :      14894 :         const type_list* types = indices->Types();
     455   [ +  +  +  + ]:      14894 :         if ( types->length() == 1 && (*types)[0]->Tag() == TYPE_SUBNET )
                 [ +  + ]
     456                 :         45 :                 return true;
     457                 :      14894 :         return false;
     458                 :            :         }
     459                 :            : 
     460                 :          3 : IMPLEMENT_SERIAL(IndexType, SER_INDEX_TYPE);
     461                 :            : 
     462                 :          2 : bool IndexType::DoSerialize(SerialInfo* info) const
     463                 :            :         {
     464 [ -  + ][ -  + ]:          2 :         DO_SERIALIZE(SER_INDEX_TYPE, BroType);
     465                 :            : 
     466 [ +  - ][ +  - ]:          2 :         SERIALIZE_OPTIONAL(yield_type);
         [ -  + ][ -  + ]
         [ -  + ][ #  # ]
     467                 :          2 :         return indices->Serialize(info);
     468                 :            :         }
     469                 :            : 
     470                 :          0 : bool IndexType::DoUnserialize(UnserialInfo* info)
     471                 :            :         {
     472         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
     473                 :            : 
     474 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(yield_type, BroType::Unserialize(info));
                 [ #  # ]
     475                 :          0 :         indices = (TypeList*) BroType::Unserialize(info, TYPE_LIST);
     476                 :          0 :         return indices != 0;
     477                 :            :         }
     478                 :            : 
     479                 :       1272 : TableType::TableType(TypeList* ind, BroType* yield)
     480                 :       1272 : : IndexType(TYPE_TABLE, ind, yield)
     481                 :            :         {
     482   [ +  -  +  - ]:       1272 :         if ( ! indices )
     483                 :       1272 :                 return;
     484                 :            : 
     485                 :       1272 :         type_list* tl = indices->Types();
     486                 :            : 
     487 [ +  + ][ +  + ]:       2620 :         loop_over_list(*tl, i)
     488                 :            :                 {
     489                 :       1348 :                 BroType* tli = (*tl)[i];
     490                 :       1348 :                 InternalTypeTag t = tli->InternalType();
     491                 :            : 
     492   [ -  +  -  + ]:       1348 :                 if ( t == TYPE_INTERNAL_ERROR )
     493                 :          0 :                         break;
     494                 :            : 
     495                 :            :                 // Allow functions, since they can be compared
     496                 :            :                 // for Func* pointer equality.
     497 [ +  + ][ +  - ]:       1348 :                 if ( t == TYPE_INTERNAL_OTHER && tli->Tag() != TYPE_FUNC &&
         [ -  + ][ -  + ]
         [ +  + ][ +  - ]
         [ -  + ][ -  + ]
     498                 :            :                      tli->Tag() != TYPE_RECORD )
     499                 :            :                         {
     500                 :          0 :                         tli->Error("bad index type");
     501                 :          0 :                         SetError();
     502                 :          0 :                         break;
     503                 :            :                         }
     504                 :            :                 }
     505                 :          0 :         }
     506                 :            : 
     507                 :        120 : bool TableType::IsUnspecifiedTable() const
     508                 :            :         {
     509                 :            :         // Unspecified types have an empty list of indices.
     510                 :        120 :         return indices->Types()->length() == 0;
     511                 :            :         }
     512                 :            : 
     513                 :          0 : TypeList* TableType::ExpandRecordIndex(RecordType* rt) const
     514                 :            :         {
     515                 :          0 :         TypeList* tl = new TypeList();
     516                 :            : 
     517                 :          0 :         int n = rt->NumFields();
     518         [ #  # ]:          0 :         for ( int i = 0; i < n; ++i )
     519                 :            :                 {
     520                 :          0 :                 TypeDecl* td = rt->FieldDecl(i);
     521                 :          0 :                 tl->Append(td->type->Ref());
     522                 :            :                 }
     523                 :            : 
     524                 :          0 :         return tl;
     525                 :            :         }
     526                 :            : 
     527                 :        533 : SetType::SetType(TypeList* ind, ListExpr* arg_elements) : TableType(ind, 0)
     528                 :            :         {
     529                 :        533 :         elements = arg_elements;
     530   [ -  +  #  # ]:        533 :         if ( elements )
     531                 :            :                 {
     532 [ #  # ][ #  # ]:          0 :                 if ( indices )
     533                 :            :                         { // We already have a type.
     534 [ #  # ][ #  # ]:          0 :                         if ( ! check_and_promote_exprs(elements, indices) )
     535                 :          0 :                                 SetError();
     536                 :            :                         }
     537                 :            :                 else
     538                 :            :                         {
     539                 :          0 :                         TypeList* tl_type = elements->Type()->AsTypeList();
     540                 :          0 :                         type_list* tl = tl_type->Types();
     541                 :            : 
     542   [ #  #  #  # ]:          0 :                         if ( tl->length() < 1 )
     543                 :            :                                 {
     544                 :          0 :                                 Error("no type given for set");
     545                 :          0 :                                 SetError();
     546                 :            :                                 }
     547                 :            : 
     548 [ #  # ][ #  # ]:          0 :                         else if ( tl->length() == 1 )
     549                 :            :                                 {
     550                 :          0 :                                 BroType* t = flatten_type((*tl)[0]->Ref());
     551                 :          0 :                                 indices = new TypeList(t);
     552                 :          0 :                                 indices->Append(t->Ref());
     553                 :            :                                 }
     554                 :            : 
     555                 :            :                         else
     556                 :            :                                 {
     557                 :          0 :                                 BroType* t = merge_types((*tl)[0], (*tl)[1]);
     558                 :            : 
     559 [ #  # ][ #  # ]:          0 :                                 for ( int i = 2; t && i < tl->length(); ++i )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     560                 :            :                                         {
     561                 :            :                                         BroType* t_new =
     562                 :          0 :                                                 merge_types(t, (*tl)[i]);
     563                 :          0 :                                         Unref(t);
     564                 :          0 :                                         t = t_new;
     565                 :            :                                         }
     566                 :            : 
     567 [ #  # ][ #  # ]:          0 :                                 if ( ! t )
     568                 :            :                                         {
     569                 :          0 :                                         Error("bad set type");
     570                 :          0 :                                         return;
     571                 :            :                                         }
     572                 :            : 
     573                 :        533 :                                 indices = new TypeList(t);
     574                 :          0 :                                 indices->Append(t);
     575                 :            :                                 }
     576                 :            :                         }
     577                 :            :                 }
     578                 :        533 :         }
     579                 :            : 
     580                 :          7 : IMPLEMENT_SERIAL(TableType, SER_TABLE_TYPE);
     581                 :            : 
     582                 :          2 : bool TableType::DoSerialize(SerialInfo* info) const
     583                 :            :         {
     584 [ +  - ][ -  + ]:          2 :         DO_SERIALIZE(SER_TABLE_TYPE, IndexType);
     585                 :          2 :         return true;
     586                 :            :         }
     587                 :            : 
     588                 :          0 : bool TableType::DoUnserialize(UnserialInfo* info)
     589                 :            :         {
     590         [ #  # ]:          0 :         DO_UNSERIALIZE(IndexType);
     591                 :          0 :         return true;
     592                 :            :         }
     593                 :            : 
     594                 :          0 : SetType::~SetType()
     595                 :            :         {
     596                 :          0 :         Unref(elements);
     597 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
     598                 :            : 
     599                 :          3 : IMPLEMENT_SERIAL(SetType, SER_SET_TYPE);
     600                 :            : 
     601                 :          0 : bool SetType::DoSerialize(SerialInfo* info) const
     602                 :            :         {
     603 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_SET_TYPE, TableType);
     604                 :            : 
     605 [ #  # ][ #  # ]:          0 :         SERIALIZE_OPTIONAL(elements);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     606                 :          0 :         return true;
     607                 :            :         }
     608                 :            : 
     609                 :          0 : bool SetType::DoUnserialize(UnserialInfo* info)
     610                 :            :         {
     611         [ #  # ]:          0 :         DO_UNSERIALIZE(TableType);
     612                 :            : 
     613 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(elements, (ListExpr*) Expr::Unserialize(info, EXPR_LIST));
                 [ #  # ]
     614                 :          0 :         return true;
     615                 :            :         }
     616                 :            : 
     617                 :       2986 : FuncType::FuncType(RecordType* arg_args, BroType* arg_yield, int arg_is_event)
     618                 :       2986 : : BroType(TYPE_FUNC)
     619                 :            :         {
     620                 :       2986 :         args = arg_args;
     621                 :       2986 :         yield = arg_yield;
     622                 :       2986 :         is_event = arg_is_event;
     623                 :            : 
     624                 :       2986 :         arg_types = new TypeList();
     625                 :            : 
     626 [ +  + ][ #  # ]:       9549 :         for ( int i = 0; i < args->NumFields(); ++i )
     627                 :       6563 :                 arg_types->Append(args->FieldType(i)->Ref());
     628                 :       2986 :         }
     629                 :            : 
     630                 :          0 : FuncType::~FuncType()
     631                 :            :         {
     632                 :          0 :         Unref(arg_types);
     633 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
     634                 :            : 
     635                 :     173861 : BroType* FuncType::YieldType()
     636                 :            :         {
     637                 :     173861 :         return yield;
     638                 :            :         }
     639                 :            : 
     640                 :       3585 : int FuncType::MatchesIndex(ListExpr*& index) const
     641                 :            :         {
     642                 :            :         return check_and_promote_exprs(index, arg_types) ?
     643         [ +  - ]:       3585 :                         MATCHES_INDEX_SCALAR : DOES_NOT_MATCH_INDEX;
     644                 :            :         }
     645                 :            : 
     646                 :         15 : int FuncType::CheckArgs(const type_list* args) const
     647                 :            :         {
     648                 :         15 :         const type_list* my_args = arg_types->Types();
     649                 :            : 
     650         [ -  + ]:         15 :         if ( my_args->length() != args->length() )
     651                 :          0 :                 return 0;
     652                 :            : 
     653         [ +  + ]:         30 :         for ( int i = 0; i < my_args->length(); ++i )
     654         [ -  + ]:         15 :                 if ( ! same_type((*args)[i], (*my_args)[i]) )
     655                 :          0 :                         return 0;
     656                 :            : 
     657                 :         15 :         return 1;
     658                 :            :         }
     659                 :            : 
     660                 :          0 : void FuncType::Describe(ODesc* d) const
     661                 :            :         {
     662         [ #  # ]:          0 :         if ( d->IsReadable() )
     663                 :            :                 {
     664         [ #  # ]:          0 :                 d->Add(is_event ? "event" : "function");
     665                 :          0 :                 d->Add("(");
     666                 :          0 :                 args->DescribeFields(d);
     667                 :          0 :                 d->Add(")");
     668                 :            : 
     669         [ #  # ]:          0 :                 if ( yield )
     670                 :            :                         {
     671                 :          0 :                         d->AddSP(" :");
     672                 :          0 :                         yield->Describe(d);
     673                 :            :                         }
     674                 :            :                 }
     675                 :            :         else
     676                 :            :                 {
     677                 :          0 :                 d->Add(int(Tag()));
     678                 :          0 :                 d->Add(is_event);
     679                 :          0 :                 d->Add(yield != 0);
     680                 :          0 :                 args->DescribeFields(d);
     681         [ #  # ]:          0 :                 if ( yield )
     682                 :          0 :                         yield->Describe(d);
     683                 :            :                 }
     684                 :          0 :         }
     685                 :            : 
     686                 :          5 : IMPLEMENT_SERIAL(FuncType, SER_FUNC_TYPE);
     687                 :            : 
     688                 :          1 : bool FuncType::DoSerialize(SerialInfo* info) const
     689                 :            :         {
     690 [ +  - ][ -  + ]:          1 :         DO_SERIALIZE(SER_FUNC_TYPE, BroType);
     691                 :            : 
     692         [ -  + ]:          1 :         assert(args);
     693         [ -  + ]:          1 :         assert(arg_types);
     694                 :            : 
     695 [ +  - ][ +  - ]:          1 :         SERIALIZE_OPTIONAL(yield);
         [ -  + ][ -  + ]
         [ -  + ][ #  # ]
     696                 :            : 
     697                 :            :         return args->Serialize(info) &&
     698                 :            :                 arg_types->Serialize(info) &&
     699 [ +  - ][ +  - ]:          1 :                 SERIALIZE(is_event);
                 [ +  - ]
     700                 :            :         }
     701                 :            : 
     702                 :          0 : bool FuncType::DoUnserialize(UnserialInfo* info)
     703                 :            :         {
     704         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
     705                 :            : 
     706 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(yield, BroType::Unserialize(info));
                 [ #  # ]
     707                 :            : 
     708                 :          0 :         args = (RecordType*) BroType::Unserialize(info, TYPE_RECORD);
     709         [ #  # ]:          0 :         if ( ! args )
     710                 :          0 :                 return false;
     711                 :            : 
     712                 :          0 :         arg_types = (TypeList*) BroType::Unserialize(info, TYPE_LIST);
     713         [ #  # ]:          0 :         if ( ! arg_types )
     714                 :          0 :                 return false;
     715                 :            : 
     716                 :          0 :         return UNSERIALIZE(&is_event);
     717                 :            :         }
     718                 :            : 
     719                 :      10335 : TypeDecl::TypeDecl(BroType* t, const char* i, attr_list* arg_attrs)
     720                 :            :         {
     721                 :      10335 :         type = t;
     722 [ +  + ][ #  # ]:      10335 :         attrs = arg_attrs ? new Attributes(arg_attrs, t) : 0;
     723                 :      10335 :         id = i;
     724                 :            : 
     725 [ -  + ][ #  # ]:      10335 :         if ( in_global_attr_decl && ! attrs->FindAttr(ATTR_DEFAULT) )
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
     726                 :          0 :                 error("global attribute types must have default values");
     727                 :      10335 :         }
     728                 :            : 
     729                 :       1228 : TypeDecl::~TypeDecl()
     730                 :            :         {
     731                 :       1228 :         Unref(type);
     732                 :       1228 :         Unref(attrs);
     733   [ -  +  #  # ]:       1228 :         delete [] id;
     734                 :       1228 :         }
     735                 :            : 
     736                 :          7 : bool TypeDecl::Serialize(SerialInfo* info) const
     737                 :            :         {
     738         [ -  + ]:          7 :         assert(type);
     739         [ -  + ]:          7 :         assert(id);
     740                 :            : 
     741 [ +  + ][ +  - ]:          7 :         SERIALIZE_OPTIONAL(attrs);
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     742                 :            : 
     743 [ +  - ][ +  - ]:          7 :         return type->Serialize(info) && SERIALIZE(id);
     744                 :            :         }
     745                 :            : 
     746                 :          0 : TypeDecl* TypeDecl::Unserialize(UnserialInfo* info)
     747                 :            :         {
     748                 :          0 :         TypeDecl* t = new TypeDecl(0, 0, 0);
     749                 :            : 
     750   [ #  #  #  # ]:          0 :         UNSERIALIZE_OPTIONAL_STATIC(t->attrs, Attributes::Unserialize(info), t);
         [ #  # ][ #  # ]
                 [ #  # ]
     751                 :          0 :         t->type = BroType::Unserialize(info);
     752                 :            : 
     753   [ #  #  #  # ]:          0 :         if ( ! (t->type && UNSERIALIZE_STR(&t->id, 0)) )
                 [ #  # ]
     754                 :            :                 {
     755         [ #  # ]:          0 :                 delete t;
     756                 :          0 :                 return 0;
     757                 :            :                 }
     758                 :            : 
     759                 :          0 :         return t;
     760                 :            :         }
     761                 :            : 
     762                 :          0 : RecordField::RecordField(int arg_base, int arg_offset, int arg_total_offset)
     763                 :            :         {
     764                 :          0 :         base = arg_base;
     765                 :          0 :         offset = arg_offset;
     766                 :          0 :         total_offset = arg_total_offset;
     767                 :          0 :         }
     768                 :            : 
     769                 :       3520 : RecordType::RecordType(type_decl_list* arg_types) : BroType(TYPE_RECORD)
     770                 :            :         {
     771                 :       3520 :         types = arg_types;
     772                 :       3520 :         base = 0;
     773                 :       3520 :         fields = 0;
     774 [ +  - ][ #  # ]:       3520 :         num_fields = types ? types->length() : 0;
     775                 :       3520 :         }
     776                 :            : 
     777                 :          0 : RecordType::RecordType(TypeList* arg_base, type_decl_list* refinements)
     778                 :          0 : : BroType(TYPE_RECORD)
     779                 :            :         {
     780   [ #  #  #  # ]:          0 :         if ( refinements )
     781                 :          0 :                 arg_base->Append(new RecordType(refinements));
     782                 :            : 
     783                 :          0 :         Init(arg_base);
     784                 :          0 :         }
     785                 :            : 
     786                 :          0 : void RecordType::Init(TypeList* arg_base)
     787                 :            :         {
     788                 :          0 :         base = arg_base;
     789                 :            : 
     790         [ #  # ]:          0 :         if ( ! base )
     791                 :          0 :                 Internal("empty RecordType");
     792                 :            : 
     793                 :          0 :         fields = new PDict(RecordField)(ORDERED);
     794                 :          0 :         types = 0;
     795                 :            : 
     796                 :          0 :         type_list* t = base->Types();
     797         [ #  # ]:          0 :         loop_over_list(*t, i)
     798                 :            :                 {
     799                 :          0 :                 BroType* ti = (*t)[i];
     800         [ #  # ]:          0 :                 if ( ti->Tag() != TYPE_RECORD )
     801                 :          0 :                         (*t)[i]->Error("non-record in base type list");
     802                 :            : 
     803                 :          0 :                 RecordType* rti = ti->AsRecordType();
     804                 :          0 :                 int n = rti->NumFields();
     805                 :            : 
     806         [ #  # ]:          0 :                 for ( int j = 0; j < n; ++j )
     807                 :            :                         {
     808                 :          0 :                         const TypeDecl* tdij = rti->FieldDecl(j);
     809         [ #  # ]:          0 :                         if ( fields->Lookup(tdij->id) )
     810                 :            :                                 {
     811                 :          0 :                                 error("duplicate field", tdij->id);
     812                 :          0 :                                 continue;
     813                 :            :                                 }
     814                 :            : 
     815                 :          0 :                         RecordField* rf = new RecordField(i, j, fields->Length());
     816         [ #  # ]:          0 :                         if ( fields->Insert(tdij->id, rf) )
     817                 :          0 :                                 Internal("duplicate field when constructing record");
     818                 :            :                         }
     819                 :            :                 }
     820                 :            : 
     821                 :          0 :         num_fields = fields->Length();
     822                 :          0 :         }
     823                 :            : 
     824                 :          0 : RecordType::~RecordType()
     825                 :            :         {
     826 [ #  # ][ #  # ]:          0 :         if ( types )
                 [ #  # ]
     827                 :            :                 {
     828 [ #  # ][ #  # ]:          0 :                 loop_over_list(*types, i)
                 [ #  # ]
     829 [ #  # ][ #  # ]:          0 :                         delete (*types)[i];
                 [ #  # ]
     830 [ #  # ][ #  # ]:          0 :                 delete types;
                 [ #  # ]
     831                 :            :                 }
     832                 :            : 
     833 [ #  # ][ #  # ]:          0 :         delete fields;
                 [ #  # ]
     834                 :          0 :         Unref(base);
     835 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
     836                 :            : 
     837                 :          0 : int RecordType::HasField(const char* field) const
     838                 :            :         {
     839                 :          0 :         return FieldOffset(field) >= 0;
     840                 :            :         }
     841                 :            : 
     842                 :         10 : BroType* RecordType::FieldType(const char* field) const
     843                 :            :         {
     844                 :         10 :         int offset = FieldOffset(field);
     845         [ +  - ]:         10 :         return offset >= 0 ? FieldType(offset) : 0;
     846                 :            :         }
     847                 :            : 
     848                 :     258538 : BroType* RecordType::FieldType(int field) const
     849                 :            :         {
     850         [ +  - ]:     258538 :         if ( types )
     851                 :     258538 :                 return (*types)[field]->type;
     852                 :            :         else
     853                 :            :                 {
     854                 :          0 :                 RecordField* rf = fields->NthEntry(field);
     855         [ #  # ]:          0 :                 if ( ! rf )
     856                 :          0 :                         Internal("missing field in RecordType::FieldType");
     857                 :          0 :                 BroType* bt = (*base->Types())[rf->base];
     858                 :          0 :                 RecordType* rbt = bt->AsRecordType();
     859                 :     258538 :                 return rbt->FieldType(rf->offset);
     860                 :            :                 }
     861                 :            :         }
     862                 :            : 
     863                 :       5415 : int RecordType::FieldOffset(const char* field) const
     864                 :            :         {
     865         [ +  - ]:       5415 :         if ( types )
     866                 :            :                 {
     867         [ +  - ]:      19817 :                 loop_over_list(*types, i)
     868                 :            :                         {
     869                 :      19817 :                         TypeDecl* td = (*types)[i];
     870         [ +  + ]:      19817 :                         if ( streq(td->id, field) )
     871                 :       5415 :                                 return i;
     872                 :            :                         }
     873                 :            : 
     874                 :          0 :                 return -1;
     875                 :            :                 }
     876                 :            : 
     877                 :            :         else
     878                 :            :                 {
     879                 :          0 :                 RecordField* rf = fields->Lookup(field);
     880         [ #  # ]:          0 :                 if ( ! rf )
     881                 :          0 :                         return -1;
     882                 :            :                 else
     883                 :       5415 :                         return rf->total_offset;
     884                 :            :                 }
     885                 :            :         }
     886                 :            : 
     887                 :        855 : const char* RecordType::FieldName(int field) const
     888                 :            :         {
     889                 :        855 :         return FieldDecl(field)->id;
     890                 :            :         }
     891                 :            : 
     892                 :       3819 : const TypeDecl* RecordType::FieldDecl(int field) const
     893                 :            :         {
     894         [ +  - ]:       3819 :         if ( types )
     895                 :       3819 :                 return (*types)[field];
     896                 :            :         else
     897                 :            :                 {
     898                 :          0 :                 RecordField* rf = fields->NthEntry(field);
     899         [ #  # ]:          0 :                 if ( ! rf )
     900                 :          0 :                         internal_error("missing field in RecordType::FieldDecl");
     901                 :            : 
     902                 :          0 :                 BroType* bt = (*base->Types())[rf->base];
     903                 :          0 :                 RecordType* rbt = bt->AsRecordType();
     904                 :       3819 :                 return rbt->FieldDecl(rf->offset);
     905                 :            :                 }
     906                 :            :         }
     907                 :            : 
     908                 :     387762 : TypeDecl* RecordType::FieldDecl(int field)
     909                 :            :         {
     910         [ +  - ]:     387762 :         if ( types )
     911                 :     387762 :                 return (*types)[field];
     912                 :            :         else
     913                 :            :                 {
     914                 :          0 :                 RecordField* rf = fields->NthEntry(field);
     915         [ #  # ]:          0 :                 if ( ! rf )
     916                 :          0 :                         Internal("missing field in RecordType::FieldDecl");
     917                 :          0 :                 BroType* bt = (*base->Types())[rf->base];
     918                 :          0 :                 RecordType* rbt = bt->AsRecordType();
     919                 :     387762 :                 return rbt->FieldDecl(rf->offset);
     920                 :            :                 }
     921                 :            :         }
     922                 :            : 
     923                 :          0 : void RecordType::Describe(ODesc* d) const
     924                 :            :         {
     925         [ #  # ]:          0 :         if ( d->IsReadable() )
     926                 :            :                 {
     927                 :          0 :                 d->AddSP("record {");
     928                 :          0 :                 DescribeFields(d);
     929                 :          0 :                 d->SP();
     930                 :          0 :                 d->Add("}");
     931                 :            :                 }
     932                 :            : 
     933                 :            :         else
     934                 :            :                 {
     935                 :          0 :                 d->Add(int(Tag()));
     936                 :          0 :                 DescribeFields(d);
     937                 :            :                 }
     938                 :          0 :         }
     939                 :            : 
     940                 :          0 : void RecordType::DescribeFields(ODesc* d) const
     941                 :            :         {
     942         [ #  # ]:          0 :         if ( d->IsReadable() )
     943                 :            :                 {
     944         [ #  # ]:          0 :                 for ( int i = 0; i < num_fields; ++i )
     945                 :            :                         {
     946         [ #  # ]:          0 :                         if ( i > 0 )
     947                 :          0 :                                 d->SP();
     948                 :            : 
     949                 :          0 :                         const TypeDecl* td = FieldDecl(i);
     950                 :          0 :                         d->Add(td->id);
     951                 :          0 :                         d->Add(":");
     952                 :          0 :                         td->type->Describe(d);
     953                 :          0 :                         d->Add(";");
     954                 :            :                         }
     955                 :            :                 }
     956                 :            : 
     957                 :            :         else
     958                 :            :                 {
     959         [ #  # ]:          0 :                 if ( types )
     960                 :            :                         {
     961                 :          0 :                         d->AddCount(0);
     962                 :          0 :                         d->AddCount(types->length());
     963         [ #  # ]:          0 :                         loop_over_list(*types, i)
     964                 :            :                                 {
     965                 :          0 :                                 (*types)[i]->type->Describe(d);
     966                 :          0 :                                 d->SP();
     967                 :          0 :                                 d->Add((*types)[i]->id);
     968                 :          0 :                                 d->SP();
     969                 :            :                                 }
     970                 :            :                         }
     971                 :            :                 else
     972                 :            :                         {
     973                 :          0 :                         d->AddCount(1);
     974                 :          0 :                         base->Describe(d);
     975                 :            :                         }
     976                 :            :                 }
     977                 :          0 :         }
     978                 :            : 
     979                 :          9 : IMPLEMENT_SERIAL(RecordType, SER_RECORD_TYPE)
     980                 :            : 
     981                 :          3 : bool RecordType::DoSerialize(SerialInfo* info) const
     982                 :            :         {
     983 [ +  - ][ -  + ]:          3 :         DO_SERIALIZE(SER_RECORD_TYPE, BroType);
     984                 :            : 
     985         [ -  + ]:          3 :         if ( ! SERIALIZE(num_fields) )
     986                 :          0 :                 return false;
     987                 :            : 
     988         [ +  - ]:          3 :         if ( types )
     989                 :            :                 {
     990 [ +  - ][ -  + ]:          3 :                 if ( ! (SERIALIZE(true) && SERIALIZE(types->length())) )
                 [ -  + ]
     991                 :          0 :                         return false;
     992                 :            : 
     993         [ +  + ]:         10 :                 loop_over_list(*types, i)
     994                 :            :                         {
     995         [ -  + ]:          7 :                         if ( ! (*types)[i]->Serialize(info) )
     996                 :          0 :                                 return false;
     997                 :            :                         }
     998                 :            :                 }
     999                 :            : 
    1000         [ #  # ]:          0 :         else if ( ! SERIALIZE(false) )
    1001                 :          0 :                 return false;
    1002                 :            : 
    1003 [ -  + ][ #  # ]:          3 :         SERIALIZE_OPTIONAL(base);
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
    1004                 :            : 
    1005                 :            :         // We don't serialize the fields as we can reconstruct them.
    1006                 :          3 :         return true;
    1007                 :            :         }
    1008                 :            : 
    1009                 :          0 : bool RecordType::DoUnserialize(UnserialInfo* info)
    1010                 :            :         {
    1011         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
    1012                 :            : 
    1013         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&num_fields) )
    1014                 :          0 :                 return false;
    1015                 :            : 
    1016                 :            :         bool has_it;
    1017         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&has_it) )
    1018                 :          0 :                 return false;
    1019                 :            : 
    1020         [ #  # ]:          0 :         if ( has_it )
    1021                 :            :                 {
    1022                 :            :                 int len;
    1023         [ #  # ]:          0 :                 if ( ! UNSERIALIZE(&len) )
    1024                 :          0 :                         return false;
    1025                 :            : 
    1026                 :          0 :                 types = new type_decl_list(len);
    1027                 :            : 
    1028         [ #  # ]:          0 :                 while ( len-- )
    1029                 :            :                         {
    1030                 :          0 :                         TypeDecl* t = TypeDecl::Unserialize(info);
    1031         [ #  # ]:          0 :                         if ( ! t )
    1032                 :          0 :                                 return false;
    1033                 :            : 
    1034                 :          0 :                         types->append(t);
    1035                 :            :                         }
    1036                 :            :                 }
    1037                 :            :         else
    1038                 :          0 :                 types = 0;
    1039                 :            : 
    1040                 :            :         BroType* type;
    1041 [ #  # ][ #  # ]:          0 :         UNSERIALIZE_OPTIONAL(type, BroType::Unserialize(info, TYPE_LIST));
                 [ #  # ]
    1042                 :          0 :         base = (TypeList*) type;
    1043                 :            : 
    1044         [ #  # ]:          0 :         if ( base )
    1045                 :          0 :                 Init(base);
    1046                 :            : 
    1047                 :          0 :         return true;
    1048                 :            :         }
    1049                 :            : 
    1050                 :          0 : SubNetType::SubNetType() : BroType(TYPE_SUBNET)
    1051                 :            :         {
    1052                 :          0 :         }
    1053                 :            : 
    1054                 :          0 : void SubNetType::Describe(ODesc* d) const
    1055                 :            :         {
    1056         [ #  # ]:          0 :         if ( d->IsReadable() )
    1057                 :          0 :                 d->Add("subnet");
    1058                 :            :         else
    1059                 :          0 :                 d->Add(int(Tag()));
    1060                 :          0 :         }
    1061                 :            : 
    1062                 :          3 : IMPLEMENT_SERIAL(SubNetType, SER_SUBNET_TYPE);
    1063                 :            : 
    1064                 :          0 : bool SubNetType::DoSerialize(SerialInfo* info) const
    1065                 :            :         {
    1066 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_SUBNET_TYPE, BroType);
    1067                 :          0 :         return true;
    1068                 :            :         }
    1069                 :            : 
    1070                 :          0 : bool SubNetType::DoUnserialize(UnserialInfo* info)
    1071                 :            :         {
    1072         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
    1073                 :          0 :         return true;
    1074                 :            :         }
    1075                 :            : 
    1076                 :         95 : FileType::FileType(BroType* yield_type)
    1077                 :         95 : : BroType(TYPE_FILE)
    1078                 :            :         {
    1079                 :         95 :         yield = yield_type;
    1080                 :         95 :         }
    1081                 :            : 
    1082                 :          0 : FileType::~FileType()
    1083                 :            :         {
    1084                 :          0 :         Unref(yield);
    1085 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
    1086                 :            : 
    1087                 :        246 : BroType* FileType::YieldType()
    1088                 :            :         {
    1089                 :        246 :         return yield;
    1090                 :            :         }
    1091                 :            : 
    1092                 :          0 : void FileType::Describe(ODesc* d) const
    1093                 :            :         {
    1094         [ #  # ]:          0 :         if ( d->IsReadable() )
    1095                 :            :                 {
    1096                 :          0 :                 d->AddSP("file of");
    1097                 :          0 :                 yield->Describe(d);
    1098                 :            :                 }
    1099                 :            :         else
    1100                 :            :                 {
    1101                 :          0 :                 d->Add(int(Tag()));
    1102                 :          0 :                 yield->Describe(d);
    1103                 :            :                 }
    1104                 :          0 :         }
    1105                 :            : 
    1106                 :          3 : IMPLEMENT_SERIAL(FileType, SER_FILE_TYPE);
    1107                 :            : 
    1108                 :          0 : bool FileType::DoSerialize(SerialInfo* info) const
    1109                 :            :         {
    1110 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_FILE_TYPE, BroType);
    1111                 :            : 
    1112         [ #  # ]:          0 :         assert(yield);
    1113                 :          0 :         return yield->Serialize(info);
    1114                 :            :         }
    1115                 :            : 
    1116                 :          0 : bool FileType::DoUnserialize(UnserialInfo* info)
    1117                 :            :         {
    1118         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
    1119                 :            : 
    1120                 :          0 :         yield = BroType::Unserialize(info);
    1121                 :          0 :         return yield != 0;
    1122                 :            :         }
    1123                 :            : 
    1124                 :        102 : EnumType::EnumType(bool arg_is_export)
    1125                 :        102 : : BroType(TYPE_ENUM)
    1126                 :            :         {
    1127                 :        102 :         is_export = arg_is_export;
    1128                 :        102 :         counter = 0;
    1129                 :        102 :         }
    1130                 :            : 
    1131                 :          0 : EnumType::~EnumType()
    1132                 :            :         {
    1133 [ #  # ][ #  # ]:          0 :         for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter )
                 [ #  # ]
    1134 [ #  # ][ #  # ]:          0 :                 delete [] iter->first;
                 [ #  # ]
    1135 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
    1136                 :            : 
    1137                 :        446 : int EnumType::AddName(const string& module_name, const char* name)
    1138                 :            :         {
    1139                 :        446 :         ID* id = lookup_ID(name, module_name.c_str());
    1140         [ +  - ]:        446 :         if ( ! id )
    1141                 :            :                 {
    1142                 :        446 :                 id = install_ID(name, module_name.c_str(), true, is_export);
    1143                 :        446 :                 id->SetType(this->Ref());
    1144                 :        446 :                 id->SetEnumConst();
    1145                 :            :                 }
    1146                 :            :         else
    1147                 :            :                 {
    1148                 :          0 :                 debug_msg("identifier already exists: %s\n", name);
    1149                 :          0 :                 return -1;
    1150                 :            :                 }
    1151                 :            : 
    1152                 :        446 :         string fullname = make_full_var_name(module_name.c_str(), name);
    1153                 :        446 :         names[copy_string(fullname.c_str())] = counter;
    1154                 :        446 :         return counter++;
    1155                 :            :         }
    1156                 :            : 
    1157                 :         58 : int EnumType::AddNamesFrom(const string& module_name, EnumType* et)
    1158                 :            :         {
    1159                 :         58 :         int last_added = counter;
    1160         [ +  + ]:        217 :         for ( NameMap::iterator iter = et->names.begin();
    1161                 :            :               iter != et->names.end(); ++iter )
    1162                 :            :                 {
    1163                 :        159 :                 ID* id = lookup_ID(iter->first, module_name.c_str());
    1164                 :        159 :                 id->SetType(this->Ref());
    1165                 :        159 :                 names[copy_string(id->Name())] = counter;
    1166                 :        159 :                 last_added = counter++;
    1167                 :            :                 }
    1168                 :            : 
    1169                 :         58 :         return last_added;
    1170                 :            :         }
    1171                 :            : 
    1172                 :        911 : int EnumType::Lookup(const string& module_name, const char* name)
    1173                 :            :         {
    1174                 :            :         NameMap::iterator pos =
    1175                 :        911 :                 names.find(make_full_var_name(module_name.c_str(), name).c_str());
    1176                 :            : 
    1177         [ -  + ]:        911 :         if ( pos == names.end() )
    1178                 :          0 :                 return -1;
    1179                 :            :         else
    1180                 :        911 :                 return pos->second;
    1181                 :            :         }
    1182                 :            : 
    1183                 :       5847 : const char* EnumType::Lookup(int value)
    1184                 :            :         {
    1185         [ +  - ]:     138568 :         for ( NameMap::iterator iter = names.begin();
    1186                 :            :               iter != names.end(); ++iter )
    1187         [ +  + ]:     138568 :                 if ( iter->second == value )
    1188                 :       5847 :                         return iter->first;
    1189                 :            : 
    1190                 :       5847 :         return 0;
    1191                 :            :         }
    1192                 :            : 
    1193                 :          3 : IMPLEMENT_SERIAL(EnumType, SER_ENUM_TYPE);
    1194                 :            : 
    1195                 :          0 : bool EnumType::DoSerialize(SerialInfo* info) const
    1196                 :            :         {
    1197 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_ENUM_TYPE, BroType);
    1198                 :            : 
    1199                 :            :         // I guess we don't really need both ...
    1200 [ #  # ][ #  # ]:          0 :         if ( ! (SERIALIZE(counter) && SERIALIZE((unsigned int) names.size()) &&
         [ #  # ][ #  # ]
    1201                 :            :                 SERIALIZE(is_export)) )
    1202                 :          0 :                 return false;
    1203                 :            : 
    1204         [ #  # ]:          0 :         for ( NameMap::const_iterator iter = names.begin();
    1205                 :            :               iter != names.end(); ++iter )
    1206                 :            :                 {
    1207 [ #  # ][ #  # ]:          0 :                 if ( ! SERIALIZE(iter->first) || ! SERIALIZE(iter->second) )
                 [ #  # ]
    1208                 :          0 :                         return false;
    1209                 :            :                 }
    1210                 :            : 
    1211                 :          0 :         return true;
    1212                 :            :         }
    1213                 :            : 
    1214                 :          0 : bool EnumType::DoUnserialize(UnserialInfo* info)
    1215                 :            :         {
    1216         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
    1217                 :            : 
    1218                 :            :         unsigned int len;
    1219 [ #  # ][ #  # ]:          0 :         if ( ! UNSERIALIZE(&counter) ||
         [ #  # ][ #  # ]
    1220                 :            :              ! UNSERIALIZE(&len) ||
    1221                 :            :              ! UNSERIALIZE(&is_export) )
    1222                 :          0 :                 return false;
    1223                 :            : 
    1224         [ #  # ]:          0 :         while ( len-- )
    1225                 :            :                 {
    1226                 :            :                 const char* name;
    1227                 :            :                 int val;
    1228 [ #  # ][ #  # ]:          0 :                 if ( ! (UNSERIALIZE_STR(&name, 0) && UNSERIALIZE(&val)) )
                 [ #  # ]
    1229                 :          0 :                         return false;
    1230                 :            : 
    1231                 :          0 :                 names[name] = val;
    1232                 :            :                 }
    1233                 :            : 
    1234                 :          0 :         return true;
    1235                 :            :         }
    1236                 :            : 
    1237                 :         47 : VectorType::VectorType(BroType* element_type)
    1238                 :         47 : : BroType(TYPE_VECTOR)
    1239                 :            :         {
    1240   [ +  -  #  # ]:         47 :         if ( element_type )
    1241                 :         47 :                 yield_type = element_type;
    1242                 :         47 :         }
    1243                 :            : 
    1244                 :          0 : VectorType::~VectorType()
    1245                 :            :         {
    1246                 :          0 :         Unref(yield_type);
    1247 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
    1248                 :            : 
    1249                 :         18 : int VectorType::MatchesIndex(ListExpr*& index) const
    1250                 :            :         {
    1251                 :         18 :         expr_list& el = index->Exprs();
    1252                 :            : 
    1253         [ -  + ]:         18 :         if ( el.length() != 1 )
    1254                 :          0 :                 return DOES_NOT_MATCH_INDEX;
    1255                 :            : 
    1256         [ -  + ]:         18 :         if ( el[0]->Type()->Tag() == TYPE_VECTOR )
    1257                 :            :                 return (IsIntegral(el[0]->Type()->YieldType()->Tag()) ||
    1258                 :            :                          IsBool(el[0]->Type()->YieldType()->Tag())) ?
    1259 [ #  # ][ #  # ]:          0 :                                 MATCHES_INDEX_VECTOR : DOES_NOT_MATCH_INDEX;
         [ #  # ][ #  # ]
    1260                 :            :         else
    1261                 :            :                 return (IsIntegral(el[0]->Type()->Tag()) ||
    1262                 :            :                          IsBool(el[0]->Type()->Tag())) ?
    1263 [ +  + ][ -  + ]:         18 :                                 MATCHES_INDEX_SCALAR : DOES_NOT_MATCH_INDEX;
         [ #  # ][ #  # ]
    1264                 :            :         }
    1265                 :            : 
    1266                 :          3 : IMPLEMENT_SERIAL(VectorType, SER_VECTOR_TYPE);
    1267                 :            : 
    1268                 :          0 : bool VectorType::DoSerialize(SerialInfo* info) const
    1269                 :            :         {
    1270 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_VECTOR_TYPE, BroType);
    1271                 :          0 :         return yield_type->Serialize(info);
    1272                 :            :         }
    1273                 :            : 
    1274                 :          0 : bool VectorType::DoUnserialize(UnserialInfo* info)
    1275                 :            :         {
    1276         [ #  # ]:          0 :         DO_UNSERIALIZE(BroType);
    1277                 :          0 :         yield_type = BroType::Unserialize(info);
    1278                 :          0 :         return yield_type != 0;
    1279                 :            :         }
    1280                 :            : 
    1281                 :        389 : BroType* refine_type(TypeList* base, type_decl_list* refinements)
    1282                 :            :         {
    1283                 :        389 :         type_list* t = base->Types();
    1284                 :            : 
    1285   [ +  -  +  - ]:        389 :         if ( t->length() == 1 && ! refinements )
                 [ +  - ]
    1286                 :            :                 { // Just a direct reference to a single type.
    1287                 :        389 :                 BroType* rt = (*t)[0]->Ref();
    1288                 :        389 :                 Unref(base);
    1289                 :        389 :                 return rt;
    1290                 :            :                 }
    1291                 :            : 
    1292                 :        389 :         return new RecordType(base, refinements);
    1293                 :            :         }
    1294                 :            : 
    1295                 :            : 
    1296                 :     645813 : BroType* base_type(TypeTag tag)
    1297                 :            :         {
    1298                 :            :         static BroType* base_types[NUM_TYPES];
    1299                 :            : 
    1300                 :            :         // We could check here that "tag" actually corresponds to a BRO
    1301                 :            :         // basic type.
    1302                 :            : 
    1303                 :     645813 :         int t = int(tag);
    1304         [ +  + ]:     645813 :         if ( ! base_types[t] )
    1305                 :            :                 {
    1306                 :         44 :                 base_types[t] = new BroType(tag, true);
    1307                 :            :                 // Give the base types a pseudo-location for easier identification.
    1308                 :         44 :                 Location l(type_name(tag), 0, 0, 0, 0);
    1309                 :         44 :                 base_types[t]->SetLocationInfo(&l);
    1310                 :            :                 }
    1311                 :            : 
    1312                 :     645813 :         return base_types[t]->Ref();
    1313                 :            :         }
    1314                 :            : 
    1315                 :            : 
    1316                 :            : // Returns true if t1 is initialization-compatible with t2 (i.e., if an
    1317                 :            : // initializer with type t1 can be used to initialize a value with type t2),
    1318                 :            : // false otherwise.  Assumes that t1's tag is different from t2's.  Note
    1319                 :            : // that the test is in only one direction - we don't check whether t2 is
    1320                 :            : // initialization-compatible with t1.
    1321                 :        465 : static int is_init_compat(const BroType* t1, const BroType* t2)
    1322                 :            :         {
    1323         [ +  + ]:        465 :         if ( t1->Tag() == TYPE_LIST )
    1324                 :            :                 {
    1325         [ -  + ]:        106 :                 if ( t2->Tag() == TYPE_RECORD )
    1326                 :          0 :                         return 1;
    1327                 :            :                 else
    1328                 :        106 :                         return t1->AsTypeList()->AllMatch(t2, 1);
    1329                 :            :                 }
    1330                 :            : 
    1331         [ +  + ]:        359 :         if ( t1->IsSet() )
    1332                 :         26 :                 return same_type(t1->AsSetType()->Indices(), t2, 1);
    1333                 :            : 
    1334                 :        465 :         return 0;
    1335                 :            :         }
    1336                 :            : 
    1337                 :      46726 : int same_type(const BroType* t1, const BroType* t2, int is_init)
    1338                 :            :         {
    1339         [ +  + ]:      46726 :         if ( t1 == t2 )
    1340                 :      41541 :                 return 1;
    1341                 :            : 
    1342                 :       5185 :         t1 = flatten_type(t1);
    1343                 :       5185 :         t2 = flatten_type(t2);
    1344         [ +  + ]:       5185 :         if ( t1 == t2 )
    1345                 :       2049 :                 return 1;
    1346                 :            : 
    1347         [ +  + ]:       3136 :         if ( t1->Tag() != t2->Tag() )
    1348                 :            :                 {
    1349         [ +  + ]:        781 :                 if ( is_init )
    1350 [ +  + ][ +  + ]:        233 :                         return is_init_compat(t1, t2) || is_init_compat(t2, t1);
    1351                 :            : 
    1352                 :        548 :                 return 0;
    1353                 :            :                 }
    1354                 :            : 
    1355 [ -  -  +  +  + :       2355 :         switch ( t1->Tag() ) {
             +  +  -  - ]
    1356                 :            :         case TYPE_VOID:
    1357                 :            :         case TYPE_BOOL:
    1358                 :            :         case TYPE_INT:
    1359                 :            :         case TYPE_COUNT:
    1360                 :            :         case TYPE_COUNTER:
    1361                 :            :         case TYPE_DOUBLE:
    1362                 :            :         case TYPE_TIME:
    1363                 :            :         case TYPE_INTERVAL:
    1364                 :            :         case TYPE_STRING:
    1365                 :            :         case TYPE_PATTERN:
    1366                 :            :         case TYPE_TIMER:
    1367                 :            :         case TYPE_PORT:
    1368                 :            :         case TYPE_ADDR:
    1369                 :            :         case TYPE_NET:
    1370                 :            :         case TYPE_SUBNET:
    1371                 :            :         case TYPE_ANY:
    1372                 :            :         case TYPE_ERROR:
    1373                 :          0 :                 return 1;
    1374                 :            : 
    1375                 :            :         case TYPE_ENUM:
    1376                 :            :                 // We should probably check to see whether all of the
    1377                 :            :                 // enumerations are present and in the same location.
    1378                 :            :                 // FIXME: Yes, but perhaps we should better return
    1379                 :            :                 // true per default?
    1380                 :          0 :                 return 1;
    1381                 :            : 
    1382                 :            :         case TYPE_TABLE:
    1383                 :            :                 {
    1384                 :        660 :                 const IndexType* it1 = (const IndexType*) t1;
    1385                 :        660 :                 const IndexType* it2 = (const IndexType*) t2;
    1386                 :            : 
    1387                 :        660 :                 TypeList* tl1 = it1->Indices();
    1388                 :        660 :                 TypeList* tl2 = it2->Indices();
    1389                 :            : 
    1390   [ -  +  #  # ]:        660 :                 if ( tl1 || tl2 )
    1391                 :            :                         {
    1392 [ +  - ][ +  - ]:        660 :                         if ( ! tl1 || ! tl2 || ! same_type(tl1, tl2, is_init) )
         [ +  + ][ +  + ]
    1393                 :          4 :                                 return 0;
    1394                 :            :                         }
    1395                 :            : 
    1396                 :        656 :                 const BroType* y1 = t1->YieldType();
    1397                 :        656 :                 const BroType* y2 = t2->YieldType();
    1398                 :            : 
    1399   [ +  +  -  + ]:        656 :                 if ( y1 || y2 )
    1400                 :            :                         {
    1401 [ +  - ][ +  - ]:        421 :                         if ( ! y1 || ! y2 || ! same_type(y1, y2, is_init) )
         [ -  + ][ -  + ]
    1402                 :          0 :                                 return 0;
    1403                 :            :                         }
    1404                 :            : 
    1405                 :        656 :                 return 1;
    1406                 :            :                 }
    1407                 :            : 
    1408                 :            :         case TYPE_FUNC:
    1409                 :            :                 {
    1410                 :        614 :                 const FuncType* ft1 = (const FuncType*) t1;
    1411                 :        614 :                 const FuncType* ft2 = (const FuncType*) t2;
    1412                 :            : 
    1413         [ -  + ]:        614 :                 if ( ft1->IsEvent() != ft2->IsEvent() )
    1414                 :          0 :                         return 0;
    1415                 :            : 
    1416 [ +  + ][ -  + ]:        614 :                 if ( t1->YieldType() || t2->YieldType() )
                 [ +  + ]
    1417                 :            :                         {
    1418 [ +  - ][ +  - ]:        108 :                         if ( ! t1->YieldType() || ! t2->YieldType() ||
         [ +  + ][ +  + ]
    1419                 :            :                              ! same_type(t1->YieldType(), t2->YieldType(), is_init) )
    1420                 :          1 :                                 return 0;
    1421                 :            :                         }
    1422                 :            : 
    1423                 :        613 :                 return same_type(ft1->Args(), ft2->Args(), is_init);
    1424                 :            :                 }
    1425                 :            : 
    1426                 :            :         case TYPE_RECORD:
    1427                 :            :                 {
    1428                 :        844 :                 const RecordType* rt1 = (const RecordType*) t1;
    1429                 :        844 :                 const RecordType* rt2 = (const RecordType*) t2;
    1430                 :            : 
    1431         [ +  + ]:        844 :                 if ( rt1->NumFields() != rt2->NumFields() )
    1432                 :        191 :                         return 0;
    1433                 :            : 
    1434         [ +  + ]:       2135 :                 for ( int i = 0; i < rt1->NumFields(); ++i )
    1435                 :            :                         {
    1436                 :       1482 :                         const TypeDecl* td1 = rt1->FieldDecl(i);
    1437                 :       1482 :                         const TypeDecl* td2 = rt2->FieldDecl(i);
    1438                 :            : 
    1439   [ +  -  -  + ]:       1482 :                         if ( ! streq(td1->id, td2->id) ||
                 [ -  + ]
    1440                 :            :                              ! same_type(td1->type, td2->type, is_init) )
    1441                 :          0 :                                 return 0;
    1442                 :            :                         }
    1443                 :            : 
    1444                 :        653 :                 return 1;
    1445                 :            :                 }
    1446                 :            : 
    1447                 :            :         case TYPE_LIST:
    1448                 :            :                 {
    1449                 :         92 :                 const type_list* tl1 = t1->AsTypeList()->Types();
    1450                 :         92 :                 const type_list* tl2 = t2->AsTypeList()->Types();
    1451                 :            : 
    1452         [ -  + ]:         92 :                 if ( tl1->length() != tl2->length() )
    1453                 :          0 :                         return 0;
    1454                 :            : 
    1455         [ +  + ]:        276 :                 loop_over_list(*tl1, i)
    1456         [ -  + ]:        184 :                         if ( ! same_type((*tl1)[i], (*tl2)[i], is_init) )
    1457                 :          0 :                                 return 0;
    1458                 :            : 
    1459                 :         92 :                 return 1;
    1460                 :            :                 }
    1461                 :            : 
    1462                 :            :         case TYPE_VECTOR:
    1463                 :            :         case TYPE_FILE:
    1464                 :        145 :                 return same_type(t1->YieldType(), t2->YieldType(), is_init);
    1465                 :            : 
    1466                 :            :         case TYPE_UNION:
    1467                 :          0 :                 error("union type in same_type()");
    1468                 :            :         }
    1469                 :      46726 :         return 0;
    1470                 :            :         }
    1471                 :            : 
    1472                 :            : int record_promotion_compatible(const RecordType* /* super_rec */,
    1473                 :        228 :                                 const RecordType* /* sub_rec */)
    1474                 :            :         {
    1475                 :            : #if 0
    1476                 :            :         int n = sub_rec->NumFields();
    1477                 :            : 
    1478                 :            :         for ( int i = 0; i < n; ++i )
    1479                 :            :                 {
    1480                 :            :                 if ( ! super_rec->HasField(sub_rec->FieldName(i)) )
    1481                 :            :                         return 0;
    1482                 :            :                 }
    1483                 :            : #endif
    1484                 :            : 
    1485                 :        228 :         return 1;
    1486                 :            :         }
    1487                 :            : 
    1488                 :      22663 : const BroType* flatten_type(const BroType* t)
    1489                 :            :         {
    1490         [ +  + ]:      22663 :         if ( t->Tag() != TYPE_LIST )
    1491                 :      18150 :                 return t;
    1492                 :            : 
    1493                 :       4513 :         const TypeList* tl = t->AsTypeList();
    1494                 :            : 
    1495         [ +  + ]:       4513 :         if ( tl->IsPure() )
    1496                 :       2447 :                 return tl->PureType();
    1497                 :            : 
    1498                 :       2066 :         const type_list* types = tl->Types();
    1499                 :            : 
    1500         [ -  + ]:       2066 :         if ( types->length() == 0 )
    1501                 :          0 :                 internal_error("empty type list in flatten_type");
    1502                 :            : 
    1503                 :       2066 :         const BroType* ft = (*types)[0];
    1504   [ +  +  +  + ]:       2066 :         if ( types->length() == 1 || tl->AllMatch(ft, 0) )
                 [ +  + ]
    1505                 :       1595 :                 return ft;
    1506                 :            : 
    1507                 :      22663 :         return t;
    1508                 :            :         }
    1509                 :            : 
    1510                 :       6084 : BroType* flatten_type(BroType* t)
    1511                 :            :         {
    1512                 :       6084 :         return (BroType*) flatten_type((const BroType*) t);
    1513                 :            :         }
    1514                 :            : 
    1515                 :       2559 : int is_assignable(BroType* t)
    1516                 :            :         {
    1517   [ +  +  -  -  :       2559 :         switch ( t->Tag() ) {
                      - ]
    1518                 :            :         case TYPE_BOOL:
    1519                 :            :         case TYPE_INT:
    1520                 :            :         case TYPE_COUNT:
    1521                 :            :         case TYPE_COUNTER:
    1522                 :            :         case TYPE_DOUBLE:
    1523                 :            :         case TYPE_TIME:
    1524                 :            :         case TYPE_INTERVAL:
    1525                 :            :         case TYPE_STRING:
    1526                 :            :         case TYPE_PATTERN:
    1527                 :            :         case TYPE_ENUM:
    1528                 :            :         case TYPE_TIMER:
    1529                 :            :         case TYPE_PORT:
    1530                 :            :         case TYPE_ADDR:
    1531                 :            :         case TYPE_NET:
    1532                 :            :         case TYPE_SUBNET:
    1533                 :            :         case TYPE_RECORD:
    1534                 :            :         case TYPE_FUNC:
    1535                 :            :         case TYPE_ANY:
    1536                 :            :         case TYPE_ERROR:
    1537                 :            :         case TYPE_LIST:
    1538                 :       2411 :                 return 1;
    1539                 :            : 
    1540                 :            :         case TYPE_VECTOR:
    1541                 :            :         case TYPE_FILE:
    1542                 :            :         case TYPE_TABLE:
    1543                 :        148 :                 return 1;
    1544                 :            : 
    1545                 :            :         case TYPE_VOID:
    1546                 :          0 :                 return 0;
    1547                 :            : 
    1548                 :            :         case TYPE_UNION:
    1549                 :          0 :                 error("union type in is_assignable()");
    1550                 :            :         }
    1551                 :            : 
    1552                 :       2559 :         return 0;
    1553                 :            :         }
    1554                 :            : 
    1555                 :        894 : TypeTag max_type(TypeTag t1, TypeTag t2)
    1556                 :            :         {
    1557 [ +  - ][ -  + ]:        894 :         if ( t1 == TYPE_INTERVAL || t1 == TYPE_TIME )
    1558                 :          0 :                 t1 = TYPE_DOUBLE;
    1559 [ +  - ][ -  + ]:        894 :         if ( t2 == TYPE_INTERVAL || t2 == TYPE_TIME )
    1560                 :          0 :                 t2 = TYPE_DOUBLE;
    1561                 :            : 
    1562 [ +  + ][ +  + ]:        894 :         if ( BothArithmetic(t1, t2) )
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
    1563                 :            :                 {
    1564                 :            : #define CHECK_TYPE(t) \
    1565                 :            :         if ( t1 == t || t2 == t ) \
    1566                 :            :                 return t;
    1567                 :            : 
    1568 [ +  + ][ +  + ]:        894 :                 CHECK_TYPE(TYPE_DOUBLE);
    1569 [ +  + ][ +  + ]:        771 :                 CHECK_TYPE(TYPE_INT);
    1570 [ -  + ][ #  # ]:        712 :                 CHECK_TYPE(TYPE_COUNT);
    1571                 :            : 
    1572                 :            :                 // Note - mixing two TYPE_COUNTER's still promotes to
    1573                 :            :                 // a TYPE_COUNT.
    1574                 :          0 :                 return TYPE_COUNT;
    1575                 :            :                 }
    1576                 :            :         else
    1577                 :            :                 {
    1578                 :        894 :                 internal_error("non-arithmetic tags in max_type()");
    1579                 :            :                 return TYPE_ERROR;
    1580                 :            :                 }
    1581                 :            :         }
    1582                 :            : 
    1583                 :         66 : BroType* merge_types(const BroType* t1, const BroType* t2)
    1584                 :            :         {
    1585                 :         66 :         t1 = flatten_type(t1);
    1586                 :         66 :         t2 = flatten_type(t2);
    1587                 :            : 
    1588                 :         66 :         TypeTag tg1 = t1->Tag();
    1589                 :         66 :         TypeTag tg2 = t2->Tag();
    1590                 :            : 
    1591   [ +  -  +  - ]:         66 :         if ( BothArithmetic(tg1, tg2) )
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1592                 :          0 :                 return base_type(max_type(tg1, tg2));
    1593                 :            : 
    1594         [ -  + ]:         66 :         if ( tg1 != tg2 )
    1595                 :            :                 {
    1596                 :          0 :                 t1->Error("incompatible types", t2);
    1597                 :          0 :                 return 0;
    1598                 :            :                 }
    1599                 :            : 
    1600 [ +  -  -  -  - :         66 :         switch ( tg1 ) {
             -  -  -  - ]
    1601                 :            :         case TYPE_TIME:
    1602                 :            :         case TYPE_INTERVAL:
    1603                 :            :         case TYPE_STRING:
    1604                 :            :         case TYPE_PATTERN:
    1605                 :            :         case TYPE_TIMER:
    1606                 :            :         case TYPE_PORT:
    1607                 :            :         case TYPE_ADDR:
    1608                 :            :         case TYPE_NET:
    1609                 :            :         case TYPE_SUBNET:
    1610                 :            :         case TYPE_ANY:
    1611                 :            :         case TYPE_ERROR:
    1612                 :         66 :                 return base_type(tg1);
    1613                 :            : 
    1614                 :            :         case TYPE_TABLE:
    1615                 :            :                 {
    1616                 :          0 :                 const IndexType* it1 = (const IndexType*) t1;
    1617                 :          0 :                 const IndexType* it2 = (const IndexType*) t2;
    1618                 :            : 
    1619                 :          0 :                 const type_list* tl1 = it1->IndexTypes();
    1620                 :          0 :                 const type_list* tl2 = it2->IndexTypes();
    1621                 :          0 :                 TypeList* tl3 = 0;
    1622                 :            : 
    1623   [ #  #  #  # ]:          0 :                 if ( tl1 || tl2 )
    1624                 :            :                         {
    1625 [ #  # ][ #  # ]:          0 :                         if ( ! tl1 || ! tl2 || tl1->length() != tl2->length() )
         [ #  # ][ #  # ]
    1626                 :            :                                 {
    1627                 :          0 :                                 t1->Error("incompatible types", t2);
    1628                 :          0 :                                 return 0;
    1629                 :            :                                 }
    1630                 :            : 
    1631                 :          0 :                         tl3 = new TypeList();
    1632                 :            : 
    1633         [ #  # ]:          0 :                         loop_over_list(*tl1, i)
    1634                 :            :                                 {
    1635                 :          0 :                                 BroType* tl3_i = merge_types((*tl1)[i], (*tl2)[i]);
    1636         [ #  # ]:          0 :                                 if ( ! tl3_i )
    1637                 :            :                                         {
    1638                 :          0 :                                         Unref(tl3);
    1639                 :          0 :                                         return 0;
    1640                 :            :                                         }
    1641                 :            : 
    1642                 :          0 :                                 tl3->Append(tl3_i);
    1643                 :            :                                 }
    1644                 :            :                         }
    1645                 :            : 
    1646                 :          0 :                 const BroType* y1 = t1->YieldType();
    1647                 :          0 :                 const BroType* y2 = t2->YieldType();
    1648                 :          0 :                 BroType* y3 = 0;
    1649                 :            : 
    1650   [ #  #  #  # ]:          0 :                 if ( y1 || y2 )
    1651                 :            :                         {
    1652 [ #  # ][ #  # ]:          0 :                         if ( ! y1 || ! y2 )
    1653                 :            :                                 {
    1654                 :          0 :                                 t1->Error("incompatible types", t2);
    1655                 :          0 :                                 return 0;
    1656                 :            :                                 }
    1657                 :            : 
    1658                 :          0 :                         y3 = merge_types(y1, y2);
    1659         [ #  # ]:          0 :                         if ( ! y3 )
    1660                 :            :                                 {
    1661                 :          0 :                                 Unref(tl3);
    1662                 :          0 :                                 return 0;
    1663                 :            :                                 }
    1664                 :            :                         }
    1665                 :            : 
    1666         [ #  # ]:          0 :                 if ( t1->IsSet() )
    1667                 :          0 :                         return new SetType(tl3, 0);
    1668         [ #  # ]:          0 :                 else if ( tg1 == TYPE_TABLE )
    1669                 :          0 :                         return new TableType(tl3, y3);
    1670                 :            :                 else
    1671                 :            :                         {
    1672                 :          0 :                         internal_error("bad tag in merge_types");
    1673                 :            :                         return 0;
    1674                 :            :                         }
    1675                 :            :                 }
    1676                 :            : 
    1677                 :            :         case TYPE_FUNC:
    1678                 :            :                 {
    1679         [ #  # ]:          0 :                 if ( ! same_type(t1, t2) )
    1680                 :            :                         {
    1681                 :          0 :                         t1->Error("incompatible types", t2);
    1682                 :          0 :                         return 0;
    1683                 :            :                         }
    1684                 :            : 
    1685                 :          0 :                 const FuncType* ft1 = (const FuncType*) t1;
    1686                 :          0 :                 const FuncType* ft2 = (const FuncType*) t1;
    1687                 :          0 :                 BroType* args = merge_types(ft1->Args(), ft2->Args());
    1688                 :            :                 BroType* yield = t1->YieldType() ?
    1689         [ #  # ]:          0 :                         merge_types(t1->YieldType(), t2->YieldType()) : 0;
    1690                 :            : 
    1691                 :          0 :                 return new FuncType(args->AsRecordType(), yield, ft1->IsEvent());
    1692                 :            :                 }
    1693                 :            : 
    1694                 :            :         case TYPE_RECORD:
    1695                 :            :                 {
    1696                 :          0 :                 const RecordType* rt1 = (const RecordType*) t1;
    1697                 :          0 :                 const RecordType* rt2 = (const RecordType*) t2;
    1698                 :            : 
    1699         [ #  # ]:          0 :                 if ( rt1->NumFields() != rt2->NumFields() )
    1700                 :          0 :                         return 0;
    1701                 :            : 
    1702                 :          0 :                 type_decl_list* tdl3 = new type_decl_list;
    1703                 :            : 
    1704         [ #  # ]:          0 :                 for ( int i = 0; i < rt1->NumFields(); ++i )
    1705                 :            :                         {
    1706                 :          0 :                         const TypeDecl* td1 = rt1->FieldDecl(i);
    1707                 :          0 :                         const TypeDecl* td2 = rt2->FieldDecl(i);
    1708                 :          0 :                         BroType* tdl3_i = merge_types(td1->type, td2->type);
    1709                 :            : 
    1710   [ #  #  #  # ]:          0 :                         if ( ! streq(td1->id, td2->id) || ! tdl3_i )
                 [ #  # ]
    1711                 :            :                                 {
    1712                 :          0 :                                 t1->Error("incompatible record fields", t2);
    1713         [ #  # ]:          0 :                                 delete tdl3;
    1714                 :          0 :                                 Unref(tdl3_i);
    1715                 :          0 :                                 return 0;
    1716                 :            :                                 }
    1717                 :            : 
    1718                 :          0 :                         tdl3->append(new TypeDecl(tdl3_i, copy_string(td1->id)));
    1719                 :            :                         }
    1720                 :            : 
    1721                 :          0 :                 return new RecordType(tdl3);
    1722                 :            :                 }
    1723                 :            : 
    1724                 :            :         case TYPE_LIST:
    1725                 :            :                 {
    1726                 :          0 :                 const TypeList* tl1 = t1->AsTypeList();
    1727                 :          0 :                 const TypeList* tl2 = t2->AsTypeList();
    1728                 :            : 
    1729         [ #  # ]:          0 :                 if ( tl1->IsPure() != tl2->IsPure() )
    1730                 :            :                         {
    1731                 :          0 :                         tl1->Error("incompatible lists", tl2);
    1732                 :          0 :                         return 0;
    1733                 :            :                         }
    1734                 :            : 
    1735                 :          0 :                 const type_list* l1 = tl1->Types();
    1736                 :          0 :                 const type_list* l2 = tl2->Types();
    1737                 :            : 
    1738   [ #  #  #  # ]:          0 :                 if ( l1->length() == 0 || l2->length() == 0 )
                 [ #  # ]
    1739                 :            :                         {
    1740         [ #  # ]:          0 :                         if ( l1->length() == 0 )
    1741                 :          0 :                                 tl1->Error("empty list");
    1742                 :            :                         else
    1743                 :          0 :                                 tl2->Error("empty list");
    1744                 :          0 :                         return 0;
    1745                 :            :                         }
    1746                 :            : 
    1747         [ #  # ]:          0 :                 if ( tl1->IsPure() )
    1748                 :            :                         {
    1749                 :            :                         // We will be expanding the pure list when converting
    1750                 :            :                         // the initialization expression into a set of values.
    1751                 :            :                         // So the merge type of the list is the type of one
    1752                 :            :                         // of the elements, providing they're consistent.
    1753                 :          0 :                         return merge_types((*l1)[0], (*l2)[0]);
    1754                 :            :                         }
    1755                 :            : 
    1756                 :            :                 // Impure lists - must have the same size and match element
    1757                 :            :                 // by element.
    1758         [ #  # ]:          0 :                 if ( l1->length() != l2->length() )
    1759                 :            :                         {
    1760                 :          0 :                         tl1->Error("different number of indices", tl2);
    1761                 :          0 :                         return 0;
    1762                 :            :                         }
    1763                 :            : 
    1764                 :          0 :                 TypeList* tl3 = new TypeList();
    1765         [ #  # ]:          0 :                 loop_over_list(*l1, i)
    1766                 :          0 :                         tl3->Append(merge_types((*l1)[i], (*l2)[i]));
    1767                 :            : 
    1768                 :          0 :                 return tl3;
    1769                 :            :                 }
    1770                 :            : 
    1771                 :            :         case TYPE_VECTOR:
    1772         [ #  # ]:          0 :                 if ( ! same_type(t1->YieldType(), t2->YieldType()) )
    1773                 :            :                         {
    1774                 :          0 :                         t1->Error("incompatible types", t2);
    1775                 :          0 :                         return 0;
    1776                 :            :                         }
    1777                 :            : 
    1778                 :          0 :                 return new VectorType(merge_types(t1->YieldType(), t2->YieldType()));
    1779                 :            : 
    1780                 :            :         case TYPE_FILE:
    1781         [ #  # ]:          0 :                 if ( ! same_type(t1->YieldType(), t2->YieldType()) )
    1782                 :            :                         {
    1783                 :          0 :                         t1->Error("incompatible types", t2);
    1784                 :          0 :                         return 0;
    1785                 :            :                         }
    1786                 :            : 
    1787                 :          0 :                 return new FileType(merge_types(t1->YieldType(), t2->YieldType()));
    1788                 :            : 
    1789                 :            :         case TYPE_UNION:
    1790                 :          0 :                 internal_error("union type in merge_types()");
    1791                 :            :                 return 0;
    1792                 :            : 
    1793                 :            :         default:
    1794                 :         66 :                 internal_error("bad type in merge_types()");
    1795                 :            :                 return 0;
    1796                 :            :         }
    1797                 :            :         }
    1798                 :            : 
    1799                 :          6 : BroType* merge_type_list(ListExpr* elements)
    1800                 :            :         {
    1801                 :          6 :         TypeList* tl_type = elements->Type()->AsTypeList();
    1802                 :          6 :         type_list* tl = tl_type->Types();
    1803                 :            : 
    1804         [ -  + ]:          6 :         if ( tl->length() < 1 )
    1805                 :            :                 {
    1806                 :          0 :                 error("no type can be inferred for empty list");
    1807                 :          0 :                 return 0;
    1808                 :            :                 }
    1809                 :            : 
    1810                 :          6 :         BroType* t = (*tl)[0]->Ref();
    1811                 :            : 
    1812         [ +  + ]:          6 :         if ( tl->length() == 1 )
    1813                 :          2 :                 return t;
    1814                 :            : 
    1815 [ +  - ][ +  + ]:         70 :         for ( int i = 1; t && i < tl->length(); ++i )
                 [ +  + ]
    1816                 :            :                 {
    1817                 :         66 :                 BroType* t_new = merge_types(t, (*tl)[i]);
    1818                 :         66 :                 Unref(t);
    1819                 :         66 :                 t = t_new;
    1820                 :            :                 }
    1821                 :            : 
    1822         [ -  + ]:          4 :         if ( ! t )
    1823                 :          0 :                 error("inconsistent types in list");
    1824                 :            : 
    1825                 :          6 :         return t;
    1826                 :            :         }
    1827                 :            : 
    1828                 :            : // Reduces an aggregate type.
    1829                 :        884 : static BroType* reduce_type(BroType* t)
    1830                 :            :         {
    1831         [ +  + ]:        884 :         if ( t->Tag() == TYPE_LIST )
    1832                 :          7 :                 return flatten_type(t);
    1833                 :            : 
    1834         [ +  + ]:        877 :         else if ( t->IsSet() )
    1835                 :            :                 {
    1836                 :         76 :                 TypeList* tl = t->AsTableType()->Indices();
    1837         [ +  - ]:         76 :                 if ( tl->Types()->length() == 1 )
    1838                 :         76 :                         return (*tl->Types())[0];
    1839                 :            :                 else
    1840                 :          0 :                         return tl;
    1841                 :            :                 }
    1842                 :            : 
    1843                 :            :         else
    1844                 :        884 :                 return t;
    1845                 :            :         }
    1846                 :            : 
    1847                 :       2384 : BroType* init_type(Expr* init)
    1848                 :            :         {
    1849         [ +  + ]:       2384 :         if ( init->Tag() != EXPR_LIST )
    1850                 :            :                 {
    1851                 :       2250 :                 BroType* t = init->InitType();
    1852         [ -  + ]:       2250 :                 if ( ! t )
    1853                 :          0 :                         return 0;
    1854                 :            : 
    1855 [ -  + ][ #  # ]:       2250 :                 if ( t->Tag() == TYPE_LIST &&
                 [ -  + ]
    1856                 :            :                      t->AsTypeList()->Types()->length() != 1 )
    1857                 :            :                         {
    1858                 :          0 :                         init->Error("list used in scalar initialization");
    1859                 :          0 :                         Unref(t);
    1860                 :          0 :                         return 0;
    1861                 :            :                         }
    1862                 :            : 
    1863                 :       2250 :                 return t;
    1864                 :            :                 }
    1865                 :            : 
    1866                 :        134 :         ListExpr* init_list = init->AsListExpr();
    1867                 :        134 :         const expr_list& el = init_list->Exprs();
    1868                 :            : 
    1869         [ -  + ]:        134 :         if ( el.length() == 0 )
    1870                 :            :                 {
    1871                 :          0 :                 init->Error("empty list in untyped initialization");
    1872                 :          0 :                 return 0;
    1873                 :            :                 }
    1874                 :            : 
    1875                 :            :         // Could be a record, a set, or a list of table elements.
    1876                 :        134 :         Expr* e0 = el[0];
    1877         [ -  + ]:        134 :         if ( e0->IsRecordElement(0) )
    1878                 :            :                 // ListExpr's know how to build a record from their
    1879                 :            :                 // components.
    1880                 :          0 :                 return init_list->InitType();
    1881                 :            : 
    1882                 :        134 :         BroType* t = e0->InitType();
    1883         [ +  - ]:        134 :         if ( t )
    1884                 :        134 :                 t = reduce_type(t);
    1885         [ -  + ]:        134 :         if ( ! t )
    1886                 :          0 :                 return 0;
    1887                 :            : 
    1888 [ +  - ][ +  + ]:        884 :         for ( int i = 1; t && i < el.length(); ++i )
                 [ +  + ]
    1889                 :            :                 {
    1890                 :        750 :                 BroType* el_t = el[i]->InitType();
    1891         [ +  - ]:        750 :                 BroType* ti = el_t ? reduce_type(el_t) : 0;
    1892         [ -  + ]:        750 :                 if ( ! ti )
    1893                 :            :                         {
    1894                 :          0 :                         Unref(t);
    1895                 :          0 :                         return 0;
    1896                 :            :                         }
    1897                 :            : 
    1898         [ +  - ]:        750 :                 if ( same_type(t, ti) )
    1899                 :            :                         {
    1900                 :        750 :                         Unref(ti);
    1901                 :        750 :                         continue;
    1902                 :            :                         }
    1903                 :            : 
    1904                 :          0 :                 BroType* t_merge = merge_types(t, ti);
    1905                 :          0 :                 Unref(t);
    1906                 :          0 :                 Unref(ti);
    1907                 :          0 :                 t = t_merge;
    1908                 :            :                 }
    1909                 :            : 
    1910         [ -  + ]:        134 :         if ( ! t )
    1911                 :            :                 {
    1912                 :          0 :                 init->Error("type error in initialization");
    1913                 :          0 :                 return 0;
    1914                 :            :                 }
    1915                 :            : 
    1916 [ +  + ][ +  - ]:        134 :         if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() )
                 [ +  + ]
    1917                 :            :                 // A list of table elements.
    1918                 :         19 :                 return t;
    1919                 :            : 
    1920                 :            :         // A set.  If the index type isn't yet a type list, make
    1921                 :            :         // it one, as that's what's required for creating a set type.
    1922         [ +  + ]:        115 :         if ( t->Tag() != TYPE_LIST )
    1923                 :            :                 {
    1924                 :        113 :                 TypeList* tl = new TypeList(t);
    1925                 :        113 :                 tl->Append(t);
    1926                 :        113 :                 t = tl;
    1927                 :            :                 }
    1928                 :            : 
    1929                 :       2384 :         return new SetType(t->AsTypeList(), 0);
    1930 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8