peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 1 | // Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | #ifndef FORTRAN_EVALUATE_CALL_H_ |
| 16 | #define FORTRAN_EVALUATE_CALL_H_ |
| 17 | |
| 18 | #include "common.h" |
| 19 | #include "type.h" |
| 20 | #include "../common/indirection.h" |
| 21 | #include "../parser/char-block.h" |
peter klausler | d804c9d | 2018-10-18 20:03:51 | [diff] [blame^] | 22 | #include "../semantics/attr.h" |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 23 | #include <optional> |
| 24 | #include <ostream> |
| 25 | #include <vector> |
| 26 | |
peter klausler | d804c9d | 2018-10-18 20:03:51 | [diff] [blame^] | 27 | namespace Fortran::semantics { |
| 28 | class Symbol; |
| 29 | } |
| 30 | |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 31 | namespace Fortran::evaluate { |
| 32 | |
| 33 | struct ActualArgument { |
peter klausler | 62425d6 | 2018-10-12 00:01:31 | [diff] [blame] | 34 | explicit ActualArgument(Expr<SomeType> &&x) : value{std::move(x)} {} |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 35 | explicit ActualArgument(CopyableIndirection<Expr<SomeType>> &&v) |
| 36 | : value{std::move(v)} {} |
peter klausler | 84ea49d | 2018-10-18 17:50:55 | [diff] [blame] | 37 | |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 38 | std::optional<DynamicType> GetType() const; |
| 39 | int Rank() const; |
| 40 | std::ostream &Dump(std::ostream &) const; |
peter klausler | ad9aede | 2018-10-11 21:51:14 | [diff] [blame] | 41 | std::optional<int> VectorSize() const; |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 42 | |
| 43 | std::optional<parser::CharBlock> keyword; |
peter klausler | 84ea49d | 2018-10-18 17:50:55 | [diff] [blame] | 44 | bool isAssumedRank{false}; // TODO: make into a function of the value |
peter klausler | d804c9d | 2018-10-18 20:03:51 | [diff] [blame^] | 45 | bool isAlternateReturn{false}; // when true, "value" is a label number |
| 46 | |
| 47 | // TODO: Mark legacy %VAL and %REF arguments |
peter klausler | ad9aede | 2018-10-11 21:51:14 | [diff] [blame] | 48 | |
| 49 | // Subtlety: There is a distinction that must be maintained here between an |
| 50 | // actual argument expression that is a variable and one that is not, |
| 51 | // e.g. between X and (X). The parser attempts to parse each argument |
| 52 | // first as a variable, then as an expression, and the distinction appears |
| 53 | // in the parse tree. |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 54 | CopyableIndirection<Expr<SomeType>> value; |
| 55 | }; |
| 56 | |
peter klausler | ef9dd9d | 2018-10-17 22:09:48 | [diff] [blame] | 57 | using ActualArguments = std::vector<std::optional<ActualArgument>>; |
peter klausler | d804c9d | 2018-10-18 20:03:51 | [diff] [blame^] | 58 | |
| 59 | // Intrinsics are identified by their names and the characteristics |
| 60 | // of their arguments, at least for now. |
| 61 | using IntrinsicProcedure = const char *; // not an owning pointer |
| 62 | |
| 63 | struct SpecificIntrinsic { |
| 64 | explicit SpecificIntrinsic(IntrinsicProcedure n) : name{n} {} |
| 65 | SpecificIntrinsic(IntrinsicProcedure n, std::optional<DynamicType> &&dt, |
| 66 | int r, semantics::Attrs a) |
| 67 | : name{n}, type{std::move(dt)}, rank{r}, attrs{a} {} |
| 68 | std::ostream &Dump(std::ostream &) const; |
| 69 | |
| 70 | IntrinsicProcedure name; |
| 71 | bool isRestrictedSpecific{false}; // if true, can only call it |
| 72 | std::optional<DynamicType> type; // absent if and only if subroutine call |
| 73 | int rank{0}; |
| 74 | semantics::Attrs attrs; // ELEMENTAL, POINTER |
| 75 | }; |
| 76 | |
| 77 | struct ProcedureDesignator { |
| 78 | EVALUATE_UNION_CLASS_BOILERPLATE(ProcedureDesignator) |
| 79 | explicit ProcedureDesignator(SpecificIntrinsic &&i) : u{std::move(i)} {} |
| 80 | explicit ProcedureDesignator(const semantics::Symbol &n) : u{&n} {} |
| 81 | std::optional<DynamicType> GetType() const; |
| 82 | int Rank() const; |
| 83 | bool IsElemental() const; |
| 84 | Expr<SubscriptInteger> LEN() const; |
| 85 | const semantics::Symbol *GetSymbol() const; |
| 86 | std::ostream &Dump(std::ostream &) const; |
| 87 | |
| 88 | // TODO: When calling X%F, pass X as PASS argument unless NOPASS |
| 89 | std::variant<SpecificIntrinsic, const semantics::Symbol *> u; |
| 90 | }; |
Jean Perier | f7e7cb3 | 2018-10-25 12:55:23 | [diff] [blame] | 91 | } |
peter klausler | a62636f | 2018-10-08 22:35:19 | [diff] [blame] | 92 | #endif // FORTRAN_EVALUATE_CALL_H_ |