A ProcedureDesignator is a derived type constructor call if the name
resolves to a derived type. We need to recognize it as such and not
report an error. It may be in another derived type so we have to call
FindSymbol() first to find the derived type.
Most of the diffs are due to `symbol` changing from a reference to a
pointer.
In this example we were reporting an error on the first `t1()` and
resolving the second as an external function call.
```
module m
type :: t1
end type
type(t1) :: x = t1()
type t2
type(t1) :: y = t1()
end type
end module
```
Original-commit: flang-compiler/f18@717b22ca2b
Reviewed-on: https://github.com/flang-compiler/f18/pull/116
When `-fdebug-dump-symbols` is supplied with `-funparse`, include symbol
information in comments in the Fortran output. This will be used for
testing to verify that correct symbols are defined and references in
the right place.
In `UnparseWithSymbols()`, walk the parse tree and collect symbol
definitions and references, organized by statement. When a symbol is
defined across several statement it is associated with the first.
The definition of implicitly defined symbols is associated with the
first reference.
To write out the symbol information, a new optional argument is added to
`Unparse()`: it is a function that is called immediately before each
statement is unparsed. We pass in a function that prints out the symbol
information collected for that statement.
Add `Symbol::GetType()` to make it easier to write the symbol types
and add `Symbol::SetType()` for uniformity.
Original-commit: flang-compiler/f18@2e827de4ad
Reviewed-on: https://github.com/flang-compiler/f18/pull/112
Tree-same-pre-rewrite: false
This gets the code base back to compiling cleanly with clang after
pull request 109.
There were two overloadings of `Post(const parser::DeclarationTypeSpec::Type &)`.
The one in DeclarationVisitor needed to call the one in DeclTypeSpecVisitor.
This was fixed by introducing a new function, SetDerivedDeclTypeSpec, to do
the equivalent thing.
Original-commit: flang-compiler/f18@81e447bf4e
Reviewed-on: https://github.com/flang-compiler/f18/pull/110
This consists of:
- a new kind of symbols to represent them with DerivedTypeDetails
- creating symbols for derived types when they are declared
- creating a new kind of scope for the type to hold component symbols
- resolving entity declarations of objects of derived type
- resolving references to objects of derived type and to components
- handling derived types with same name as generic
Type parameters are not yet implemented.
Refactor DeclTypeSpec to be a value class wrapping an IntrinsicTypeSpec
or a DerivedTypeSpec (or neither in the TypeStar and ClassStar cases).
Store DerivedTypeSpec objects in a new structure the current scope
MakeDerivedTypeSpec so that DeclTypeSpec can just contain a pointer to
them, as it currently does for intrinsic types.
In GenericDetails, add derivedType field to handle case where generic
and derived type have the same name. The generic is in the scope and the
derived type is referenced from the generic, similar to the case where a
generic and specific have the same name. When one of these names is
mis-recognized, we sometimes have to fix up the 'occurrences' lists
of the symbols.
Assign implicit types as soon as an entity is encountered that requires
one. Otherwise implicit derived types won't work. When we see 'x%y' we
have to know the type of x in order to resolve y. Add an Implicit flag
to mark symbols that were implicitly typed
For symbols that introduce a new scope, include a pointer back to that
scope.
Add CurrNonTypeScope() for the times when we want the current scope but
ignoring derived type scopes. For example, that happens when looking for
types or parameters, or creating implicit symbols.
Original-commit: flang-compiler/f18@9bd16da020
Reviewed-on: https://github.com/flang-compiler/f18/pull/109
Make DerivedTypeSpec a simple wrapper around the name of the type.
Leave out type parameter values until we are ready to resolve them
as well.
Change DeclTypeSpec to be an old-fashioned union with an enum to
indicate what is in it. std::variant doesn't work well here because
we wanted the enum visible in the class' API and there is not a
1-to-1 mapping between enumerators and data stored.
Original-commit: flang-compiler/f18@03bdeef790
Reviewed-on: https://github.com/flang-compiler/f18/pull/109
Tree-same-pre-rewrite: false
With this change, all instances Symbol are stored in class Symbols.
Scope.symbols_, which used to own the symbol memory, now maps names to
Symbol* instead. This causes a bunch of reference-to-pointer changes
because of the change in type of key-value pairs. It also requires a
default constructor for Symbol, which means owner_ can't be a reference.
Symbols manages Symbol instances by allocating a block of them at a time
and returning the next one when needed. They are never freed.
The reason for the change is that there are a few cases where we need
to have a two symbols with the same name, so they can't both live in
the map in Scope. Those are:
1. When there is an erroneous redeclaration of a name we may delete the
first symbol and replace it with a new one. If we have saved a pointer
to the first one it is now dangling. This can be seen by running
`f18 -fdebug-dump-symbols -fparse-only test/semantics/resolve19.f90`
under valgrind. Subroutine s is declared twice: each results in a
scope that contains a pointer back to the symbol for the subroutine.
After the second symbol for s is created the first is gone so the
pointer in the scope is invalid.
2. A generic and one of its specifics can have the same name. We currently
handle that by moving the symbol for the specific into a unique_ptr
in the generic. So in that case the symbol is owned by another symbol
instead of by the scope. It is simpler if we only have to deal with
moving the raw pointer around.
3. A generic and a derived type can have the same name. This case isn't
handled yet, but it can be done like flang-compiler/f18#2 above. It's more complicated
because the derived type and the generic can be declared in either
order.
Original-commit: flang-compiler/f18@55a68cf023
Reviewed-on: https://github.com/flang-compiler/f18/pull/107
We were collecting symbols in a map of SourceName to Symbol*.
This is wrong because sometimes different occurrences of a name
map to different symbols (e.g. in different scopes).
SourceName::begin() is unique for each occurrence so use that
as the map key instead.
The problem can be reproduced by running:
`f18 -fdebug-resolve-names -fparse-only -fdebug-dump-parse-tree`
on the following source. The two symbols 'i' should have different
types and they were both coming out as INTEGER because they both
pointed to the first symbol for 'i'.
```
module m
integer :: i
contains
subroutine s
real :: i
end
end
```
Original-commit: flang-compiler/f18@a165c717ff
Reviewed-on: https://github.com/flang-compiler/f18/pull/107
Tree-same-pre-rewrite: false