1 //===-- lib/Evaluate/expression.cpp ---------------------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "flang/Evaluate/expression.h" 10 #include "int-power.h" 11 #include "flang/Common/idioms.h" 12 #include "flang/Evaluate/common.h" 13 #include "flang/Evaluate/tools.h" 14 #include "flang/Evaluate/variable.h" 15 #include "flang/Parser/char-block.h" 16 #include "flang/Parser/message.h" 17 #include "flang/Semantics/scope.h" 18 #include "flang/Semantics/symbol.h" 19 #include "flang/Semantics/tools.h" 20 #include "flang/Semantics/type.h" 21 #include "llvm/Support/Compiler.h" 22 #include "llvm/Support/raw_ostream.h" 23 #include <string> 24 #include <type_traits> 25 26 using namespace Fortran::parser::literals; 27 28 namespace Fortran::evaluate { 29 30 template <int KIND> 31 std::optional<Expr<SubscriptInteger>> 32 Expr<Type<TypeCategory::Character, KIND>>::LEN() const { 33 using T = std::optional<Expr<SubscriptInteger>>; 34 return std::visit( 35 common::visitors{ 36 [](const Constant<Result> &c) -> T { 37 return AsExpr(Constant<SubscriptInteger>{c.LEN()}); 38 }, 39 [](const ArrayConstructor<Result> &a) -> T { return a.LEN(); }, 40 [](const Parentheses<Result> &x) { return x.left().LEN(); }, 41 [](const Convert<Result> &x) { 42 return std::visit( 43 [&](const auto &kx) { return kx.LEN(); }, x.left().u); 44 }, 45 [](const Concat<KIND> &c) -> T { 46 if (auto llen{c.left().LEN()}) { 47 if (auto rlen{c.right().LEN()}) { 48 return *std::move(llen) + *std::move(rlen); 49 } 50 } 51 return std::nullopt; 52 }, 53 [](const Extremum<Result> &c) -> T { 54 if (auto llen{c.left().LEN()}) { 55 if (auto rlen{c.right().LEN()}) { 56 return Expr<SubscriptInteger>{Extremum<SubscriptInteger>{ 57 Ordering::Greater, *std::move(llen), *std::move(rlen)}}; 58 } 59 } 60 return std::nullopt; 61 }, 62 [](const Designator<Result> &dr) { return dr.LEN(); }, 63 [](const FunctionRef<Result> &fr) { return fr.LEN(); }, 64 [](const SetLength<KIND> &x) -> T { return x.right(); }, 65 }, 66 u); 67 } 68 69 Expr<SomeType>::~Expr() = default; 70 71 #if defined(__APPLE__) && defined(__GNUC__) 72 template <typename A> 73 typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() { 74 return *static_cast<Derived *>(this); 75 } 76 77 template <typename A> 78 const typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() const { 79 return *static_cast<const Derived *>(this); 80 } 81 #endif 82 83 template <typename A> 84 std::optional<DynamicType> ExpressionBase<A>::GetType() const { 85 if constexpr (IsLengthlessIntrinsicType<Result>) { 86 return Result::GetType(); 87 } else { 88 return std::visit( 89 [&](const auto &x) -> std::optional<DynamicType> { 90 if constexpr (!common::HasMember<decltype(x), TypelessExpression>) { 91 return x.GetType(); 92 } 93 return std::nullopt; // w/o "else" to dodge bogus g++ 8.1 warning 94 }, 95 derived().u); 96 } 97 } 98 99 template <typename A> int ExpressionBase<A>::Rank() const { 100 return std::visit( 101 [](const auto &x) { 102 if constexpr (common::HasMember<decltype(x), TypelessExpression>) { 103 return 0; 104 } else { 105 return x.Rank(); 106 } 107 }, 108 derived().u); 109 } 110 111 DynamicType Parentheses<SomeDerived>::GetType() const { 112 return left().GetType().value(); 113 } 114 115 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 116 template <typename A> LLVM_DUMP_METHOD void ExpressionBase<A>::dump() const { 117 llvm::errs() << "Expr is <{" << AsFortran() << "}>\n"; 118 } 119 #endif 120 121 // Equality testing 122 123 bool ImpliedDoIndex::operator==(const ImpliedDoIndex &that) const { 124 return name == that.name; 125 } 126 127 template <typename T> 128 bool ImpliedDo<T>::operator==(const ImpliedDo<T> &that) const { 129 return name_ == that.name_ && lower_ == that.lower_ && 130 upper_ == that.upper_ && stride_ == that.stride_ && 131 values_ == that.values_; 132 } 133 134 template <typename T> 135 bool ArrayConstructorValue<T>::operator==( 136 const ArrayConstructorValue<T> &that) const { 137 return u == that.u; 138 } 139 140 template <typename R> 141 bool ArrayConstructorValues<R>::operator==( 142 const ArrayConstructorValues<R> &that) const { 143 return values_ == that.values_; 144 } 145 146 template <int KIND> 147 bool ArrayConstructor<Type<TypeCategory::Character, KIND>>::operator==( 148 const ArrayConstructor &that) const { 149 return length_ == that.length_ && 150 static_cast<const Base &>(*this) == static_cast<const Base &>(that); 151 } 152 153 bool ArrayConstructor<SomeDerived>::operator==( 154 const ArrayConstructor &that) const { 155 return result_ == that.result_ && 156 static_cast<const Base &>(*this) == static_cast<const Base &>(that); 157 ; 158 } 159 160 StructureConstructor::StructureConstructor( 161 const semantics::DerivedTypeSpec &spec, 162 const StructureConstructorValues &values) 163 : result_{spec}, values_{values} {} 164 StructureConstructor::StructureConstructor( 165 const semantics::DerivedTypeSpec &spec, StructureConstructorValues &&values) 166 : result_{spec}, values_{std::move(values)} {} 167 168 bool StructureConstructor::operator==(const StructureConstructor &that) const { 169 return result_ == that.result_ && values_ == that.values_; 170 } 171 172 bool Relational<SomeType>::operator==(const Relational<SomeType> &that) const { 173 return u == that.u; 174 } 175 176 template <int KIND> 177 bool Expr<Type<TypeCategory::Integer, KIND>>::operator==( 178 const Expr<Type<TypeCategory::Integer, KIND>> &that) const { 179 return u == that.u; 180 } 181 182 template <int KIND> 183 bool Expr<Type<TypeCategory::Real, KIND>>::operator==( 184 const Expr<Type<TypeCategory::Real, KIND>> &that) const { 185 return u == that.u; 186 } 187 188 template <int KIND> 189 bool Expr<Type<TypeCategory::Complex, KIND>>::operator==( 190 const Expr<Type<TypeCategory::Complex, KIND>> &that) const { 191 return u == that.u; 192 } 193 194 template <int KIND> 195 bool Expr<Type<TypeCategory::Logical, KIND>>::operator==( 196 const Expr<Type<TypeCategory::Logical, KIND>> &that) const { 197 return u == that.u; 198 } 199 200 template <int KIND> 201 bool Expr<Type<TypeCategory::Character, KIND>>::operator==( 202 const Expr<Type<TypeCategory::Character, KIND>> &that) const { 203 return u == that.u; 204 } 205 206 template <TypeCategory CAT> 207 bool Expr<SomeKind<CAT>>::operator==(const Expr<SomeKind<CAT>> &that) const { 208 return u == that.u; 209 } 210 211 bool Expr<SomeDerived>::operator==(const Expr<SomeDerived> &that) const { 212 return u == that.u; 213 } 214 215 bool Expr<SomeCharacter>::operator==(const Expr<SomeCharacter> &that) const { 216 return u == that.u; 217 } 218 219 bool Expr<SomeType>::operator==(const Expr<SomeType> &that) const { 220 return u == that.u; 221 } 222 223 DynamicType StructureConstructor::GetType() const { return result_.GetType(); } 224 225 std::optional<Expr<SomeType>> StructureConstructor::CreateParentComponent( 226 const Symbol &component) const { 227 if (const semantics::DerivedTypeSpec * 228 parentSpec{GetParentTypeSpec(derivedTypeSpec())}) { 229 StructureConstructor structureConstructor{*parentSpec}; 230 if (const auto *parentDetails{ 231 component.detailsIf<semantics::DerivedTypeDetails>()}) { 232 auto parentIter{parentDetails->componentNames().begin()}; 233 for (const auto &childIter : values_) { 234 if (parentIter == parentDetails->componentNames().end()) { 235 break; // There are more components in the child 236 } 237 SymbolRef componentSymbol{childIter.first}; 238 structureConstructor.Add( 239 *componentSymbol, common::Clone(childIter.second.value())); 240 ++parentIter; 241 } 242 Constant<SomeDerived> constResult{std::move(structureConstructor)}; 243 Expr<SomeDerived> result{std::move(constResult)}; 244 return std::optional<Expr<SomeType>>{result}; 245 } 246 } 247 return std::nullopt; 248 } 249 250 static const Symbol *GetParentComponentSymbol(const Symbol &symbol) { 251 if (symbol.test(Symbol::Flag::ParentComp)) { 252 // we have a created parent component 253 const auto &compObject{symbol.get<semantics::ObjectEntityDetails>()}; 254 if (const semantics::DeclTypeSpec * compType{compObject.type()}) { 255 const semantics::DerivedTypeSpec &dtSpec{compType->derivedTypeSpec()}; 256 const semantics::Symbol &compTypeSymbol{dtSpec.typeSymbol()}; 257 return &compTypeSymbol; 258 } 259 } 260 if (symbol.detailsIf<semantics::DerivedTypeDetails>()) { 261 // we have an implicit parent type component 262 return &symbol; 263 } 264 return nullptr; 265 } 266 267 std::optional<Expr<SomeType>> StructureConstructor::Find( 268 const Symbol &component) const { 269 if (auto iter{values_.find(component)}; iter != values_.end()) { 270 return iter->second.value(); 271 } 272 // The component wasn't there directly, see if we're looking for the parent 273 // component of an extended type 274 if (const Symbol * typeSymbol{GetParentComponentSymbol(component)}) { 275 return CreateParentComponent(*typeSymbol); 276 } 277 // Look for the component in the parent type component. The parent type 278 // component is always the first one 279 if (!values_.empty()) { 280 const Expr<SomeType> *parentExpr{&values_.begin()->second.value()}; 281 if (const Expr<SomeDerived> *derivedExpr{ 282 std::get_if<Expr<SomeDerived>>(&parentExpr->u)}) { 283 if (const Constant<SomeDerived> *constExpr{ 284 std::get_if<Constant<SomeDerived>>(&derivedExpr->u)}) { 285 if (std::optional<StructureConstructor> parentComponentValue{ 286 constExpr->GetScalarValue()}) { 287 // Try to find the component in the parent structure constructor 288 return parentComponentValue->Find(component); 289 } 290 } 291 } 292 } 293 return std::nullopt; 294 } 295 296 StructureConstructor &StructureConstructor::Add( 297 const Symbol &symbol, Expr<SomeType> &&expr) { 298 values_.emplace(symbol, std::move(expr)); 299 return *this; 300 } 301 302 GenericExprWrapper::~GenericExprWrapper() {} 303 304 void GenericExprWrapper::Deleter(GenericExprWrapper *p) { delete p; } 305 306 GenericAssignmentWrapper::~GenericAssignmentWrapper() {} 307 308 void GenericAssignmentWrapper::Deleter(GenericAssignmentWrapper *p) { 309 delete p; 310 } 311 312 template <TypeCategory CAT> int Expr<SomeKind<CAT>>::GetKind() const { 313 return std::visit( 314 [](const auto &kx) { return std::decay_t<decltype(kx)>::Result::kind; }, 315 u); 316 } 317 318 int Expr<SomeCharacter>::GetKind() const { 319 return std::visit( 320 [](const auto &kx) { return std::decay_t<decltype(kx)>::Result::kind; }, 321 u); 322 } 323 324 std::optional<Expr<SubscriptInteger>> Expr<SomeCharacter>::LEN() const { 325 return std::visit([](const auto &kx) { return kx.LEN(); }, u); 326 } 327 328 INSTANTIATE_EXPRESSION_TEMPLATES 329 } // namespace Fortran::evaluate 330