Studying note of GCC-3.4.6 source (55)

4.3.1.7.4.            Create namespace “std”
4.3.1.7.4.1.      Add in global namespace

“std” namespace is part of the standaer. And this namespace is also part of the C++ runtime environment, for example, the exception mechanism, runtime type information, std standard library and etc. come out of this space. So next, it will create entity for this namespace and push it into global namespace. Here std_identifier is the unique identifier for std namespace, which has been created in initialize_predefined_identifiers.

 

cxx_init_decl_processing (continue)

 

2995     /* Create the `std' namespace.  */

2996     push_namespace (std_identifier);

2997     std_node = current_namespace;

2998     pop_namespace ();

 

Function push_namespace monopolizes the instantiation of std namespace, its addition to global namespace (more precisely, current namespace), and being current scope. Pay attention to line 3075 below, if name is null, the namespace is annoymous, which could only be accessed via below way:

namespace A {

   int x1;

   namespace {      // first annoymous namespace

      int x2;         // the only way to visit x2

      ... // definition

      namespace {  // another annoymous namespace

         ...

      }

   }

}

A::x1 = 5;              // no applicable to annoymous namespace

See that annoymous namespace at different level can coexist. Though annoymous namespace is nameless at side of user, the compiler must name it uniquely. anonymous_namespace_name is the name, which is also shared if there are more than one annoymous namespace. And, as annoymous namespace is only accessed in above way, sharing the same name will not cause any problem.

 

3059   void

3060   push_namespace (tree name)                                                             in name-lookup.c

3061   {

3062     tree d = NULL_TREE;

3063     int need_new = 1;

3064     int implicit_use = 0;

3065     bool anon = !name;

3066  

3067     timevar_push (TV_NAME_LOOKUP);

3068    

3069     /* We should not get here if the global_namespace is not yet constructed

3070       nor if NAME designates the global namespace: The global scope is

3071       constructed elsewhere.  */

3072     my_friendly_assert (global_namespace != NULL && name != global_scope_name,

3073                         20030531);

3074  

3075     if (anon)

3076     {

3077       /* The name of anonymous namespace is unique for the translation

3078         unit.  */

3079       if (!anonymous_namespace_name)

3080         anonymous_namespace_name = get_file_function_name ('N');

3081       name = anonymous_namespace_name;

3082       d = IDENTIFIER_NAMESPACE_VALUE (name);

3083       if (d)

3084         /* Reopening anonymous namespace.  */

3085         need_new = 0;

3086       implicit_use = 1;

3087     }

3088     else

3089     {

3090       /* Check whether this is an extended namespace definition.  */

3091       d = IDENTIFIER_NAMESPACE_VALUE (name);

3092       if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)

3093       {

3094         need_new = 0;

3095         if (DECL_NAMESPACE_ALIAS (d))

3096         {

3097           error ("namespace alias `%D' not allowed here, assuming `%D'",

3098                d, DECL_NAMESPACE_ALIAS (d));

3099           d = DECL_NAMESPACE_ALIAS (d);

3100         }

3101       }

3102     }

 

As soon as getting the name, the duty is passed to IDENTIFIER_NAMESPACE_VALUE.

 

264    #define IDENTIFIER_NAMESPACE_VALUE(NODE) /                             in cp-tree.h

265      namespace_binding ((NODE), current_namespace)

 

The name of current_namespace beguiles, in fact, this macro returns the namespace currently in used or last in used (current scope is not of namespace).

 

719    #define current_namespace scope_chain->old_namespace                             in cp-tree.h

 

Note for global namespace, scope_chain is an empty node, so current_namespace returns null. This special value in namespace searching means the global namespace.

 

2943   tree

2944   namespace_binding (tree name, tree scope)                                         in name-lookup.c

2945   {

2946     cxx_binding *binding;

2947  

2948     if (scope == NULL)

2949       scope = global_namespace;

2950     scope = ORIGINAL_NAMESPACE (scope);

2951     binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);

2952  

2953     return binding ? binding->value : NULL_TREE;

2954   }

 

For any sort of a *_DECL node, field abstract_origin points to the original (abstract) decl node which this decl is an instance of, or else it is NULL indicating that this decl is not an instance of some other decl. For below example, in a nested declaration of the inline function f, this field points back to the definition (this code snippet can’t pass compilation as the nested f hasn’t been defined).

inline int f (void) { return 0; }
int main (void)
{
  int f();
  return f ();
}

 

2090   #define DECL_NAMESPACE_ALIAS(NODE) /                                        in cp-tree.h

