This only applies to simple identifiers. Only return a match if the
lexical position of the identifier being searched is later in the
source text than the lexical position of a matching symbol.
Most places in the code use a std::vector for array dimensions.
The only exception is the constructor of NetNet, which uses
a `std::list` to pass the unpacked dimensions. But to store the
unpacked dimensions it also uses a `std::vector`.
There does not seem to be a good reason why the constructor
has to take a `std::list`, so switch it also to `std::vector`.
This allows to simplify the code and remove some special handling
for `std::list<netrange_t>`.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
`std::vector<netrange_t>` is used for signal array dimensions. As such it is
used in quite a few places.
Add a typedef that can be used as a shorthand to refer to it. This helps to
keep lines where this is used from growing to overly long.
The new type is called `netranges_t`.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Package scoped identifiers should only be able to access identifiers that
are declared in the package, but not identifiers that are visible in the
package, but declared outside of it.
```
int x;
package P;
int y;
endpackage
module test;
initial begin
$display(P::x); // Should fail
$display(P::y); // OK
end
endmodule
```
Make sure that the symbol search will not attempt to cross the package
boundary during identifier lookup.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
In SystemVerilog identifiers can usually have an additional package scope
in which they should be resolved. At the moment there are many places in
the code base that handle the resolution of the package scope.
Add a common data type for package scoped paths as well as a
symbol_search() variant that works on package scoped identifiers. This
allows to handle package scope resolution in a central place.
Having the code in a central place makes it easier to ensure consistent and
correct behavior. E.g. there are currently some corner case bugs that are
common to all implementations. With the common implementation it only has
to be fixed in one place.
It will also make it easier to eventually implement class scoped
identifiers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There are currently two mechanisms for handling class properties. One that
is used when a class property is accessed through an object and other when
a class property is used freestanding in a class method.
Both are very similar, but there are some small differences. E.g. one
supports arrays, the other supports nested properties.
```
class B;
int x;
endclass
class C;
B b;
B ba[2];
task t;
ba[0] = new; // Does work
this.ba[0] = new; // Does not work
b.x = 10; // Does not work
this.b.x = 10; // Does work
endtask
```
There is another problem where free standing properties take precedence
over local variables. E.g.
```
class C;
int x = 1;
task t();
int x = 2;
$display(x); // Should print 2, will print 1
endtask
endclass
```
The class property elaboration also ignores the package scope of the
identifier resulting in access to a class property being elaborated if
there is a property of the same name as the scoped identifier. E.g.
```
package P;
int x = 2;
endpackage
class C;
int x = 1;
task t;
$display(P::x); // Should print 2, will print 1
endtask
endclass
```
Consolidate the two implementation to use the same code path. This is
mainly done by letting the symbol search return a result for free standing
properties as if the property had been specified on the `this` object. I.e.
`prop` and `this.prop` will return the same result from the symbol search.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There are no users of the old symbol_search that need the cls_val result.
Remove it as a output parameter of the function.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
SystemVerilog allows to use the `super` keyword to access properties and
methods of a base class. This is useful if there is for example an
identifier with the same name in the current class as in the base class and
the code wants to access the base class identifier.
To support this a bit of refactoring is required. Currently properties are
internally referenced by name, this does not work if there are multiple
properties of the same. Instead reference properties always by index.
In addition when looking up an identifier that resolves to an object return
both the type and the object itself. This is necessary since both `this`
and `super` resolve to the same object, but each with a different type.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The expressions within an array assignment pattern should be evaluated in a
context that is equivalent to an assignment to a variable of the element
type of the l-value array.
This is defined in section 10.9.1 ("Array assignment patterns") of the LRM
(1800-2017).
At the moment the values in an assignment pattern are evaluated in a self
determined context, which can lead to incorrect behavior.
Use the existing `elaborate_rval_expr()` function, which is meant for
elaborating assignments, to elaborate the assignment pattern values.
This solves the following issues:
* implicit width conversion (including sign extension)
* implicit type conversion (e.g. real to vector)
* math operators that depend on the target width (e.g. addition)
* use of expressions that require `test_width()` to be called. (e.g.
unary operator)
* use of concatenations
* use of named constants (e.g. parameters or enums)
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The `elaborate_rval_expr()` function takes a `data_type_t`, a
`ivl_variable_type_t` and a `width` parameter. In most places the
ivl_variable_type_t and width are directly derived from the data_type_t.
This slightly simplifies the code.
The only place where this is currently not possible is when assigning to a
compound expression like a concatenation, e.g. `{a,b} = c;`.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Assigning a value to an enum signal that is not of the same type as the
enum requires an explicit cast.
To support this attach the type of a type cast to the resulting expression.
This allows the assignment elaboration to confirm that value has been
explicitly cast to the right type.
Also handle the case where the value is a constant. In this case create a
NetEConstEnum instead of a NetEConst as the resulting expression.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There are too many ad hoc handlers of symbol_search partial results.
Rewrite symbol_search to clean up things like partial results and
member/method detections. Use this reworked symbol_search function
to rewrite expression elaborate for the PECallFunction expressions.
Use the common data_type_or_implicit rules to support type
definitions for parameters. This eliminates a bunch of special
rules in parse.y, and opens the door for parameters having
more complex types.
As reported on iverilog-devel on 2018-10-12, a dimension size of zero
could case the compiler to go into an infinite loop. Further tests
showed that unsized or queue dimensions entered as packed dimensions
would cause the compiler to crash.
A compressed assignment statement should give exactly the same
result as the equivalent uncompressed statement. This means
that the type (signed/unsigned) of the LHS affects the type of
the RHS expression (unlike in normal assignments). We need to
take care that bit/part selects and concatenations are correctly
identified as unsigned values, even in the cases where they
reduce to a single whole signal.
If both conditions of a NetCondit device assign to the same subset
of l-value bits, then generate a smaller NetMux device that only
switches the affected bits.
For constant word indices, issue a warning if the index is out of
range or an undefined value. In any case, the RHS value should be
discarded, and the actual assignment should be skipped.
This patch adds support for implicit casts to the elaborate_rval_expr()
function. This will handle the majority of cases where an implicit cast
can occur.
If a signal s driven by multiple non-overlapping NetPartSelect(PV)
objects, then combine them into a single NetConcat object. This
eliminates the need for resolvers in the target.
This involves working out the code to get the base type of a select
expression of a darray. Also added the runtime support for darrays
with real value elements.