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) {
|
if (link->peek_chain_prefix() == 0) {
|
||||||
symbol_search_results sr;
|
symbol_search_results sr;
|
||||||
if (!symbol_search(link, des, scope, link->peek_path(),
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!sr.is_scope() || sr.scope->type() != NetScope::FUNC) {
|
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.
|
// Search for the symbol. This should turn up a scope.
|
||||||
symbol_search_results search_results;
|
symbol_search_results search_results;
|
||||||
bool search_flag = symbol_search(this, des, scope, path_, lexical_pos(),
|
bool search_flag = symbol_search(this, des, scope, path_, lexical_pos(),
|
||||||
&search_results, true);
|
&search_results,
|
||||||
|
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PECallFunction::test_width: "
|
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.
|
// Search for the symbol. This should turn up a scope.
|
||||||
symbol_search_results search_results;
|
symbol_search_results search_results;
|
||||||
bool search_flag = symbol_search(this, des, scope, path_, lexical_pos(),
|
bool search_flag = symbol_search(this, des, scope, path_, lexical_pos(),
|
||||||
&search_results, true);
|
&search_results,
|
||||||
|
SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PECallFunction::elaborate_expr: "
|
cerr << get_fileline() << ": PECallFunction::elaborate_expr: "
|
||||||
|
|
|
||||||
|
|
@ -3957,7 +3957,8 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
||||||
NetScope *task = nullptr;
|
NetScope *task = nullptr;
|
||||||
NetScope *func_scope = nullptr;
|
NetScope *func_scope = nullptr;
|
||||||
if (symbol_search(this, des, scope, call_path, lexical_pos(),
|
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(
|
if (!search_results.require_non_type(
|
||||||
this, des, "in a task or function call"))
|
this, des, "in a task or function call"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
||||||
12
netmisc.h
12
netmisc.h
|
|
@ -129,6 +129,11 @@ struct symbol_search_results {
|
||||||
pform_name_t path_head;
|
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
|
* 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
|
* 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,
|
extern bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||||
pform_name_t path, unsigned int lexical_pos,
|
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
|
/* 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,
|
extern bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||||
const pform_scoped_name_t &path,
|
const pform_scoped_name_t &path,
|
||||||
unsigned int lexical_pos,
|
unsigned int lexical_pos,
|
||||||
struct symbol_search_results *res,
|
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,
|
extern bool check_interface_modport_access(const LineInfo *li, Design *des,
|
||||||
const symbol_search_results &res,
|
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,
|
const LineInfo *li, Design *des, NetScope *scope,
|
||||||
NetScope *start_scope, const pform_name_t &path,
|
NetScope *start_scope, const pform_name_t &path,
|
||||||
const name_component_t &path_tail, unsigned int visibility_pos,
|
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
|
// Special case `super` keyword. Return the `this` object, but
|
||||||
// with the type of the base class.
|
// with the type of the base class.
|
||||||
|
|
@ -206,6 +206,12 @@ static scope_object_search_result_t symbol_search_scope_objects(
|
||||||
// been elaborated yet.
|
// been elaborated yet.
|
||||||
if (PWire *wire = scope->find_signal_placeholder(path_tail.name)) {
|
if (PWire *wire = scope->find_signal_placeholder(path_tail.name)) {
|
||||||
if (wire->lexical_pos() <= visibility_pos) {
|
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);
|
NetNet *net = wire->elaborate_sig(des, scope);
|
||||||
if (!net)
|
if (!net)
|
||||||
return scope_object_search_result_t::failed;
|
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,
|
pform_name_t path, unsigned int lexical_pos,
|
||||||
unsigned int prefix_lexical_pos,
|
unsigned int prefix_lexical_pos,
|
||||||
struct symbol_search_results *res,
|
struct symbol_search_results *res,
|
||||||
NetScope *start_scope, bool scope_is_bound)
|
NetScope *start_scope, bool scope_is_bound,
|
||||||
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
assert(scope);
|
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
|
// recursively. Ideally, the result is a scope that we search
|
||||||
// for the tail key, but there are other special cases as well.
|
// for the tail key, but there are other special cases as well.
|
||||||
if (! path.empty()) {
|
if (! path.empty()) {
|
||||||
|
const unsigned int prefix_flags =
|
||||||
|
flags & ~SYMBOL_SEARCH_ALLOW_FORWARD_REFERENCE;
|
||||||
bool flag = symbol_search_(li, des, scope, path,
|
bool flag = symbol_search_(li, des, scope, path,
|
||||||
prefix_lexical_pos,
|
prefix_lexical_pos,
|
||||||
prefix_lexical_pos, res,
|
prefix_lexical_pos, res,
|
||||||
start_scope, scope_is_bound);
|
start_scope, scope_is_bound, prefix_flags);
|
||||||
if (! flag)
|
if (! flag)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -460,7 +469,7 @@ static bool symbol_search_(const LineInfo *li, Design *des, NetScope *scope,
|
||||||
scope_object_search_result_t object_result =
|
scope_object_search_result_t object_result =
|
||||||
symbol_search_scope_objects(
|
symbol_search_scope_objects(
|
||||||
li, des, scope, start_scope, path, path_tail,
|
li, des, scope, start_scope, path, path_tail,
|
||||||
visibility_pos, res);
|
visibility_pos, res, flags);
|
||||||
if (object_result == scope_object_search_result_t::found)
|
if (object_result == scope_object_search_result_t::found)
|
||||||
return true;
|
return true;
|
||||||
if (object_result == scope_object_search_result_t::failed)
|
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,
|
bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||||
pform_name_t path, unsigned int lexical_pos,
|
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,
|
const bool allow_forward_reference =
|
||||||
res, scope, false);
|
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,
|
bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||||
const pform_scoped_name_t &path, unsigned int lexical_pos,
|
const pform_scoped_name_t &path, unsigned int lexical_pos,
|
||||||
struct symbol_search_results *res,
|
struct symbol_search_results *res, unsigned int flags)
|
||||||
bool allow_terminal_forward_reference)
|
|
||||||
{
|
{
|
||||||
NetScope *search_scope = scope;
|
NetScope *search_scope = scope;
|
||||||
bool scope_is_bound = false;
|
bool scope_is_bound = false;
|
||||||
|
|
@ -598,11 +611,13 @@ bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||||
scope_is_bound = true;
|
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;
|
? UINT_MAX : lexical_pos;
|
||||||
return symbol_search_(li, des, search_scope, path.name,
|
return symbol_search_(li, des, search_scope, path.name,
|
||||||
terminal_lexical_pos, lexical_pos, res,
|
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,
|
bool check_interface_modport_access(const LineInfo *li, Design *des,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue