Resend ________________________________ From: Francoise Martinolle Sent: Friday, December 07, 2007 10:05 PM To: sv-bc@eda.org Subject: wildcard import name resolution This is a proposal to formally describe name resolution in presence of wildcard imports. I also included some examples that Gordon sent me to illustrate this formal description. This proposal is to replace the last couple of paragraphs in section 25.3. A wildcard import is of the following form: import ComplexPkg::*; For the purpose of describing how names resolve to wildcard imported declarations we define what is a locally visible and potentially visible name. Locally visible names are the names of locally visible declarations. A name is locally visible at some point, P, in a scope, S, if one of the following holds: 1. the name denotes a scope within S 2. the name is declared within S before point P 3. the name is visible from an import select occurring within S before point P A name is potentially locally visible at some point, P, in a scope, S, if : there exist a wildcard import of a package within scope S which contains a declaration of that name. Additionally a potentially locally visible symbol from a wild card import may become locally visible if no locally visible symbol is found and the resolution of an identifier causes the potentially locally visible name to become locally visible. The following paragraph describes how identifiers can be resolved to wildcard imported declarations. A wildcard import makes all identifiers declared within a package potential locally visible symbols in the importing scope, S A potentially locally visible symbol may become locally visible during name resolution in accordance to the following rules: If the identifier is not a function or task call, The following algorithm is repeated for each scope S until a declaration is found which matches the identifier name or there is no more lexical scopes. The compilation unit scope being the final scope searched. 1 - the locally visible declarations in scope S are first searched for a match, if a match is found the identifier is bound to that declaration 2- else if no locally visible symbol match, then the potentially locally visible symbols in the scope S, lexically preceding the identifier name are searched for a match. If a match is found, the symbol from the package is imported in scope S and becomes a locally visible declaration in scope S, that declaration is bound to the identifier. 3- else S is set to its upper scope If there is no more lexical scopes, and the identifier cannot be bound, an undeclared symbol error shall be issued. If the identifier is a function or task call, the rules are slightly different and follow upwards hierarchical name resolution (section 22.7). 1- First the entire scope S (all the declarations of locally visible names up to the end of the scope) is searched for a matching declaration, if a match, the identifier is resolved to that declaration, 2- else if no match is found, the wildcard import potentially locally visible symbols in scope , lexically preceding the identifier name are searched for a match, if a match is found, the potential visible symbol becomes locally visible, imported in scope S and bound to that identifier, 3- else of no match is found, the above algorithm steps 1, 2, 3 are repeated for the upper scope of S, including when S is the compilation unit scope. 4. else if no match, steps b and c of the upwards name resolution are executed (the function and task name are searched up the instance hierarchy). If the same name is potentially locally visible from more than one wildcard imported package in scope S, and those wildcard imports are lexically preceding an identifier of that name, the identifier shall be undefined within that scope. Example 1: package p; int x; endpackage module top; import p::*; // line 1 if (1) begin : b initial x = 1; // line 2 int x; // line 3 initial x = 1; // line 4 end int x; // line 5 endmodule The reference in line 2 causes "p::x" to become visible in top and line 2 initializes p::x. Line 4 initializes top.b.x. Line 5 is illegal since it conflicts with the name x imported from p. Example 2: package p; int x; endpackage package p2; int x; endpackage module top; import p::*; // line 1 if (1) begin : b initial x = 1; // line 2 import p2::*; // line 3 end endmodule line 2 causes the import of p::x because the wildcard import p::* is in the outer scope and precedes the occurrence of x. Example 3: package p; function int f(); return 1; endfunction endpackage module top; int x; if (1) begin : b initial x = f(); // line 2 import p::*; // line 3 end function int f(); return 1; endfunction endmodule "f" binds to top.f and not to p::f since the import is after the function reference. Do you agree? Example 4: package p; function int f(); return 1; endfunction endpackage package p2; function int f(); return 1; endfunction endpackage module top; import p::*; int x; if (1) begin : b initial x = f(); // line 1 end import p2::*; endmodule Since "f" is not found in scope b, the rules require inspection of all wildcard imports in the parent. There are two wildcard imports, but p::* occurs before the occurrence of f(). In this case "f" binds to p::f since the enclosing scope's reference occurs before the p2::* import. With the above formal description approved, mantis 1809 can be revised. Basically the wildcard import only would occur if it would be actually bound to an identifier. Currently 1809 imports symbols from wildcard imports which are not used. My revision of 1809 follows (striked sentences are in (green) ) 22.7.1 Task and Function name resolution Task and function names are resolved following slightly different rules than other references. (When a task or function name matches a potential name from a wildcard import, that name is imported as would normally occur. However, even when such an import occurs, a task or function name resolution does not necessarily bind to the imported name. ) Task and function name resolution follows the rules for upwards hierarchical name resolution as described in 22.7, step (a). Then, before proceeding with step (b), an implementation shall look in the complete compilation unit of the reference. If a task or function with a matching name is found there, the name resolves to that task or function. Only then does the resolution proceed with step (b) and iterate as normal. The special matching within the compilation unit shall only take place the first time through the iteration through steps (a)-(c); a task or function name shall never match a task or function in a compilation unit other than the compilation unit enclosing the reference. Example: task t; int x; x = f(1); // valid reference to function f in $unit scope endtask function int f(int y); return y+1; endfunction Example: package p; function void f(); $display("p::f"); endfunction endpackage module top; import p::*; if (1) begin : b // generate block initial f(); // reference to "f" function void f(); $display("top.b.f"); endfunction end endmodule (The reference to f in the initial block causes the identifier f to be imported into the scope of module top since there is no previously declared name f in the scopes enclosing the reference. However,) the resolution of the name f follows the hierarchical rules and therefore is resolved to the function top.b.f. The output of the example would be the output of the string "top.b.f". -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Tue Dec 11 02:08:54 2007
This archive was generated by hypermail 2.1.8 : Tue Dec 11 2007 - 02:09:50 PST