2091        DECL_ABSTRACT_ORIGIN (NAMESPACE_DECL_CHECK (NODE))

2092   #define ORIGINAL_NAMESPACE(NODE)  /

2093     (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE))

 

1407   #define DECL_ABSTRACT_ORIGIN(NODE) (DECL_CHECK (NODE)->decl.abstract_origin)

 

ORIGINAL_NAMESPACE relates to the feature of namespace-alias of C++. According to [3], namespace-alias has following rules:

1. A namespace-alias-definition declares an alternate name for a namespace according to the following grammar:

namespace-alias:

identifier

namespace-alias-definition:

namespace identifier = qualified-namespace-specifier ;

qualified-namespace-specifier:

::opt nested-name-specifieropt namespace-name

2. The identifier in a namespace-alias-definition is a synonym for the name of the namespace denoted by the qualified-namespace-specifier and becomes a namespace-alias. [Note: when looking up a namespace-name (Note: includes both original-namespace-name and namespace-alias) in a namespace-alias-definition, only namespace names are considered, see 3.4.6. ]

3. In a declarative region, a namespace-alias-definition can be used to redefine a namespace-alias declared in that declarative region to refer only to the namespace to which it already refers. [Example: the following declarations are well-formed:

namespace Company_with_very_long_name { /* ... */ }

namespace CWVLN = Company_with_very_long_name;

namespace CWVLN = Company_with_very_long_name; // OK: duplicate

namespace CWVLN = CWVLN;

4. A namespace-name or namespace-alias shall not be declared as the name of any other entity in the same declarative region. A namespace-name defined at global scope shall not be declared as the name of any other entity in any global scope of the program. No diagnostic is required for a violation of this rule by declarations in different translation units.

Above at line 2950, ORIGNINAL_NAMESPACE returns the namepsace (instead of namespace-alias), then NAMESPACE_LEVEL returns the corresponding cp_binding_level instance, that is the scope object of the namespace. In current implement, this function is used for searching within namespace scope.

 

1587   NAMESPACE_LEVEL #define NAMESPACE_LEVEL(NODE) /                in cp-tree.h

1588     (DECL_LANG_SPECIFIC (NODE)->decl_flags.u.level)

 

1444   #define DECL_LANG_SPECIFIC(NODE) (DECL_CHECK (NODE)->decl.lang_specific)

 

Function cxx_scope_find_binding_for_name searches within the scope specified by scope for declaration of name, and returns the matching cxx_binding instance.

 

1877   static inline cxx_binding *

1878   cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)               in name-lookup.c

1879   {

1880     cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);

1881     if (b)

1882     {

1883       /* Fold-in case where NAME is used only once.  */

1884       if (scope == b->scope && b->previous == NULL)

1885         return b;

1886       return find_binding (scope, b);

1887     }

1888     return NULL;

1889   }

 

IDENTIFIER_NAMESPACE_BINDINGS accesses field namespace_bindings of the identifier, which records all declarations of the name in namespaces (note, in C++, namespaces form the outmost scopes, it can’t be defined within class scope, nor within funciton scope). Identifier also has field bindings, which denotes from innermost scope and concatenated with namespace_bindings.

 

369    #define IDENTIFIER_NAMESPACE_BINDINGS(NODE)    /                    in cp-tree.h

370      (LANG_IDENTIFIER_CAST (NODE)->namespace_bindings)

 

238    #define LANG_IDENTIFIER_CAST(NODE) /

339         ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE))          in cp-tree.h

 

We have known that in identifier, cxx_binding chains declarations of same name together, function find_bindings finds out the instance of cxx_binding of the declaration in the scope specified by parameter scope.

 

1863 static inline cxx_binding *

1864 find_binding (cxx_scope *scope, cxx_binding *binding)                        in name-lookup.c

1865 {

1866   timevar_push (TV_NAME_LOOKUP);

1867

1868   for (; binding != NULL; binding = binding->previous)

1869     if (binding->scope == scope)

1870       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding);

1871

1872   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0);

1873 }

 

Namespace alias can’t be used in defining namespace, for example:

namespace A { .. }

namespace aliasA = A;

namespace aliasA { ... } // error: namespace alias “aliasA” not allowed here, assuming “A”

will trigger error message at line 3097. At line 3099, the compiler corrects this error to be able to catch more errors.

And push_namespace continues below operation with the searching result.

 

push_namespace (continue)

 

3104     if (need_new)

