brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · ee8113a Raw
157 lines · c
1//===-- lib/Semantics/resolve-names-utils.h ---------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef FORTRAN_SEMANTICS_RESOLVE_NAMES_UTILS_H_10#define FORTRAN_SEMANTICS_RESOLVE_NAMES_UTILS_H_11 12// Utility functions and class for use in resolve-names.cpp.13 14#include "flang/Evaluate/fold.h"15#include "flang/Parser/message.h"16#include "flang/Parser/tools.h"17#include "flang/Semantics/expression.h"18#include "flang/Semantics/scope.h"19#include "flang/Semantics/semantics.h"20#include "flang/Semantics/symbol.h"21#include "flang/Semantics/type.h"22#include "llvm/Support/raw_ostream.h"23#include <forward_list>24 25namespace Fortran::parser {26class CharBlock;27struct ArraySpec;28struct CoarraySpec;29struct ComponentArraySpec;30struct DataRef;31struct DefinedOpName;32struct Designator;33struct Expr;34struct GenericSpec;35struct Name;36} // namespace Fortran::parser37 38namespace Fortran::semantics {39 40using SourceName = parser::CharBlock;41class SemanticsContext;42 43// Record that a Name has been resolved to a Symbol44Symbol &Resolve(const parser::Name &, Symbol &);45Symbol *Resolve(const parser::Name &, Symbol *);46 47// Create a copy of msg with a new severity.48parser::MessageFixedText WithSeverity(49    const parser::MessageFixedText &msg, parser::Severity);50 51bool IsIntrinsicOperator(const SemanticsContext &, const SourceName &);52bool IsLogicalConstant(const SemanticsContext &, const SourceName &);53 54template <typename T>55MaybeIntExpr EvaluateIntExpr(SemanticsContext &context, const T &expr) {56  if (MaybeExpr maybeExpr{57          Fold(context.foldingContext(), AnalyzeExpr(context, expr))}) {58    if (auto *intExpr{evaluate::UnwrapExpr<SomeIntExpr>(*maybeExpr)}) {59      return std::move(*intExpr);60    }61  }62  return std::nullopt;63}64 65template <typename T>66std::optional<std::int64_t> EvaluateInt64(67    SemanticsContext &context, const T &expr) {68  return evaluate::ToInt64(EvaluateIntExpr(context, expr));69}70 71// Analyze a generic-spec and generate a symbol name and GenericKind for it.72class GenericSpecInfo {73public:74  explicit GenericSpecInfo(const parser::DefinedOpName &x) { Analyze(x); }75  explicit GenericSpecInfo(const parser::GenericSpec &x) { Analyze(x); }76 77  GenericKind kind() const { return kind_; }78  const SourceName &symbolName() const { return symbolName_.value(); }79  // Set the GenericKind in this symbol and resolve the corresponding80  // name if there is one81  void Resolve(Symbol *) const;82  friend llvm::raw_ostream &operator<<(83      llvm::raw_ostream &, const GenericSpecInfo &);84 85private:86  void Analyze(const parser::DefinedOpName &);87  void Analyze(const parser::GenericSpec &);88 89  GenericKind kind_;90  const parser::Name *parseName_{nullptr};91  std::optional<SourceName> symbolName_;92};93 94// Analyze a parser::ArraySpec or parser::CoarraySpec95ArraySpec AnalyzeArraySpec(SemanticsContext &, const parser::ArraySpec &);96ArraySpec AnalyzeArraySpec(97    SemanticsContext &, const parser::ComponentArraySpec &);98ArraySpec AnalyzeDeferredShapeSpecList(99    SemanticsContext &, const parser::DeferredShapeSpecList &);100ArraySpec AnalyzeCoarraySpec(101    SemanticsContext &context, const parser::CoarraySpec &);102 103// Perform consistency checks on equivalence sets104class EquivalenceSets {105public:106  EquivalenceSets(SemanticsContext &context) : context_{context} {}107  std::vector<EquivalenceSet> &sets() { return sets_; };108  // Resolve this designator and add to the current equivalence set109  void AddToSet(const parser::Designator &);110  // Finish the current equivalence set: determine if it overlaps111  // with any of the others and perform necessary merges if it does.112  void FinishSet(const parser::CharBlock &);113 114private:115  bool CheckCanEquivalence(116      const parser::CharBlock &, const Symbol &, const Symbol &);117  void MergeInto(const parser::CharBlock &, EquivalenceSet &, std::size_t);118  const EquivalenceObject *Find(const EquivalenceSet &, const Symbol &);119  bool CheckDesignator(const parser::Designator &);120  bool CheckDataRef(const parser::CharBlock &, const parser::DataRef &);121  bool CheckObject(const parser::Name &);122  bool CheckArrayBound(const parser::Expr &);123  bool CheckSubstringBound(const parser::Expr &, bool);124  bool IsCharacterSequenceType(const DeclTypeSpec *);125  bool IsDefaultKindNumericType(const IntrinsicTypeSpec &);126  bool IsDefaultNumericSequenceType(const DeclTypeSpec *);127  static bool IsAnyNumericSequenceType(const DeclTypeSpec *);128  static bool IsSequenceType(129      const DeclTypeSpec *, std::function<bool(const IntrinsicTypeSpec &)>);130 131  SemanticsContext &context_;132  std::vector<EquivalenceSet> sets_; // all equivalence sets in this scope133  // Map object to index of set it is in134  std::map<EquivalenceObject, std::size_t> objectToSet_;135  EquivalenceSet currSet_; // equivalence set currently being constructed136  struct {137    Symbol *symbol{nullptr};138    std::vector<ConstantSubscript> subscripts;139    std::optional<ConstantSubscript> substringStart;140  } currObject_; // equivalence object currently being constructed141};142 143// Duplicates a subprogram's dummy arguments and result, if any, and144// maps all of the symbols in their expressions.145struct SymbolAndTypeMappings;146void MapSubprogramToNewSymbols(const Symbol &oldSymbol, Symbol &newSymbol,147    Scope &newScope, SymbolAndTypeMappings * = nullptr);148 149parser::CharBlock MakeNameFromOperator(150    const parser::DefinedOperator::IntrinsicOperator &op,151    SemanticsContext &context);152parser::CharBlock MangleSpecialFunctions(const parser::CharBlock &name);153std::string MangleDefinedOperator(const parser::CharBlock &name);154 155} // namespace Fortran::semantics156#endif // FORTRAN_SEMANTICS_RESOLVE_NAMES_H_157