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
The Fortran source files in test/semantics all contain expected
errors in comments. The script test_errors.sh compiles a file with
'f18 -fdebug-resolve-names -fparse-only' and compares the actual
errors produced against the expected ones.
The change to resolve15.f90 is necessary because test_errors.sh can't
handle two expected errors for the same source line.
A useful command to run these is 'ctest -R f90 --output-on-failure'.
-R means only run tests with f90 in the name
--output-on-failure prints the output of test_errors.sh when a test
fails, showing the expected and actual messages that differ.
Original-commit: flang-compiler/f18@df18ee7bc9
Reviewed-on: https://github.com/flang-compiler/f18/pull/105
clang give a compilation error on resolve-names.cc because there are
two overloadings of Pre(ProcedureDeclarationStmt) available in
ResolveNamesVisitor. One is defined in DeclTypeSpecVisitor and the other
in DeclarationVisitor. They are both brought in to ResolveNamesVisitor
via `using` statements.
The one in DeclarationVisitor is the one that is supposed to be called.
The other should have been removed when this one was added. This is the
one that gcc chooses to call, so this doesn't change any behavior.
The same applies to the Post method as well.
Original-commit: flang-compiler/f18@872f8faf96
Reviewed-on: https://github.com/flang-compiler/f18/pull/100
Add Dump() routines based on operator<< for the type so that they are
easy to call from the debugger. Overload for both pointer and reference
types and for dumping to std::cerr or a specific ostream.
Original-commit: flang-compiler/f18@ec6676eff0
Reviewed-on: https://github.com/flang-compiler/f18/pull/99
Replace operator=(Symbol) and operator=(DeclTypeSpec) with set_symbol()
and set_type() to make it clearer. Eliminate the move constructor as it
is not needed. Make all but the accessor functions out-of-line.
Change HasExplicitType() to NeedsExplicitType(), reversing its sense.
HasExplicitType() returned true for symbols that didn't have or need an
explicit type, which was confusing.
Original-commit: flang-compiler/f18@ada13ac6a3
Reviewed-on: https://github.com/flang-compiler/f18/pull/97
Add ObjectEntityDetails and ProcEntityDetails to distinguish between an
entity from an object-decl and one from a proc-decl. When we don't know,
it stays as EntityDetails until it is resolved. DeclareEntity() in
DeclarationVisitor creates this kind of symbol.
Add flags to Symbol as a convenient place for boolean flags common to
many kinds of symbols. Use it to mark symbols known to be functions or
subroutines so that we can report errors when they are used incorrectly.
Improve handling of EXTERNAL statement.
Handle ProcDecl nodes and add symbols for them.
Partial processing of derived types. Data component declarations are
processed and added to the derived type. Define TypeBoundProc and
TypeBoundGeneric in type.h. Procedure components, type-bound procedures,
etc. are not handled yet and nothing is done with the derived type once
it is created. Eliminate DerivedTypeDefBuilder in favor of just setting
fields in derivedTypeData_.
Add GetDeclTypeSpec to go with BeginDeclTypeSpec and EndDeclTypeSpec, to
avoid directly access the private variable.
Add tests in resolve20.f90 for errors related to procedure declarations.
Add missing copyrights to other tests.
Original-commit: flang-compiler/f18@40e65c1465
Reviewed-on: https://github.com/flang-compiler/f18/pull/97
Tree-same-pre-rewrite: false
This handles the common case of an error message referring to
a name, and an attached message referring to another name.
For example, reporting an error where a name is already declared
and mentioning the previous declaration.
Original-commit: flang-compiler/f18@901b50dcf2
Reviewed-on: https://github.com/flang-compiler/f18/pull/97
Tree-same-pre-rewrite: false
When a generic or specific procedure is use-associated, make a copy of
it in the current scope (replacing the symbol that has UseDetails) so
that we can make changes to it. This permits a generic to be defined in
one module and extended with more specific procedures in another.
When a specific procedure has the same name as its generic, it can't be
stored directly in the scope because that is indexed by name and the
generic is already there. So instead we store the specific in the
GenericDetails of the generic symbol.
Enforce the rule that a generic and a procedure can only have the same
name if the procedure is one of the specifics of the generic.
Refactorings done is support of this change:
- Add FindSymbol() and EraseSymbol() as helpers to find or erase a
symbol in the current scope. Make use of FindSymbol() where appropriate.
- Add SayAlreadyDeclared() to report a common error.
Original-commit: flang-compiler/f18@be479b9887
Reviewed-on: https://github.com/flang-compiler/f18/pull/95
This is the result of running `f18 -fdebug-resolve-names` on a bunch of
Fortran source and fixing the resulting assertion errors and segmentation
faults.
Most of the problems were with encountering attributes, array specs, or
declaration type specs when we weren't prepared to handle them. Those
were fixed by adding calls to {Begin,End}DeclTypeSpec and {Begin,End}Decl
when encountering certain nodes, though the real work for those nodes is
still to be done.
Extract some common functionality into PostAttrSpec and CheckUseError.
Add missing XOR to GenericSpec.
Original-commit: flang-compiler/f18@3c0ff7ded4
Reviewed-on: https://github.com/flang-compiler/f18/pull/93
Tree-same-pre-rewrite: false