3105     {

3106       /* Make a new namespace, binding the name to it.  */

3107       d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);

3108       DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);

3109       d = pushdecl (d);

3110       if (anon)

3111       {

3112         /* Clear DECL_NAME for the benefit of debugging back ends.  */

3113         SET_DECL_ASSEMBLER_NAME (d, name);

3114         DECL_NAME (d) = NULL_TREE;

3115       }

3116       begin_scope (sk_namespace, d);

3117     }

3118     else

3119       resume_scope (NAMESPACE_LEVEL (d));

3120  

3121     if (implicit_use)

3122       do_using_directive (d);

3123    /* Enter the name space.  */

3124     current_namespace = d;

3125  

3126     timevar_pop (TV_NAME_LOOKUP);

3127   }

 

If the namespace has been in the current namespace (that is d at line 3091 is not NULL), then it only needs to set it as current scope (ie., line 1414).

 

1406 static void

1407 resume_scope (struct cp_binding_level* b)                                                  in name-lookup.c

1408 {

1409   /* Resuming binding levels is meant only for namespaces,

1410     and those cannot nest into classes.  */

1411   my_friendly_assert(!class_binding_level, 386);

1412   /* Also, resuming a non-directly nested namespace is a no-no.  */

1413   my_friendly_assert(b->level_chain == current_binding_level, 386);

1414   current_binding_level = b;

1415   if (ENABLE_SCOPE_CHECKING)

1416   {

1417       b->binding_depth = binding_depth;

1418       indent (binding_depth);

1419       cxx_scope_debug (b, input_location.line, "resume");

1420       is_class_level = 0;

1421       binding_depth++;

1422   }

1423 }

 

Otherwise invokes pushdecl to push the namespace into current scope.

 

566    tree

567    pushdecl (tree x)                                                                                     in name-lookup.c

568    {

569      tree t;

570      tree name;

571      int need_new_binding;

572   

573      timevar_push (TV_NAME_LOOKUP);

574   

575      need_new_binding = 1;

        ...

604      name = DECL_NAME (x);

605      if (name)

606      {

607        int different_binding_level = 0;

608   

609        if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))

610          check_default_args (x);

611    

612        if (TREE_CODE (name) == TEMPLATE_ID_EXPR)

613          name = TREE_OPERAND (name, 0);

614   

615        /* In case this decl was explicitly namespace-qualified, look it

616          up in its namespace context.  */

617       if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())

618          t = namespace_binding (name, DECL_CONTEXT (x));

619        else

620          t = lookup_name_current_level (name);

 

At line 617 namespace_bindings_p finds out if current scope is contained in a namespace. And DECL_NAMESPACE_SCOPE_P if nonzero, indicates the adding entity is a namespace declaration.

 

1482   bool

1483   namespace_bindings_p (void)                                                            in name-lookup.c

1484   {

1485     struct cp_binding_level *b = innermost_nonclass_level ();

1486  

1487     return b->kind == sk_namespace;

1488   }

 

1427   static cxx_scope *

1428   innermost_nonclass_level (void)                                                        in name-lookup.c

1429   {

1430     cxx_scope *b;

1431  

1432     b = current_binding_level;

1433     while (b->kind == sk_class)

1434       b = b->level_chain;

1435  

1436     return b;

1437   }

 

DECL_CONTEXT (x) at line 168 points to the context containing x. If DECL_CONTEXT is NULL, indicates the context is global namespace. As namespace_binding will return t with NULL, then following code snippet will be executed.

 

pushdecl (continue)

 

828        /* This name is new in its binding level.

829          Install the new declaration and return it.  */

830        if (namespace_bindings_p ())

831        {

832          /* Install a global value.  */

833

834         /* If the first global decl has external linkage,

835            warn if we later see static one.  */

836          if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))

837            TREE_PUBLIC (name) = 1;

838

839          /* Bind the name for the entity.  */

840          if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)

841              && t != NULL_TREE)

842                && (TREE_CODE (x) == TYPE_DECL

843                    || TREE_CODE (x) == VAR_DECL

844                    || TREE_CODE (x) == ALIAS_DECL

845                    || TREE_CODE (x) == NAMESPACE_DECL

846                    || TREE_CODE (x) == CONST_DECL

847                    || TREE_CODE (x) == TEMPLATE_DECL))

848            SET_IDENTIFIER_NAMESPACE_VALUE (name, x);

            ...

872        }

873        else

874        {

            ...

1003       }

1004      

1005       if (TREE_CODE (x) == VAR_DECL)

