llvm/flang/lib/parser/tools.h
Jean Perier c67710e5ae [flang] Allocate semantic checks (second part)
Implement semantic checks and realted tests for constraints:
C937, C938, C939, C940, C941, C942, C945 (second part),
C946, C947, C948, C949 and C950.

Original-commit: flang-compiler/f18@b4965d272b
Tree-same-pre-rewrite: false
2019-05-03 00:45:22 -07:00

94 lines
3.1 KiB
C++

// Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FORTRAN_PARSER_TOOLS_H_
#define FORTRAN_PARSER_TOOLS_H_
#include "parse-tree.h"
namespace Fortran::parser {
// GetLastName() isolates and returns a reference to the rightmost Name
// in a variable (i.e., the Name whose symbol's type determines the type
// of the variable or expression).
const Name &GetLastName(const Name &);
const Name &GetLastName(const StructureComponent &);
const Name &GetLastName(const DataRef &);
const Name &GetLastName(const Substring &);
const Name &GetLastName(const Designator &);
const Name &GetLastName(const ProcComponentRef &);
const Name &GetLastName(const ProcedureDesignator &);
const Name &GetLastName(const Call &);
const Name &GetLastName(const FunctionReference &);
const Name &GetLastName(const Variable &);
const Name &GetLastName(const AllocateObject &);
// When a parse tree node is an instance of a specific type wrapped in
// layers of packaging, return a pointer to that object.
// Implemented with mutually recursive template functions that are
// wrapped in a struct to avoid prototypes.
struct UnwrapperHelper {
template<typename A, typename B> static const A *Unwrap(B *p) {
if (p != nullptr) {
return Unwrap<A>(*p);
} else {
return nullptr;
}
}
template<typename A, typename B, bool COPY>
static const A *Unwrap(const common::Indirection<B, COPY> &x) {
return Unwrap<A>(x.value());
}
template<typename A, typename... Bs>
static const A *Unwrap(const std::variant<Bs...> &x) {
return std::visit([](const auto &y) { return Unwrap<A>(y); }, x);
}
template<typename A, typename B>
static const A *Unwrap(const std::optional<B> &o) {
if (o.has_value()) {
return Unwrap<A>(*o);
} else {
return nullptr;
}
}
template<typename A, typename B> static const A *Unwrap(B &x) {
if constexpr (std::is_same_v<std::decay_t<A>, std::decay_t<B>>) {
return &x;
} else if constexpr (ConstraintTrait<B>) {
return Unwrap<A>(x.thing);
} else if constexpr (WrapperTrait<B>) {
return Unwrap<A>(x.v);
} else if constexpr (UnionTrait<B>) {
return Unwrap<A>(x.u);
} else {
return nullptr;
}
}
};
template<typename A, typename B> const A *Unwrap(const B &x) {
return UnwrapperHelper::Unwrap<A>(x);
}
// Get the CoindexedNamedObject if the entity is a coindexed object.
const CoindexedNamedObject *GetCoindexedNamedObject(const AllocateObject &);
const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &);
}
#endif // FORTRAN_PARSER_TOOLS_H_