LCOV - code coverage report
Current view: top level - src - Scope.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 89 133 66.9 %
Date: 2010-12-13 Functions: 15 22 68.2 %
Branches: 58 124 46.8 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Scope.cc 6219 2008-10-01 05:39:07Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include "ID.h"
       8                 :            : #include "Val.h"
       9                 :            : #include "Scope.h"
      10                 :            : 
      11                 :          6 : static scope_list scopes;
      12                 :            : static Scope* top_scope;
      13                 :            : 
      14                 :            : extern const char* GLOBAL_MODULE_NAME = "GLOBAL";
      15                 :            : 
      16                 :            : 
      17                 :            : // Returns it without trailing "::".
      18                 :      34297 : string extract_module_name(const char* name)
      19                 :            :         {
      20                 :      34297 :         string module_name = name;
      21                 :      34297 :         string::size_type pos = module_name.rfind("::");
      22                 :            : 
      23         [ +  + ]:      34297 :         if ( pos == string::npos )
      24                 :      15271 :                 return string(GLOBAL_MODULE_NAME);
      25                 :            : 
      26                 :      19026 :         module_name.erase(pos);
      27                 :            : 
      28                 :      34297 :         return module_name;
      29                 :            :         }
      30                 :            : 
      31                 :      26310 : string normalized_module_name(const char* module_name)
      32                 :            :         {
      33                 :            :         int mod_len;
      34 [ +  - ][ -  + ]:      26310 :         if ( (mod_len = strlen(module_name)) >= 2 &&
                 [ -  + ]
      35                 :            :              ! strcmp(module_name + mod_len - 2, "::") )
      36                 :          0 :                 mod_len -= 2;
      37                 :            : 
      38                 :      26310 :         return string(module_name, mod_len);
      39                 :            :         }
      40                 :            : 
      41                 :      56206 : string make_full_var_name(const char* module_name, const char* var_name)
      42                 :            :         {
      43 [ +  + ][ +  + ]:      56206 :         if ( ! module_name || streq(module_name, GLOBAL_MODULE_NAME) ||
         [ +  + ][ +  + ]
      44                 :            :              strstr(var_name, "::") )
      45                 :      34367 :                 return string(var_name);
      46                 :            : 
      47                 :      21839 :         string full_name = normalized_module_name(module_name);
      48                 :      21839 :         full_name += "::";
      49                 :      21839 :         full_name += var_name;
      50                 :            : 
      51                 :      56206 :         return full_name;
      52                 :            :         }
      53                 :            : 
      54                 :       1128 : Scope::Scope(ID* id)
      55                 :            :         {
      56                 :       1128 :         scope_id = id;
      57                 :       1128 :         return_type = 0;
      58                 :            : 
      59                 :       1128 :         local = new PDict(ID)(ORDERED);
      60                 :       1128 :         inits = new id_list;
      61                 :            : 
      62   [ +  +  #  # ]:       1128 :         if ( id )
      63                 :            :                 {
      64                 :       1125 :                 BroType* id_type = id->Type();
      65                 :            : 
      66   [ +  -  #  # ]:       1125 :                 if ( id_type->Tag() == TYPE_ERROR )
      67                 :       1128 :                         return;
      68 [ -  + ][ #  # ]:       1125 :                 else if ( id_type->Tag() != TYPE_FUNC )
      69                 :          0 :                         internal_error("bad scope id");
      70                 :            : 
      71                 :       1125 :                 Ref(id);
      72                 :            : 
      73                 :       1125 :                 FuncType* ft = id->Type()->AsFuncType();
      74                 :       1125 :                 return_type = ft->YieldType();
      75   [ +  +  #  # ]:       1125 :                 if ( return_type )
      76                 :       1128 :                         Ref(return_type);
      77                 :            :                 }
      78                 :          0 :         }
      79                 :            : 
      80                 :          0 : Scope::~Scope()
      81                 :            :         {
      82 [ #  # ][ #  # ]:          0 :         for ( int i = 0; i < local->Length(); ++i )
                 [ #  # ]
      83                 :          0 :                 Unref(local->NthEntry(i));
      84                 :            : 
      85                 :          0 :         Unref(scope_id);
      86                 :          0 :         Unref(return_type);
      87   [ #  #  #  # ]:          0 :         delete local;
                 [ #  # ]
      88 [ #  # ][ #  # ]:          0 :         delete inits;
                 [ #  # ]
      89 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
      90                 :            : 
      91                 :         20 : ID* Scope::GenerateTemporary(const char* name)
      92                 :            :         {
      93                 :         20 :         return new ID(copy_string(name), SCOPE_FUNCTION, false);
      94                 :            :         }
      95                 :            : 
      96                 :       1125 : id_list* Scope::GetInits()
      97                 :            :         {
      98                 :       1125 :         id_list* ids = inits;
      99                 :       1125 :         inits = 0;
     100                 :       1125 :         return ids;
     101                 :            :         }
     102                 :            : 
     103                 :          0 : void Scope::Describe(ODesc* d) const
     104                 :            :         {
     105         [ #  # ]:          0 :         if ( d->IsReadable() )
     106                 :          0 :                 d->AddSP("scope");
     107                 :            : 
     108                 :            :         else
     109                 :            :                 {
     110                 :          0 :                 d->Add(scope_id != 0);
     111                 :          0 :                 d->SP();
     112                 :          0 :                 d->Add(return_type != 0);
     113                 :          0 :                 d->SP();
     114                 :          0 :                 d->Add(local->Length());
     115                 :          0 :                 d->SP();
     116                 :            :                 }
     117                 :            : 
     118         [ #  # ]:          0 :         if ( scope_id )
     119                 :            :                 {
     120                 :          0 :                 scope_id->Describe(d);
     121                 :          0 :                 d->NL();
     122                 :            :                 }
     123                 :            : 
     124         [ #  # ]:          0 :         if ( return_type )
     125                 :            :                 {
     126                 :          0 :                 return_type->Describe(d);
     127                 :          0 :                 d->NL();
     128                 :            :                 }
     129                 :            : 
     130         [ #  # ]:          0 :         for ( int i = 0; i < local->Length(); ++i )
     131                 :            :                 {
     132                 :          0 :                 ID* id = local->NthEntry(i);
     133                 :          0 :                 id->Describe(d);
     134                 :          0 :                 d->NL();
     135                 :            :                 }
     136                 :          0 :         }
     137                 :            : 
     138                 :          0 : TraversalCode Scope::Traverse(TraversalCallback* cb) const
     139                 :            :         {
     140                 :          0 :         PDict(ID)* ids = GetIDs();
     141                 :          0 :         IterCookie* iter = ids->InitForIteration();
     142                 :            : 
     143                 :            :         HashKey* key;
     144                 :            :         ID* id;
     145         [ #  # ]:          0 :         while ( (id = ids->NextEntry(key, iter)) )
     146                 :            :                 {
     147                 :          0 :                 TraversalCode tc = id->Traverse(cb);
     148   [ #  #  #  # ]:          0 :                 HANDLE_TC_STMT_PRE(tc);
     149                 :            :                 }
     150                 :            : 
     151                 :          0 :         return TC_CONTINUE;
     152                 :            :         }
     153                 :            : 
     154                 :            : 
     155                 :      33386 : ID* lookup_ID(const char* name, const char* curr_module, bool no_global)
     156                 :            :         {
     157                 :      33386 :         string fullname = make_full_var_name(curr_module, name);
     158                 :      33386 :         string ID_module = extract_module_name(fullname.c_str());
     159                 :            :         bool need_export = ID_module != GLOBAL_MODULE_NAME &&
     160   [ +  +  +  + ]:      33386 :                                 ID_module != curr_module;
     161                 :            : 
     162         [ +  + ]:      55750 :         for ( int i = scopes.length() - 1; i >= 0; --i )
     163                 :            :                 {
     164                 :      43939 :                 ID* id = scopes[i]->Lookup(fullname.c_str());
     165         [ +  + ]:      43939 :                 if ( id )
     166                 :            :                         {
     167 [ +  + ][ -  + ]:      21575 :                         if ( need_export && ! id->IsExport() && ! in_debug )
         [ #  # ][ -  + ]
     168                 :            :                                 error("identifier is not exported:",
     169                 :          0 :                                       fullname.c_str());
     170                 :            : 
     171                 :      21575 :                         Ref(id);
     172                 :      21575 :                         return id;
     173                 :            :                         }
     174                 :            :                 }
     175                 :            : 
     176         [ +  - ]:      11811 :         if ( ! no_global )
     177                 :            :                 {
     178                 :      11811 :                 string globalname = make_full_var_name(GLOBAL_MODULE_NAME, name);
     179                 :      11811 :                 ID* id = global_scope()->Lookup(globalname.c_str());
     180         [ +  + ]:      11811 :                 if ( id )
     181                 :            :                         {
     182                 :       3072 :                         Ref(id);
     183                 :      11811 :                         return id;
     184         [ +  + ]:      11811 :                         }
     185                 :            :                 }
     186                 :            : 
     187                 :      33386 :         return 0;
     188                 :            :         }
     189                 :            : 
     190                 :            : ID* install_ID(const char* name, const char* module_name,
     191                 :       8914 :                 bool is_global, bool is_export)
     192                 :            :         {
     193 [ -  + ][ #  # ]:       8914 :         if ( scopes.length() == 0 && ! is_global )
                 [ -  + ]
     194                 :          0 :                 internal_error("local identifier in global scope");
     195                 :            : 
     196                 :            :         IDScope scope;
     197 [ +  + ][ +  + ]:       8914 :         if ( is_export || ! module_name ||
         [ +  + ][ +  + ]
         [ +  + ][ #  # ]
                 [ +  + ]
     198                 :            :              (is_global &&
     199                 :            :               normalized_module_name(module_name) == GLOBAL_MODULE_NAME) )
     200                 :       4729 :                 scope = SCOPE_GLOBAL;
     201         [ +  + ]:       4185 :         else if ( is_global )
     202                 :        494 :                 scope = SCOPE_MODULE;
     203                 :            :         else
     204                 :       3691 :                 scope = SCOPE_FUNCTION;
     205                 :            : 
     206                 :       8914 :         string full_name_str = make_full_var_name(module_name, name);
     207                 :       8914 :         char* full_name = copy_string(full_name_str.c_str());
     208                 :            : 
     209                 :       8914 :         ID* id = new ID(full_name, scope, is_export);
     210         [ +  + ]:       8914 :         if ( SCOPE_FUNCTION != scope )
     211                 :       5223 :                 global_scope()->Insert(full_name, id);
     212                 :            :         else
     213                 :            :                 {
     214                 :       3691 :                 id->SetOffset(top_scope->Length());
     215                 :       3691 :                 top_scope->Insert(full_name, id);
     216                 :            :                 }
     217                 :            : 
     218                 :       8914 :         return id;
     219                 :            :         }
     220                 :            : 
     221                 :          0 : void push_existing_scope(Scope* scope)
     222                 :            :         {
     223                 :          0 :         scopes.append(scope);
     224                 :          0 :         }
     225                 :            : 
     226                 :       1128 : void push_scope(ID* id)
     227                 :            :         {
     228                 :       1128 :         top_scope = new Scope(id);
     229                 :       1128 :         scopes.append(top_scope);
     230                 :       1128 :         }
     231                 :            : 
     232                 :       1125 : Scope* pop_scope()
     233                 :            :         {
     234                 :       1125 :         int n = scopes.length() - 1;
     235         [ -  + ]:       1125 :         if ( n < 0 )
     236                 :          0 :                 internal_error("scope underflow");
     237                 :       1125 :         scopes.remove_nth(n);
     238                 :            : 
     239                 :       1125 :         Scope* old_top = top_scope;
     240                 :            :         // Don't delete the scope; keep it around for later name resolution
     241                 :            :         // in the debugger.
     242                 :            :         // ### SERIOUS MEMORY LEAK!?
     243                 :            :         // delete top_scope;
     244                 :            : 
     245         [ +  - ]:       1125 :         top_scope = n == 0 ? 0 : scopes[n-1];
     246                 :            : 
     247                 :       1125 :         return old_top;
     248                 :            :         }
     249                 :            : 
     250                 :       3190 : Scope* current_scope()
     251                 :            :         {
     252                 :       3190 :         return top_scope;
     253                 :            :         }
     254                 :            : 
     255                 :      17053 : Scope* global_scope()
     256                 :            :         {
     257                 :      17053 :         return scopes[0];
     258 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8