[sv-bc] name resolution (some rules for consideration)

From: Gordon Vreugdenhil <gordonv_at_.....>
Date: Sun Jun 03 2007 - 16:59:52 PDT
The following is a set of provisional rules that came out
of some discussion that I had with people at Cadence when
I was in Chelmsford a while ago.  They provoked considerable
discussion (at very long tangents) and are certainly neither
complete nor cover all edge cases (array manipulators are one
problematic area but can be extrapolated from the approaches
taken in these rules).  It was suggested that I post these
generally to the group.

Please understand that this is mostly my set of "what do I
think we should try to formalize" rules.  I have not had
anyone make definitive suggestions or refinements to these
so I can't really judge where others are on the suggestions.

In any case, these form the basis for my answers to my
"quiz" post coming up.

Gord.



1. When a scope is finished its compilation, it is closed - no more symbol
    introduction.  The only exception is that an elaboration time "bind"
    can introduce additional instance names and implicit net names into
    the target scope.

    Implication -- external references, extern tasks, etc. cannot introduce
    new names.  The set of imported names is known when the "end" of the
    scope is encountered.


2. within a method, an identifier reference is resolved by doing searches
    in the following order:
       1. bind into the local scope (upwards to the method declaration)
       1. bind into the local class
       2. bind to any inherited names
       3. bind following normal lexical/import/hierarchy rules in the parent
          scope of the local class decl

3) for a package or class prefix, if a matching class name is visible, the
    class is the context, the package is last.

    Example:

        package C;
           int x;
        endpackage
        class C;
           static int x;
        endclass
        module top;
           int y = C::x;   // binds to visible class C not package C
        endmodule

4) package or class prefix names never back tracks in search
    (i.e. once you have matched a "<name>::" prefix, you will never
     back up and try again)

    Example:

        package C;
           int y;
        endpackage
        class C;
           static int x;
        endclass
        module top;
           int z= C::y;   // error -- "y" doesn't exist in class C
        endmodule



5) in a dotted name, if the first/next name binds to a declaration that MAY
    permit a dot select , no backtracking occurs.

    The "may" here is important.  The basic rationale of Steven and I is that
    we'd like to get rid of backtracking in the resolution other than in
    cases that are required for legacy support.

    The following is a legacy example:

       module top;
         integer x;
         child c();
       endmodule
       module child;
         integer top;
         initial top.x = 5;  // resolves to $root.top.x
       endmodule

     The following is a problematic case:

       module top;
         integer x;
         child c();
       endmodule

       module child #(type parameter T = int);
         T top;
         initial top.x = 5;    // error at elab since "top.x" is required to
                               // resolve into "T top"; is "T" is not a structure
                               // type with an "x" this becomes an elab error
       endmodule


6) In a hierarchical name, once a "bit select" is matched to a scope that permits
    a bit select, no backtracking

    This means that once you've matched, for example, an arrayed generate name
    or an arrayed instance, you never backtrack upwards.



7) all class members are visible to the body of extern methods


     Example:

         class C;
           extern task foo;
           int x;
         endclass

         int x;
         extern task C::foo;
             x = 1;   // means this.x = 1
         end


     Implication:

         package p;
            int x;
         endpackage

         import p::*;

         class C;
           task foo;
               x = 1;   // means p::x
           end
           int x;
         endclass


8) An extern class method with a reference to an identifier that resolves
    outside the method (including other class members) shall resolve the
    identifier based on the point of declaration of the extern method.

    Example:

         package p;
            int x;
         endpackage

         import p::*;

         class C;
           extern task foo;
         endclass

         int x;
         extern task C::foo;
             x = 1;   // means $unit.x and not p::x
         end


     This is related to rule (1).  If one would want to treat the "x = 1"
     reference as p::x then you have to "go back" and determine that
     the "int x" declaration is an illegal conflict.  There should be
     no "going back" requirement.


-- 
--------------------------------------------------------------------
Gordon Vreugdenhil                                503-685-0808
Model Technology (Mentor Graphics)                gordonv@model.com


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Sun Jun 3 17:00:13 2007

This archive was generated by hypermail 2.1.8 : Sun Jun 03 2007 - 17:00:39 PDT