symbol_search(): Add lookup flags
`symbol_search()` currently uses a boolean argument to allow forward references to the terminal name. Additional lookup options would require more boolean arguments and make call sites difficult to read. Replace the boolean with a bitmask and use a named flag at the existing forward-reference call sites. Add a second flag that stops lookup at an unelaborated signal instead of elaborating it. Stopping the lookup makes the signal continue to hide matching symbols in outer scopes. Forward-reference permission applies only to the terminal name, while signal elaboration suppression applies to the complete path. This allows callers that only need to classify a name to avoid triggering signal elaboration during lookup. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
9a2106a439
commit
a7e258fad1
|
|
@ -310,7 +310,8 @@ static const netclass_t* resolve_call_chain_prefix_class(Design*des, NetScope*sc
|
|||
if (link->peek_chain_prefix() == 0) {
|
||||
symbol_search_results sr;
|
||||
if (!symbol_search(link, des, scope, link->peek_path(),
|
||||
link->lexical_pos(), &sr, true)) {
|
||||
link->lexical_pos(), &sr,
|
||||
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE)) {
|
||||
return 0;
|
||||
}
|
||||
if (!sr.is_scope() || sr.scope->type() != NetScope::FUNC) {
|
||||
|
|
@ -2102,7 +2103,8 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
|
|||
// Search for the symbol. This should turn up a scope.
|
||||
symbol_search_results search_results;
|
||||
bool search_flag = symbol_search(this, des, scope, path_, lexical_pos(),
|
||||
&search_results, true);
|
||||
&search_results,
|
||||
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::test_width: "
|
||||
|
|
@ -3242,7 +3244,8 @@ NetExpr* PECallFunction::elaborate_expr_(Design*des, NetScope*scope,
|
|||
// Search for the symbol. This should turn up a scope.
|
||||
symbol_search_results search_results;
|
||||
bool search_flag = symbol_search(this, des, scope, path_, lexical_pos(),
|
||||
&search_results, true);
|
||||
&search_results,
|
||||
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_expr: "
|
||||
|
|
|
|||
|
|
@ -3957,7 +3957,8 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
NetScope *task = nullptr;
|
||||
NetScope *func_scope = nullptr;
|
||||
if (symbol_search(this, des, scope, call_path, lexical_pos(),
|
||||
&search_results, true)) {
|
||||
&search_results,
|
||||
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE)) {
|
||||
if (!search_results.require_non_type(
|
||||
this, des, "in a task or function call"))
|
||||
return nullptr;
|
||||
|
|
|
|||
12
netmisc.h
12
netmisc.h
|
|
@ -129,6 +129,11 @@ struct symbol_search_results {
|
|||
pform_name_t path_head;
|
||||
};
|
||||
|
||||
enum symbol_search_flag_t {
|
||||
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE = 1U << 0,
|
||||
SYMBOL_SEARCH_NO_SIGNAL_ELABORATION = 1U << 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Test the search results and return true if this represents a function
|
||||
* return value. That will be the case if the object is a net, the scope
|
||||
|
|
@ -145,15 +150,16 @@ static inline bool test_function_return_value(const symbol_search_results&search
|
|||
|
||||
extern bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||
pform_name_t path, unsigned int lexical_pos,
|
||||
struct symbol_search_results *res);
|
||||
struct symbol_search_results *res,
|
||||
unsigned int flags = 0);
|
||||
|
||||
/* The forward-reference flag applies only to the terminal name. Prefix
|
||||
components still use lexical_pos. */
|
||||
components still use lexical_pos. Other flags apply to the complete path. */
|
||||
extern bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||
const pform_scoped_name_t &path,
|
||||
unsigned int lexical_pos,
|
||||
struct symbol_search_results *res,
|
||||
bool allow_terminal_forward_reference = false);
|
||||
unsigned int flags = 0);
|
||||
|
||||
extern bool check_interface_modport_access(const LineInfo *li, Design *des,
|
||||
const symbol_search_results &res,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ static scope_object_search_result_t symbol_search_scope_objects(
|
|||
const LineInfo *li, Design *des, NetScope *scope,
|
||||
NetScope *start_scope, const pform_name_t &path,
|
||||
const name_component_t &path_tail, unsigned int visibility_pos,
|
||||
struct symbol_search_results *res)
|
||||
struct symbol_search_results *res, unsigned int flags)
|
||||
{
|
||||
// Special case `super` keyword. Return the `this` object, but
|
||||
// with the type of the base class.
|
||||
|
|
@ -206,6 +206,12 @@ static scope_object_search_result_t symbol_search_scope_objects(
|
|||
// been elaborated yet.
|
||||
if (PWire *wire = scope->find_signal_placeholder(path_tail.name)) {
|
||||
if (wire->lexical_pos() <= visibility_pos) {
|
||||
if (flags & SYMBOL_SEARCH_NO_SIGNAL_ELABORATION) {
|
||||
// The signal still hides matching symbols in outer
|
||||
// scopes. Stop the lookup without elaborating it.
|
||||
return scope_object_search_result_t::failed;
|
||||
}
|
||||
|
||||
NetNet *net = wire->elaborate_sig(des, scope);
|
||||
if (!net)
|
||||
return scope_object_search_result_t::failed;
|
||||
|
|
@ -322,7 +328,8 @@ static bool symbol_search_(const LineInfo *li, Design *des, NetScope *scope,
|
|||
pform_name_t path, unsigned int lexical_pos,
|
||||
unsigned int prefix_lexical_pos,
|
||||
struct symbol_search_results *res,
|
||||
NetScope *start_scope, bool scope_is_bound)
|
||||
NetScope *start_scope, bool scope_is_bound,
|
||||
unsigned int flags)
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
|
|
@ -349,10 +356,12 @@ static bool symbol_search_(const LineInfo *li, Design *des, NetScope *scope,
|
|||
// recursively. Ideally, the result is a scope that we search
|
||||
// for the tail key, but there are other special cases as well.
|
||||
if (! path.empty()) {
|
||||
const unsigned int prefix_flags =
|
||||
flags & ~SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE;
|
||||
bool flag = symbol_search_(li, des, scope, path,
|
||||
prefix_lexical_pos,
|
||||
prefix_lexical_pos, res,
|
||||
start_scope, scope_is_bound);
|
||||
start_scope, scope_is_bound, prefix_flags);
|
||||
if (! flag)
|
||||
return false;
|
||||
|
||||
|
|
@ -460,7 +469,7 @@ static bool symbol_search_(const LineInfo *li, Design *des, NetScope *scope,
|
|||
scope_object_search_result_t object_result =
|
||||
symbol_search_scope_objects(
|
||||
li, des, scope, start_scope, path, path_tail,
|
||||
visibility_pos, res);
|
||||
visibility_pos, res, flags);
|
||||
if (object_result == scope_object_search_result_t::found)
|
||||
return true;
|
||||
if (object_result == scope_object_search_result_t::failed)
|
||||
|
|
@ -577,16 +586,20 @@ static bool symbol_search_(const LineInfo *li, Design *des, NetScope *scope,
|
|||
|
||||
bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||
pform_name_t path, unsigned int lexical_pos,
|
||||
struct symbol_search_results *res)
|
||||
struct symbol_search_results *res, unsigned int flags)
|
||||
{
|
||||
return symbol_search_(li, des, scope, path, lexical_pos, lexical_pos,
|
||||
res, scope, false);
|
||||
const bool allow_forward_reference =
|
||||
flags & SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE;
|
||||
const unsigned int terminal_lexical_pos = allow_forward_reference
|
||||
? UINT_MAX : lexical_pos;
|
||||
return symbol_search_(li, des, scope, path, terminal_lexical_pos,
|
||||
lexical_pos,
|
||||
res, scope, false, flags);
|
||||
}
|
||||
|
||||
bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||
const pform_scoped_name_t &path, unsigned int lexical_pos,
|
||||
struct symbol_search_results *res,
|
||||
bool allow_terminal_forward_reference)
|
||||
struct symbol_search_results *res, unsigned int flags)
|
||||
{
|
||||
NetScope *search_scope = scope;
|
||||
bool scope_is_bound = false;
|
||||
|
|
@ -598,11 +611,13 @@ bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
|||
scope_is_bound = true;
|
||||
}
|
||||
|
||||
const unsigned int terminal_lexical_pos = allow_terminal_forward_reference
|
||||
const bool allow_forward_reference =
|
||||
flags & SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE;
|
||||
const unsigned int terminal_lexical_pos = allow_forward_reference
|
||||
? UINT_MAX : lexical_pos;
|
||||
return symbol_search_(li, des, search_scope, path.name,
|
||||
terminal_lexical_pos, lexical_pos, res,
|
||||
search_scope, scope_is_bound);
|
||||
search_scope, scope_is_bound, flags);
|
||||
}
|
||||
|
||||
bool check_interface_modport_access(const LineInfo *li, Design *des,
|
||||
|
|
|
|||
Loading…
Reference in New Issue