1006         maybe_register_incomplete_var (x);

1007     }

1008     

1009     if (need_new_binding)

1010       add_decl_to_level (x,

1011                      DECL_NAMESPACE_SCOPE_P (x)

1012                      ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))

1013                      : current_binding_level);

1014  

1015     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);

1016   }

 

Above IDENTIFIER_GLOBAL_VALUE, and SET_IDENTIFIER_NAMESPACE_VALUE has following definitions. And in an IDENTIFIER_NODE (corresponds to name, while x corresponds to declaration), TREE_PUBLIC if nonzero means an external declaration accessible from outside this module was previously seen for this name in an inner scope.

 

264  #define IDENTIFIER_GLOBAL_VALUE(NODE) /                                      in cp-tree.h

265    namespace_binding ((NODE), global_namespace)

266  #define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) /               in cp-tree.h

267    set_namespace_binding ((NODE), current_namespace, (VAL))

 

Function set_namespace_binding may create node of cxx_binding, then bind declaration with scope together. In it, parameter val is the declaration, name is the identifier, and scope is the binding scope.

 

2958   void

2959   set_namespace_binding (tree name, tree scope, tree val)                       in name-lookup.c

2960   {

2961     cxx_binding *b;

2962  

2963     timevar_push (TV_NAME_LOOKUP);

2964     if (scope == NULL_TREE)

2965       scope = global_namespace;

2966     b = binding_for_name (NAMESPACE_LEVEL (scope), name);

2967     if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)

2968       b->value = val;

2969     else

2970       supplement_binding (b, val);

2971     timevar_pop (TV_NAME_LOOKUP);

2972   }

 

Function binding_for_name is also just used for binding declaration within namespace. In below, if it’s a new declaration, its cxx_binding will be inserted at the head of namespace_bindings of the matching identifier.

 

1894   static cxx_binding *

1895   binding_for_name (cxx_scope *scope, tree name)                                in name-lookup.c

1896   {

1897     cxx_binding *result;

1898  

1899     result = cxx_scope_find_binding_for_name (scope, name);

1900     if (result)

1901       return result;

1902     /* Not found, make a new one.  */

1903     result = cxx_binding_make (NULL, NULL);

1904     result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);

1905     result->scope = scope;

1906     result->is_local = false;

1907     result->value_is_inherited = false;

1908     IDENTIFIER_NAMESPACE_BINDINGS (name) = result;

1909     return result;

1910   }

 

Field value of the cxx_binding returned by binding_for_name is null, as in cxx_binding_make below, notice that parameter value and type are both null. After returning set_namespace_binding, field value is set as the declaration node.

 

326    static cxx_binding *

327    cxx_binding_make (tree value, tree type)                                            in name-lookup.c

328    {

329      cxx_binding *binding;

330      if (free_bindings)

331      {

332        binding = free_bindings;

333        free_bindings = binding->previous;

334      }

335      else

336        binding = ggc_alloc (sizeof (cxx_binding));

337   

338      binding->value = value;

339      binding->type = type;

340      binding->previous = NULL;

341   

342      return binding;

343    }

 

Generally, more than one declarations of same name declared within the same scope means grammar error. But [2] gives an exception:

A class name (9.1) or enumeration name (7.2) can be hidden by the name of an object, function, or enumerator declared in the same scope. If a class or enumeration name and an object, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the object, function, or enumerator name is visible.

Function supplement_binding is defined for the exception, we come it later.

At line 1009 in pushdecl, need_new_binding is set as 1. In add_decl_to_level, node of namespace declaration is linked into namespaces field of corresponding cxx_scope node, and line 532 handles case of vtable, and line 537 processes the other non-namespace declarations.

 

523    static void

524    add_decl_to_level (tree decl, cxx_scope *b)                                        in name-lookup.c

525    {

526      if (TREE_CODE (decl) == NAMESPACE_DECL

527          && !DECL_NAMESPACE_ALIAS (decl))

528      {

529        TREE_CHAIN (decl) = b->namespaces;

530        b->namespaces = decl;

531      }

532      else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))

533      {

534        TREE_CHAIN (decl) = b->vtables;

535        b->vtables = decl;

536      }

537      else      

538      {

539        /* We build up the list in reverse order, and reverse it later if

540          necessary.  */

541        TREE_CHAIN (decl) = b->names;

542        b->names = decl;

543        b->names_size++;

544   

545        /* If appropriate, add decl to separate list of statics. We

546          include extern variables because they might turn out to be

547          static later. It's OK for this list to contain a few false

548          positives. */

549        if (b->kind == sk_namespace)

550          if ((TREE_CODE (decl) == VAR_DECL

551               && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))

552             || (TREE_CODE (decl) == FUNCTION_DECL

553               && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))

