| //===-- include/flang/Evaluate/intrinsics.h ---------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef FORTRAN_EVALUATE_INTRINSICS_H_ |
| #define FORTRAN_EVALUATE_INTRINSICS_H_ |
| |
| #include "call.h" |
| #include "characteristics.h" |
| #include "type.h" |
| #include "flang/Common/default-kinds.h" |
| #include "flang/Parser/char-block.h" |
| #include "flang/Parser/message.h" |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| namespace llvm { |
| class raw_ostream; |
| } |
| |
| namespace Fortran::semantics { |
| class Scope; |
| } |
| |
| namespace Fortran::evaluate { |
| |
| class FoldingContext; |
| |
| // Utility for checking for missing, excess, and duplicated arguments, |
| // and rearranging the actual arguments into dummy argument order. |
| bool CheckAndRearrangeArguments(ActualArguments &, parser::ContextualMessages &, |
| const char *const dummyKeywords[] /* null terminated */, |
| std::size_t trailingOptionals = 0); |
| |
| struct CallCharacteristics { |
| std::string name; |
| bool isSubroutineCall{false}; |
| }; |
| |
| struct SpecificCall { |
| SpecificCall(SpecificIntrinsic &&si, ActualArguments &&as) |
| : specificIntrinsic{std::move(si)}, arguments{std::move(as)} {} |
| SpecificIntrinsic specificIntrinsic; |
| ActualArguments arguments; |
| }; |
| |
| struct SpecificIntrinsicFunctionInterface : public characteristics::Procedure { |
| SpecificIntrinsicFunctionInterface( |
| characteristics::Procedure &&p, std::string n, bool isRestrictedSpecific) |
| : characteristics::Procedure{std::move(p)}, genericName{n}, |
| isRestrictedSpecific{isRestrictedSpecific} {} |
| std::string genericName; |
| bool isRestrictedSpecific; |
| // N.B. If there are multiple arguments, they all have the same type. |
| // All argument and result types are intrinsic types with default kinds. |
| }; |
| |
| // Generic intrinsic classes from table 16.1 |
| ENUM_CLASS(IntrinsicClass, atomicSubroutine, collectiveSubroutine, |
| elementalFunction, elementalSubroutine, inquiryFunction, pureSubroutine, |
| impureSubroutine, transformationalFunction, noClass) |
| |
| class IntrinsicProcTable { |
| private: |
| class Implementation; |
| |
| IntrinsicProcTable() = default; |
| |
| public: |
| ~IntrinsicProcTable(); |
| IntrinsicProcTable(IntrinsicProcTable &&) = default; |
| |
| static IntrinsicProcTable Configure( |
| const common::IntrinsicTypeDefaultKinds &); |
| |
| // Make *this aware of the __Fortran_builtins module to expose TEAM_TYPE &c. |
| void SupplyBuiltins(const semantics::Scope &) const; |
| |
| // Check whether a name should be allowed to appear on an INTRINSIC |
| // statement. |
| bool IsIntrinsic(const std::string &) const; |
| bool IsIntrinsicFunction(const std::string &) const; |
| bool IsIntrinsicSubroutine(const std::string &) const; |
| |
| // Inquiry intrinsics are defined in section 16.7, table 16.1 |
| IntrinsicClass GetIntrinsicClass(const std::string &) const; |
| |
| // Return the generic name of a specific intrinsic name. |
| // The name provided is returned if it is a generic intrinsic name or is |
| // not known to be an intrinsic. |
| std::string GetGenericIntrinsicName(const std::string &) const; |
| |
| // Probe the intrinsics for a match against a specific call. |
| // On success, the actual arguments are transferred to the result |
| // in dummy argument order; on failure, the actual arguments remain |
| // untouched. |
| std::optional<SpecificCall> Probe( |
| const CallCharacteristics &, ActualArguments &, FoldingContext &) const; |
| |
| // Probe the intrinsics with the name of a potential specific intrinsic. |
| std::optional<SpecificIntrinsicFunctionInterface> IsSpecificIntrinsicFunction( |
| const std::string &) const; |
| |
| // Illegal name for an intrinsic used to avoid cascading error messages when |
| // constant folding. |
| static const inline std::string InvalidName{ |
| "(invalid intrinsic function call)"}; |
| |
| llvm::raw_ostream &Dump(llvm::raw_ostream &) const; |
| |
| private: |
| std::unique_ptr<Implementation> impl_; |
| }; |
| |
| // Check if an intrinsic explicitly allows its INTENT(OUT) arguments to be |
| // allocatable coarrays. |
| bool AcceptsIntentOutAllocatableCoarray(const std::string &); |
| } // namespace Fortran::evaluate |
| #endif // FORTRAN_EVALUATE_INTRINSICS_H_ |