Instead of tracking just genericName_ while in a generic interface
block or generic statement, now we immediately create a symbol for it.
A parser::Name isn't good enough because a defined-operator or
defined-io-generic-spec doesn't have a name.
Change the parse tree to add a source field to GenericSpec. Use these
as names for symbols for defined-operator and defined-io-generic-spec
(e.g. "operator(+)" or "read(formatted)").
Change the source for defined-op-name to include the dots so that they
can be distinguished from normal symbols with the same name (e.g. you
can have both ".foo." and "foo"). These symbols have names in the symbol
table like ".foo.", not "operator(.foo.)", because references to them
have that form.
Add GenericKind enum to GenericDetails and GenericBindingDetails.
This allows us to know a symbol is "assignment(=)", for example,
without having to do a string comparison.
Add GenericSpecInfo to handle analyzing the various kinds of
generic-spec and generating symbol names and GenericKind for them.
Add reference to LanguageFeatureControl to SemanticsContext so that
they can be checked during semantics. For this change, if
LogicalAbbreviations is enabled, report an error if the user tries
to define an operator named ".T." or ".F.".
Add resolve-name-utils.cc to hold utility functions and classes that
don't have to be in the ResolveNamesVisitor class hierarchy. The goal
is to reduce the size of resolve-names.cc where possible.
Original-commit: flang-compiler/f18@3081f694e2
Reviewed-on: https://github.com/flang-compiler/f18/pull/338
`Semantics::Perform` is mostly a series of calls followed by a check
for fatal errors. There is more error checking logic than real code.
To make it clearer, change each of the phases it calls to return true
on success so that `Perform` can just call them one after the other.
Original-commit: flang-compiler/f18@a218cac788
Reviewed-on: https://github.com/flang-compiler/f18/pull/317
DoConcurrentChecker depends on expressions being fully resolved so it
can't be in the same pass as ExprChecker. The same will probably
apply to AssignmentChecker when its finished.
Checks that don't depend on expressions can go in the first pass
with ExprChecker.
Original-commit: flang-compiler/f18@c0785ec06f
Reviewed-on: https://github.com/flang-compiler/f18/pull/315
Add `SemanticsVisitor` as the visitor class to perform statement
semantics checks. Its template parameters are "checker" classes
that perform the checks. They have `Enter` and `Leave` functions
that are called for the corresponding parse tree nodes (`Enter`
before the children, `Leave` after). Unlike `Pre` and `Post` in
visitors they cannot prevent the parse tree walker from visiting
child nodes.
Existing checks have been incorporated into this framework:
- `ExprChecker` replaces `AnalyzeExpressions()`
- `AssignmentChecker` replaces `AnalyzeAssignments()`
- `DoConcurrentChecker` replaces `CheckDoConcurrentConstraints()`
Adding a new checker requires:
- defining the checker class:
- with BaseChecker as virtual base class
- constructible from `SemanticsContext`
- with Enter/Leave functions for nodes of interest
- add the checker class to the template parameters of `StatementSemantics`
Because these checkers and also `ResolveNamesVisitor` require tracking
the current statement source location, that has been moved into
`SemanticsContext`. `ResolveNamesVisitor` and `SemanticsVisitor`
update the location when `Statement` nodes are encountered, making it
available for error messages.
`AnalyzeKindSelector()` now has access to the current statement through
the context and so no longer needs to have it passed in.
Test `assign01.f90` was added to verify that `AssignmentChecker` is
actually doing something.
Original-commit: flang-compiler/f18@3a222c3673
Reviewed-on: https://github.com/flang-compiler/f18/pull/315
Tree-same-pre-rewrite: false
This showed up in procinterface01. A function can have more than one
PrefixSpec (e.g. `real elemental f()`). We need to ignore that ones
that aren't types.
Also, process the type after the ImplicitPart rather than after the
SpecificationPart. The type of the function result variable could
be accessed between those places.
Original-commit: flang-compiler/f18@df85eedb92
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
A module procedure interface body can access entities in its host
without an IMPORT statement. So the `ImportKind` of the scope created
for such an interface body should be `Default`, not `None` as it is
for other interface bodies.
Original-commit: flang-compiler/f18@24bb2668fd
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false
The `GenericDetails::CheckSpecific()` check was happening too early.
We have to wait until all procedures of the generic have been seen.
The generic can have the same name as a module procedure only if that
module procedure is a specific procedure of the generic.
Improve the `SayAlreadyDeclared` error message when the previous
declaration is a use-association
Original-commit: flang-compiler/f18@269e3db602
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false
When a generic has the same name as a module procedure or derived type,
the latter weren't being written to the `.mod` file. Fix that by calling
`PutSymbol()` on those symbols from the generic. Change `PutSymbol()` to
accept `Symbol *` to make that more convenient.
Original-commit: flang-compiler/f18@1778efe981
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false
When a function-stmt has a type in the prefix (`type(t) function f()`),
the type cannot be resolve until after processing the USE and IMPLICIT
statements. So save the parse-tree of the type and process it at the
end of the specification section.
Add `ProcessTypeSpec()` to handle the process of setting up to walk
a type spec, walking it, restoring the state, and returning the type
spec. We do this several other places too.
Original-commit: flang-compiler/f18@bcde294d0e
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false
A statement entity (`data-i-do-variable` or `ac-do-variable`) that
doesn't have a type specified gets the type it would have in the
enclosing scope. That means if there is a visible variable with the
same name, the statement entity gets its type. We were failing to
do that and just applying the implicit rules.
Original-commit: flang-compiler/f18@72bc7c29ba
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false
If an external subprogram is called and then declared, we have to
replace the `ProcEntityDetails` with `SubprogramDetails` in the symbol.
While doing so we can also check that the call was consistent with the
declaration for function vs. subprogram.
Original-commit: flang-compiler/f18@e43a2dae79
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false