554            VARRAY_PUSH_TREE (b->static_decls, decl);

555     }

556    }

 

Figure 34: namespace std and global namespace

Arriving here, we can see part of relation between namespace std and global in above figure.

4.3.1.7.4.1.      Exit the namespace scope

As soon as the NAMESPACE_DECL of std_identifier and the associated binding context created, std_node is assignment with this NAMESPACE_DECL, from the figure above, departing from this node, it can easily move to contained and containing scope. After that, it needs to restore back to global namespace by pop_namespace.

 

3131   void

3132   pop_namespace (void)                                                                       in name-lookup.c

3133   {

3134     my_friendly_assert (current_namespace != global_namespace, 20010801);

3135     current_namespace = CP_DECL_CONTEXT (current_namespace);

3136     /* The binding level is not popped, as it might be re-opened later.  */

3137     leave_scope ();

3138   }

 

leave_scope returns back upper scope and sets it as current scope. At line 1356, class_binding_level points to the innermost class scope in effective. If condition at line 1356 is satisfied, means we are exitting the definition of the namespace, and at the same time we are within a class definition, which almost indicates error (as class_binding_level if not null, will set is_class_level, and gives out error message at line 1370). Under such situation, the compiler tries to fix current_binding_level, but at line 1376 below, current_binding_level will be revised again and makes the change at line 1357 meaningless.

 

1351   cxx_scope *

1352   leave_scope (void)                                                                            in name-lookup.c

1353   {

1354     cxx_scope *scope = current_binding_level;

1355  

1356     if (scope->kind == sk_namespace && class_binding_level)

1357       current_binding_level = class_binding_level;

1358  

1359    /* We cannot leave a scope, if there are none left.  */

1360     if (NAMESPACE_LEVEL (global_namespace))

1361       my_friendly_assert (!global_scope_p (scope), 20030527);

1362    

1363     if (ENABLE_SCOPE_CHECKING)

1364     {

1365       indent (--binding_depth);

1366       cxx_scope_debug (scope, input_location.line, "leave");

1367       if (is_class_level != (scope == class_binding_level))

1368       {

1369         indent (binding_depth);

1370         verbatim ("XXX is_class_level != (current_scope == class_scope)/n");

1371       }

1372      is_class_level = 0;

1373     }

1374  

1375     /* Move one nesting level up.  */

1376     current_binding_level = scope->level_chain;

1377  

1378     /* Namespace-scopes are left most probably temporarily, not completely;

1379      they can be reopen later, e.g. in namespace-extension or any name

1380       binding activity that requires us to resume a namespace. For other

1381       scopes, we just make the structure available for reuse.  */

1382     if (scope->kind != sk_namespace)

1383     {

1384       scope->level_chain = free_binding_level;

1385       if (scope->kind == sk_class)

1386         scope->type_decls = NULL;

1387       else

1388         binding_table_free (scope->type_decls);

1389       my_friendly_assert (!ENABLE_SCOPE_CHECKING

1390                             || scope->binding_depth == binding_depth,

1391                             20030529);

1392       free_binding_level = scope;

1393     }

1394  

1395    /* Find the innermost enclosing class scope, and reset

1396       CLASS_BINDING_LEVEL appropriately.  */

1397     for (scope = current_binding_level;

1398          scope && scope->kind != sk_class;

1399          scope = scope->level_chain)

1400       ;

1401     class_binding_level = scope && scope->kind == sk_class ? scope : NULL;

1402  

1403     return current_binding_level;

1404   }

 

Note line 1382, if the scope isn’t namespace, the object would be freed to free_binding_level. But not is namespace. It because namespaces forms the outtestmost scopes, it almost can ensure they would be entered again later; and all namespaces’ scope are reserved, so are relations among them, which speeds up the searching these objects hereafter. It is why in IDENTIFIER_NODE, there is pointer namespace_bindings. The reason not reserving non-namespace scope object may be: 1) Such objects are in great number, especially when we designe lots of classes, functions and {} blocks; 2) Most of which would be only visited once – it is true for functions and {} blocks. In this way, it keeps the tree of scopes as neat as possible, so as to reduce the possibility of introducing bug, and lowers the memory consumption. And at the same time, it makes reentering these non-namepsace scopes simply – just adding these object into scope tree again.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值