From: Tim Keith Date: Fri, 24 Jul 2020 00:15:33 +0000 (-0700) Subject: [flang] Implicitly convert result of statement function X-Git-Tag: llvmorg-13-init~16937 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=412056e2d02fae43c6e7c8511c650e8458d55701;p=platform%2Fupstream%2Fllvm.git [flang] Implicitly convert result of statement function The result of a statement function may require an implicit conversion to match its result type. Add that to the expression that represents the statement function body in SubprogramDetails. Extract the analysis of that expression into a separate function. Dump the statement function expression as part of the dump of SubprogramDetails. Differential Revision: https://reviews.llvm.org/D84452 --- diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 73d111ca3c09..7189b4848265 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1438,6 +1438,7 @@ private: void PreSpecificationConstruct(const parser::SpecificationConstruct &); void CreateGeneric(const parser::GenericSpec &); void FinishSpecificationPart(const std::list &); + void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt &); void CheckImports(); void CheckImport(const SourceName &, const SourceName &); void HandleCall(Symbol::Flag, const parser::Call &); @@ -6101,23 +6102,11 @@ void ResolveNamesVisitor::FinishSpecificationPart( } } currScope().InstantiateDerivedTypes(context()); - // Analyze the bodies of statement functions now that the symbol in this - // specification part have been fully declared and implicitly typed. for (const auto &decl : decls) { if (const auto *statement{std::get_if< parser::Statement>>( &decl.u)}) { - const parser::StmtFunctionStmt &stmtFunc{statement->statement.value()}; - if (Symbol * symbol{std::get(stmtFunc.t).symbol}) { - if (auto *details{symbol->detailsIf()}) { - if (auto expr{AnalyzeExpr(context(), - std::get>(stmtFunc.t))}) { - details->set_stmtFunction(std::move(*expr)); - } else { - context().SetError(*symbol); - } - } - } + AnalyzeStmtFunctionStmt(statement->statement.value()); } } // TODO: what about instantiations in BLOCK? @@ -6126,6 +6115,33 @@ void ResolveNamesVisitor::FinishSpecificationPart( CheckEquivalenceSets(); } +// Analyze the bodies of statement functions now that the symbols in this +// specification part have been fully declared and implicitly typed. +void ResolveNamesVisitor::AnalyzeStmtFunctionStmt( + const parser::StmtFunctionStmt &stmtFunc) { + Symbol *symbol{std::get(stmtFunc.t).symbol}; + if (!symbol || !symbol->has()) { + return; + } + auto &details{symbol->get()}; + auto expr{AnalyzeExpr( + context(), std::get>(stmtFunc.t))}; + if (!expr) { + context().SetError(*symbol); + return; + } + if (auto type{evaluate::DynamicType::From(*symbol)}) { + auto converted{ConvertToType(*type, std::move(*expr))}; + if (!converted) { + context().SetError(*symbol); + return; + } + details.set_stmtFunction(std::move(*converted)); + } else { + details.set_stmtFunction(std::move(*expr)); + } +} + void ResolveNamesVisitor::CheckImports() { auto &scope{currScope()}; switch (scope.GetImportKind()) { diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp index a7e2696518ff..e0d80ec6d1c8 100644 --- a/flang/lib/Semantics/symbol.cpp +++ b/flang/lib/Semantics/symbol.cpp @@ -111,6 +111,9 @@ llvm::raw_ostream &operator<<( } } os << (sep == '(' ? "()" : ")"); + if (x.stmtFunction_) { + os << " -> " << x.stmtFunction_->AsFortran(); + } return os; }