Add overloads to AsGenericExpr() in Evaluate/tools.h to take care
of wrapping an untyped DataRef or bare Symbol in a typed Designator
wrapped up in a generic Expr<SomeType>. Use the new overloads to
replace a few instances of code that was calling TypedWrapper<>()
with a dynamic type.
This new tool will be useful in lowering to drive some code that
works with typed expressions (viz., list-directed I/O list items)
when starting with only a bare Symbol (viz., NAMELIST).
Differential Revision: https://reviews.llvm.org/D102352
We sometimes unroll an ac-implied-do of an array constructor into a flat list
of values. We then re-analyze the array constructor that contains the
resulting list of expressions. Such a list may or may not contain errors.
But when processing an array constructor with an unrolled ac-implied-do, the
compiler was building an expression to represent the extent of the resulting
array constructor containing the list of values. The number of operands
in this extent expression was based on the number of elements in the
unrolled list of values. For very large lists, this created an
expression so large that it could not be evaluated by the compiler
without overflowing the stack.
I fixed this by continuously folding the extent expression as each operand is
added to it. I added the test .../flang/test/Semantics/array-constr-big.f90
that will cause the compiler to seg fault without this change.
Also, when the unrolled ac-implied-do expression contains errors, we were
repeating the same error message referencing the same source line for every
instance of the erroneous expression in the unrolled list. This potentially
resulted in a very long list of messages for a single error in the source code.
I fixed this by comparing the message being emitted to the previously emitted
message. If they are the same, I do not emit the message. This change is also
tested by the new test array-constr-big.f90.
Several of the existing tests had duplicate error messages for the same source
line, and this change caused differences in their output. So I adjusted the
tests to match the new message emitting behavior.
Differential Revision: https://reviews.llvm.org/D102210
Add InputNamelist and OutputNamelist as I/O data transfer APIs
to be used with internal & external list-directed I/O; delete the
needless original namelist-specific Begin... calls.
Implement NAMELIST output and input; add basic tests.
Differential Revision: https://reviews.llvm.org/D101931
We were not correctly handling structure constructors that had forward
references to parameterized derived types. I harvested the code that checks
for forward references that was used during analysis of function call
expressions and called it from there and also called it during the
analysis of structure constructors.
I also added a test that will produce an internal error without this change.
Differential Revision: https://reviews.llvm.org/D101330
Andrezj W. @ Arm discovered that the runtime derived type table
building code in semantics was detecting fatal errors in the tests
that the f18 driver wasn't printing. This patch fixes f18 so that
these messages are printed; however, the messages were not valid user
errors, and the rest of this patch fixes them up.
There were two sources of the bogus errors. One was that the runtime
derived type information table builder was calculating the shapes of
allocatable and pointer array components in derived types, and then
complaining that they weren't constant or LEN parameter values, which
of course they couldn't be since they have to have deferred shapes
and those bounds were expressions like LBOUND(component,dim=1).
The second was that f18 was forwarding the actual LEN type parameter
expressions of a type instantiation too far into the uses of those
parameters in various expressions in the declarations of components;
when an actual LEN type parameter is not a constant value, it needs
to remain a "bare" type parameter inquiry so that it will be lowered
to a descriptor inquiry and acquire a captured expression value.
Fixing this up properly involved: moving some code into new utility
function templates in Evaluate/tools.h, tweaking the rewriting of
conversions in expression folding to elide needless integer kind
conversions of type parameter inquiries, making type parameter
inquiry folding *not* replace bare LEN type parameters with
non-constant actual parameter values, and cleaning up some
altered test results.
Differential Revision: https://reviews.llvm.org/D101001
This patch adds semantic checks for the General Restrictions of the
Allocate Directive.
Since the requires directive is not yet implemented in Flang, the
restriction:
```
allocate directives that appear in a target region must
specify an allocator clause unless a requires directive with the
dynamic_allocators clause is present in the same compilation unit
```
will need to be updated at a later time.
A different patch will be made with the Fortran specific restrictions of
this directive.
I have used the code from https://reviews.llvm.org/D89395 for the
CheckObjectListStructure function.
Co-authored-by: Isaac Perry <isaac.perry@arm.com>
Reviewed By: clementval, kiranchandramohan
Differential Revision: https://reviews.llvm.org/D91159
We were erroneously not taking into account the constant values of LEN type
parameters of parameterized derived types when checking for argument
compatibility. The required checks are identical to those for assignment
compatibility. Since argument compatibility is checked in .../lib/Evaluate and
assignment compatibility is checked in .../lib/Semantics, I moved the common
code into .../lib/Evaluate/tools.cpp and changed the assignment compatibility
checking code to call it.
After implementing these new checks, tests in resolve53.f90 were failing
because the tests were erroneous. I fixed these tests and added new tests
to call03.f90 to test argument passing of parameterized derived types more
completely.
Differential Revision: https://reviews.llvm.org/D100989
This patch adds `-fget-definition` to `flang-new`. The semantics of this
option are identical in both drivers. The error message in the
"throwaway" driver is updated so that it matches the one from
`flang-new` (which is auto-generated and cannot be changed easily).
Tests are updated accordingly. A dedicated test for error handling was
added: get-definition.f90 (for the sake of simplicity,
getdefinition01.f90 no longer tests for errors).
The `ParseFrontendArgs` function is updated so that it can return
errors. This change is required in order to report invalid values
following `-fget-definition`.
The actual implementation of `GetDefinitionAction::ExecuteAction()` was
extracted from f18.cpp (i.e. the bit that deals with
`-fget-definition`).
Depends on: https://reviews.llvm.org/D100556
Differential Revision: https://reviews.llvm.org/D100558
We were erroneously emitting error messages for assignments of derived types
where the associated objects were instantiated with non-constant LEN type
parameters.
I fixed this by adding the member function MightBeAssignmentCompatibleWith() to
the class DerivedTypeSpec and calling it to determine whether it's possible
that objects of parameterized derived types can be assigned to each other. Its
implementation first compares the uninstantiated values of the types. If they
are equal, it then compares the values of the constant instantiated type
parameters.
I added tests to assign04.f90 to exercise this new code.
Differential Revision: https://reviews.llvm.org/D100868
This is just a small update that makes sure that errors arising from
parsing command-line options are captured more visibly. Also, all
parsing methods will now consistently return either a bool ("may fail")
or void ("never fails").
An instance of `InputKind` coming from `-x` is added to
`FrontendOptions` rather then being returned from `ParseFrontendArgs`.
It's currently not used, but we will require it shortly. In particular,
once code-generation is available we will use it to differentiate
between LLVM IR and Fortran input. `FrontendOptions` is a very suitable
place to keep it.
This changes don't affect the error reporting in the driver. In this
respect these are non-functional-changes. However, it will simplify
things in the forthcoming patches in which we may need a better error
tracking/recovery mechanism.
Differential Revision: https://reviews.llvm.org/D100556
For pernicious test cases with explicit non-constant actual
type parameter expressions in components, e.g.:
type :: t(k)
integer, kind :: k
type(t(k+1)), pointer :: p
end type
we should detect the infinite recursion and complain rather
than looping until the stack overflows.
Differential Revision: https://reviews.llvm.org/D100065
Call static functions using the class name (fir::NameUniquer).
Add function for mangling derivedTypes.
All the name mangling functions that are ultimately called are
tested in unittests/Optimizer/InternalNamesTest.cpp.
Differential Revision: https://reviews.llvm.org/D99967
This patch adds two debugging options in the new Flang driver
(flang-new):
*fdebug-unparse-no-sema
*fdebug-dump-parse-tree-no-sema
Each of these options combines two options from the "throwaway" driver
(left: f18, right: flang-new):
* `-fdebug-uparse -fdebug-no-semantics` --> `-fdebug-unparse-no-sema`
* `-fdebug-dump-parse-tree -fdebug-no-semantics` -->
`-fdebug-dump-parse-tree-no-sema`
There are no plans to implement `-fdebug-no-semantics` in the new
driver. Such option would be too powerful. Also, it would only make
sense when combined with specific frontend actions (`-fdebug-unparse`
and `-fdebug-dump-parse-tree`). Instead, this patch adds 2 specialised
options listed above. Each of these is implemented through a dedicated
FrontendAction (also added).
The new frontend actions are implemented in terms of a new abstract base
action: `PrescanAndSemaAction`. This new base class was required so that
we can have finer control over what steps within the frontend are
executed:
* `PrescanAction`: run the _prescanner_
* `PrescanAndSemaAction`: run the _prescanner_ and the _parser_ (new
in this patch)
* `PrescanAndSemaAction`: run the _prescanner_, _parser_ and run the
_semantic checks_
This patch introduces `PrescanAndParseAction::BeginSourceFileAction`.
Apart from the semantic checks removed at the end, it is similar to
`PrescanAndSemaAction::BeginSourceFileAction`.
Differential Revision: https://reviews.llvm.org/D99645
The -fdebug-dump-provenance flag is meant to be used with
needProvenanceRangeToCharBlockMappings set to true. This way, extra
mapping is generated that allows e.g. IDEs to retrieve symbol's scope
(offset into cooked character stream) based on symbol's source code
location. This patch makes sure that this option is set when using
-fdebug-dump-provenance.
With this patch, the implementation of -fdebug-dump-provenance in
`flang-new -fc1` becomes consistent with `f18`. The corresponding LIT
test is updated so that it can be shared with `f18`. I refined it a bit
so that:
* it becomes a frontend-only test
* it's stricter about the expected output
Differential Revision: https://reviews.llvm.org/D98847
This patch adds support for the `-cpp` and `-nocpp` flags. The
implemented semantics match f18 (i.e. the "throwaway" driver), but are
different to gfortran. In Flang the preprocessor is always run. Instead,
`-cpp/-nocpp` are used to control whether predefined and command-line
preprocessor macro definitions are enabled or not. In practice this is
sufficient to model gfortran`s `-cpp/-nocpp`.
In the absence of `-cpp/-nocpp`, the driver will use the extension of
the input file to decide whether to include the standard macro
predefinitions. gfortran's documentation [1] was used to decide which
file extension to use for this.
The logic mentioned above was added in FrontendAction::BeginSourceFile.
That's relatively late in the driver set-up, but this roughly where the
name of the input file becomes available. The logic for deciding between
fixed and free form works in a similar way and was also moved to
FrontendAction::BeginSourceFile for consistency (and to reduce
code-duplication).
The `-cpp/-nocpp` flags are respected also when the input is read from
stdin. This is different to:
* gfortran (behaves as if `-cpp` was used)
* f18 (behaves as if `-nocpp` was used)
Starting with this patch, file extensions are significant and some test
files had to be renamed to reflect that. Where possible, preprocessor
tests were updated so that they can be shared between `f18` and
`flang-new`. This was implemented on top of adding new test for
`-cpp/-nocpp`.
[1] https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D99292
Add runtime APIs, implementations, and tests for ALL, ANY, COUNT,
MAXLOC, MAXVAL, MINLOC, MINVAL, PRODUCT, and SUM reduction
transformantional intrinsic functions for all relevant argument
and result types and kinds, both without DIM= arguments
(total reductions) and with (partial reductions).
Complex-valued reductions have their APIs in C so that
C's _Complex types can be used for their results.
Some infrastructure work was also necessary or noticed:
* Usage of "long double" in the compiler was cleaned up a
bit, and host dependences on x86 / MSVC have been isolated
in a new Common/long-double header.
* Character comparison has been exposed via an extern template
so that reductions could use it.
* Mappings from Fortran type category/kind to host C++ types
and vice versa have been isolated into runtime/cpp-type.h and
then used throughout the runtime as appropriate.
* The portable 128-bit integer package in Common/uint128.h
was generalized to support signed comparisons.
* Bugs in descriptor indexing code were fixed.
Differential Revision: https://reviews.llvm.org/D99666
f18 was emitting a bogus error message about the lack of a TARGET
attribute when a pointer was initialized with a component of a
variable that was a legitimate TARGET.
Differential Revision: https://reviews.llvm.org/D99665
Before the conversion to LLVM-IR dialect and ultimately LLVM IR, FIR is
partially rewritten into a codegen form. This patch adds that pass, the
fircg dialect, and the small set of Ops in the fircg (sub) dialect.
Fircg is not part of the FIR dialect and should never be used outside of
the (closed) conversion to LLVM IR.
Authors: Eric Schweitz, Jean Perier, Rajan Walia, et.al.
Differential Revision: https://reviews.llvm.org/D98063
Binding labels start as expressions but they have to evaluate to
constant character of default kind, so they can be represented as an
std::string. Leading and trailing blanks have to be removed, so the
folded expression isn't exactly right anyway.
So all BIND(C) symbols now have a string binding label, either the
default or user-supplied one. This is recorded in the .mod file.
Add WithBindName mix-in for details classes that can have a binding
label so that they are all consistent. Add GetBindName() and
SetBindName() member functions to Symbol.
Add tests that verifies that leading and trailing blanks are ignored
in binding labels and that the default label is folded to lower case.
Differential Revision: https://reviews.llvm.org/D99208
Binding labels start as expressions but they have to evaluate to
constant character of default kind, so they can be represented as an
std::string. Leading and trailing blanks have to be removed, so the
folded expression isn't exactly right anyway.
So all BIND(C) symbols now have a string binding label, either the
default or user-supplied one. This is recorded in the .mod file.
Add WithBindName mix-in for details classes that can have a binding
label so that they are all consistent. Add GetBindName() and
SetBindName() member functions to Symbol.
Add tests that verifies that leading and trailing blanks are ignored
in binding labels and that the default label is folded to lower case.
Differential Revision: https://reviews.llvm.org/D99208
Replace semantics::SymbolSet with alternatives that clarify
whether the set should order its contents by source position
or not. This matters because positionally-ordered sets must
not be used for Symbols that might be subjected to name
replacement during name resolution, and address-ordered
sets must not be used (without sorting) in circumstances
where the order of their contents affects the output of the
compiler.
All set<> and map<> instances in the compiler that are keyed
by Symbols now have explicit Compare types in their template
instantiations. Symbol::operator< is no more.
Differential Revision: https://reviews.llvm.org/D98878
Adds support for `-fget-symbols-sources` in the new Flang driver. All
relevant tests are updated to use the new driver when
`FLANG_BUILD_NEW_DRIVER` is set.
`RUN` lines in tests are updated so `-fsyntax-only`
comes before `-fget-symbols-sources`. That's because:
* both `-fsyntax-only` and `-fget-symbols-sources` are
action flags, and
* the new driver, flang-new, will only consider the right-most
action flag.
In other words, this change is needed so that the tests work with both
`f18` (requires both flags) and `flang-new` (only considers the last
action flag).
Differential Revision: https://reviews.llvm.org/D98191
In parser::AllCookedSources, implement a map from CharBlocks to
the CookedSource instances that they cover. This permits a fast
Find() operation based on std::map::equal_range to map a CharBlock
to its enclosing CookedSource instance.
Add a creation order number to each CookedSource. This allows
AllCookedSources to provide a Precedes(x,y) predicate that is a
true source stream ordering between two CharBlocks -- x is less
than y if it is in an earlier CookedSource, or in the same
CookedSource at an earlier position.
Add a reference to the singleton SemanticsContext to each Scope.
All of this allows operator< to be implemented on Symbols by
means of a true source ordering. From a Symbol, we get to
its Scope, then to the SemanticsContext, and then use its
AllCookedSources reference to call Precedes().
Differential Revision: https://reviews.llvm.org/D98743
`parser::AllocateObject` and `parser::PointerObject` can be represented
as typed expressions once analyzed. This simplifies the work for parse-tree
consumers that work with typed expressions to deal with allocatable and
pointer objects such as lowering.
This change also makes it easier to add typedExpr in the future by
automatically handling nodes that have this member when possible.
Changes:
- Add a `mutable TypedExpr typedExpr` field to `parser::PointerObject` and `parser::AllocateObject`.
- Add a `parser::HasTypedExpr<T>` helper to better share code relating to typedExpr in the parse tree.
- Add hooks in `semantics::ExprChecker` for AllocateObject and PointerObject nodes, and use
ExprOrVariable on it to analyze and set the tyedExpr field during
expression analysis. This required adding overloads for `AssumedTypeDummy`.
- Update check-nullify.cpp and check-deallocate.cpp to not re-analyze the StructureComponent but to
use the typedExpr field instead.
- Update dump/unparse to use HasTypedExpr and use the typedExpr when there is one.
Differential Revision: https://reviews.llvm.org/D98256
Fortran permits a reference to a function whose result is a pointer
to be used as a definable variable in any context where a
designator could appear. This patch wrings out remaining bugs
with such usage and adds more testing.
The utility predicate IsProcedurePointer(expr) had a misleading
name which has been corrected to IsProcedurePointerTarget(expr).
Differential Revision: https://reviews.llvm.org/D98555
I changed the declaration of symbolCount_ in the type Symbols to be
static to avoid possible problems in the future when we might have
multiple objects of type Symbols. Thanks to Peter for pointing out the
need for this change.
Differential Revision: https://reviews.llvm.org/D98357
This allows for storage instances to store data that isn't uniqued in the context, or contain otherwise non-trivial logic, in the rare situations that they occur. Storage instances with trivial destructors will still have their destructor skipped. A consequence of this is that the storage instance definition must be visible from the place that registers the type.
Differential Revision: https://reviews.llvm.org/D98311
The PFT has been updated to support Fortran 77.
clang-tidy cleanup.
Authors: Val Donaldson, Jean Perier, Eric Schweitz, et.al.
Differential Revision: https://reviews.llvm.org/D98283
This patch adds `-fdebug-dump-parsing-log` in the new driver. This option is
semantically identical to `-fdebug-instrumented-parse` in `f18` (the
former is added as an alias in `f18`).
As dumping the parsing log makes only sense for instrumented parses, we
set Fortran::parser::Options::instrumentedParse to `True` when
`-fdebug-dump-parsing-log` is used. This is consistent with `f18`.
To facilitate tweaking the configuration of the frontend based on the
action being requested, `setUpFrontendBasedOnAction` is introduced in
CompilerInvocation.cpp.
Differential Revision: https://reviews.llvm.org/D97457
We have a "<" operator defined on the type semantics::Symbol that's based on
the symbols' locations in the cooked character stream. This is potentially
problematic when comparing symbols from .mod files when the cooked character
streams themselves might be allocated to varying memory locations.
This change fixes that by using the order in which symbols are created as the
basis for the "<" operator. Thanks to Tim and Peter for consultation on the
necessity of doing this and the idea for what to use as the basis of the sort.
This change in the "<" operator changed the expected results for three of the
tests. I manually inspected the new results, and they look OK to me. The
differences in data05.f90 and typeinfo01.f90 are entirely the order, offsets,
and sizes of the derived type components. The changes in resolve102.f90 are
due to the new, different "<" operator used for sorting.
Differential Revision: https://reviews.llvm.org/D98225
Add support for the following Fortran dialect options:
- -default*
- -flarge-sizes
It also adds two test cases:
# For checking whether `flang-new` is passing options correctly to `flang-new -fc1`.
# For checking if `fdefault-` arguments are processed properly.
Also moves the Dialect related option parsing to a dedicated function
and adds a member `defaultKinds()` to `CompilerInvocation`
Depends on: D96032
Differential Revision: https://reviews.llvm.org/D96344
It's possible to define a procedure whose interface depends on a procedure
which has an interface that depends on the original procedure. Such a circular
definition was causing the compiler to fall into an infinite loop when
resolving the name of the second procedure. It's also possible to create
circular dependency chains of more than two procedures.
I fixed this by adding the function HasCycle() to the class DeclarationVisitor
and calling it from DeclareProcEntity() to detect procedures with such
circularly defined interfaces. I marked the associated symbols of such
procedures by calling SetError() on them. When processing subsequent
procedures, I called HasError() before attempting to analyze their interfaces.
Unfortunately, this did not work.
With help from Tim, we determined that the SymbolSet used to track the
erroneous symbols was instantiated using a "<" operator which was defined using
the location of the name of the procedure. But the location of the procedure
name was being changed by a call to ReplaceName() between the times that the
calls to SetError() and HasError() were made. This caused HasError() to
incorrectly report that a symbol was not in the set of erroneous symbols.
I fixed this by changing SymbolSet to be an unordered set that uses the
contents of the name of the symbol as the basis for its hash function. This
works because the contents of the name of the symbol is preserved by
ReplaceName() even though its location changes.
I also fixed the error message used when reporting recursively defined
dummy procedure arguments by removing extra apostrophes and sorting the
list of symbols.
I also added tests that will crash the compiler without this change.
Note that the "<" operator is used in other contexts, for example, in the map
of characterized procedures, maps of items in equivalence sets, maps of
structure constructor values, ... All of these situations happen after name
resolution has been completed and all calls to ReplaceName() have already
happened and thus are not subject to the problem I ran into when ReplaceName()
was called when processing procedure entities.
Note also that the implementation of the "<" operator uses the relative
location in the cooked character stream as the basis of its implementation.
This is potentially problematic when symbols from diffent compilation units
(for example symbols originating in .mod files) are put into the same map since
their names will appear in two different source streams which may not be
allocated in the same relative positions in memory. But I was unable to create
a test that caused a problem. Using a direct comparison of the content of the
name of the symbol in the "<" operator has problems. Symbols in enclosing or
parallel scopes can have the same name. Also using the location of the symbol
in the cooked character stream has the advantage that it preserves the the
order of the symbols in a structure constructor constant, which makes matching
the values with the symbols relatively easy.
This patch supersedes D97749.
Differential Revision: https://reviews.llvm.org/D97774
It's possible to define a procedure whose interface depends on a procedure
which has an interface that depends on the original procedure. Such a circular
definition was causing the compiler to fall into an infinite loop when
resolving the name of the second procedure. It's also possible to create
circular dependency chains of more than two procedures.
I fixed this by adding the function HasCycle() to the class DeclarationVisitor
and calling it from DeclareProcEntity() to detect procedures with such
circularly defined interfaces. I marked the associated symbols of such
procedures by calling SetError() on them. When processing subsequent
procedures, I called HasError() before attempting to analyze their interfaces.
Unfortunately, this did not work.
With help from Tim, we determined that the SymbolSet used to track the
erroneous symbols was instantiated using a "<" operator which was defined using
the location of the name of the procedure. But the location of the procedure
name was being changed by a call to ReplaceName() between the times that the
calls to SetError() and HasError() were made. This caused HasError() to
incorrectly report that a symbol was not in the set of erroneous symbols.
I fixed this by changing SymbolSet to be an unordered set that uses the
contents of the name of the symbol as the basis for its hash function. This
works because the contents of the name of the symbol is preserved by
ReplaceName() even though its location changes.
I also fixed the error message used when reporting recursively defined dummy
procedure arguments.
I also added tests that will crash the compiler without this change.
Note that the "<" operator is used in other contexts, for example, in the map
of characterized procedures, maps of items in equivalence sets, maps of
structure constructor values, ... All of these situations happen after name
resolution has been completed and all calls to ReplaceName() have already
happened and thus are not subject to the problem I ran into when ReplaceName()
was called when processing procedure entities.
Note also that the implementation of the "<" operator uses the relative
location in the cooked character stream as the basis of its implementation.
This is potentially problematic when symbols from diffent compilation units
(for example symbols originating in .mod files) are put into the same map since
their names will appear in two different source streams which may not be
allocated in the same relative positions in memory. But I was unable to create
a test that caused a problem. Using a direct comparison of the content of the
name of the symbol in the "<" operator has problems. Symbols in enclosing or
parallel scopes can have the same name. Also using the location of the symbol
in the cooked character stream has the advantage that it preserves the the
order of the symbols in a structure constructor constant, which makes matching
the values with the symbols relatively easy.
This change supersedes D97201.
Differential Revision: https://reviews.llvm.org/D97749
Semantic checks for the following OpenMP 4.5 clauses.
1. 2.15.4.2 - Copyprivate clause
2. 2.15.3.4 - Firstprivate clause
3. 2.15.3.5 - Lastprivate clause
Add related test cases and resolve test cases marked as XFAIL.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D91920
This reverts commit 07de0846a5.
The original patch has caused 6 out 8 of Flang's public buildbots to
fail. As I'm not sure what the fix should be, I'm reverting this for
now. Please see https://reviews.llvm.org/D97201 for more context and
discussion.