`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
We were setting `expectedProcFlag_` to indicate if a `ProcedureDesignator`
was used in a function or subroutine context. That didn't work if they
were nested, for example: `call f(g())`.
Instead, at the point we know function vs. subroutine (i.e. in the
`CallStmt` and `FunctionReference` nodes), explicitly walk the children,
passing in the flag.
Original-commit: flang-compiler/f18@8a13283f98
Reviewed-on: https://github.com/flang-compiler/f18/pull/305
Tree-same-pre-rewrite: false
Moving one of the `Pre(ImplicitStmt)` functions up to
`DeclarationVisitor` seemed to cause clang to complain that the `Pre`
call from the `Walk` function was ambiguous. So this change moves
it back to `ResolveNameVisitor`.
Also, remove an unused variable that was causing a warning.
Original-commit: flang-compiler/f18@766d000e25
Reviewed-on: https://github.com/flang-compiler/f18/pull/299
As with COMMON blocks, we can't completely check SAVE statements and
attributes until the end of the specification part when we have seen
full declarations of entities. So when SAVE is specified, add it to one
of the two sets in `saveInfo_`. At the end of the specification part,
check that those entities can have SAVE applied and set it if it is
not already implicitly set (e.g. due to being in a module). Also apply
the "global" SAVE if present (i.e. setting it on every applicable
entity).
Add `IsDummy()` and `IsFuncResult()` to `Symbol` to simplify some of
the checks. Also detect attempts to put a function result in a common
block.
Original-commit: flang-compiler/f18@af19c02bac
Reviewed-on: https://github.com/flang-compiler/f18/pull/298
Common block names can't clash with other names, so add `commonBlocks_`
to `Scope` to record the common blocks of a scoping unit. This requires
changes to how scopes are dumped and written to `.mod` files.
Support common blocks in BIND statements. Add optional bind-name to
`CommonBlockDetails`.
Add `CheckNotInBlock()` for checking statements that are not allowed in
block constructs.
In `rewrite-parse-tree.cc`, no longer skip check for resolved names in
common statements. But do skip the checks in compiler directives.
Original-commit: flang-compiler/f18@805a1ffd9b
Reviewed-on: https://github.com/flang-compiler/f18/pull/298
Tree-same-pre-rewrite: false
Previously `BIND(C, NAME="...")` caused `bindName` to be set but not
the `BIND` attribute. This made writing the `.mod` file easier, but it
makes it hard to ask: does this symbol have a C binding.
This change causes the `BIND` attribute to be set whenever there is
`BIND(C)` in the source, regardless of whether there is a name or not.
`bindName` is only set when the `BIND` attribute is also set.
Original-commit: flang-compiler/f18@5a6706ffcb
Reviewed-on: https://github.com/flang-compiler/f18/pull/298
Tree-same-pre-rewrite: false