From b12a146b1bd742cfcdbed15b105ecf0da5b2860c Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Fri, 19 Apr 2019 12:55:36 -0700 Subject: [PATCH] [flang] Share code for analyzing Expr and Variable Move check for empty CharBlock from here to SetLocation. (Can an Expr ever have an empty source location?) Original-commit: flang-compiler/f18@7fd422f02515e4211170ba18fda04cc1405cf084 Reviewed-on: https://github.com/flang-compiler/f18/pull/422 --- flang/lib/parser/message.h | 3 +++ flang/lib/semantics/expression.cc | 38 +++++++++++++++++--------------------- flang/lib/semantics/expression.h | 1 + 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/flang/lib/parser/message.h b/flang/lib/parser/message.h index fbe97bb..b9b80ef 100644 --- a/flang/lib/parser/message.h +++ b/flang/lib/parser/message.h @@ -250,6 +250,9 @@ public: // Set CharBlock for messages; restore when the returned value is deleted common::Restorer SetLocation(CharBlock at) { + if (at.empty()) { + at = at_; + } return common::ScopedSet(at_, std::move(at)); } diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index 480e70a..9c727590f 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -1856,27 +1856,29 @@ void FixMisparsedFunctionReference( } } -MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) { - if (expr.typedExpr) { +// Common handling of parser::Expr and Parser::Variable +template +MaybeExpr ExpressionAnalyzer::ExprOrVariable(const PARSED &x) { + if (x.typedExpr) { // Expression was already checked by ExprChecker - return std::make_optional>(expr.typedExpr->v); + return std::make_optional>(x.typedExpr->v); } else { - FixMisparsedFunctionReference(context_, expr.u); + FixMisparsedFunctionReference(context_, x.u); MaybeExpr result; - if (!expr.source.empty()) { + if constexpr (std::is_same_v) { // Analyze the expression in a specified source position context for // better error reporting. - auto save{GetFoldingContext().messages().SetLocation(expr.source)}; - result = Analyze(expr.u); + auto save{GetFoldingContext().messages().SetLocation(x.source)}; + result = Analyze(x.u); } else { - result = Analyze(expr.u); + result = Analyze(x.u); } if (result.has_value()) { - expr.typedExpr.reset(new GenericExprWrapper{common::Clone(*result)}); + x.typedExpr.reset(new GenericExprWrapper{common::Clone(*result)}); } else if (!fatalErrors_) { if (!context_.AnyFatalError()) { #if DUMP_ON_FAILURE - parser::DumpTree(std::cout << "Expression analysis failed on: ", expr); + parser::DumpTree(std::cout << "Expression analysis failed on: ", x); #elif CRASH_ON_FAILURE common::die("Expression analysis failed without emitting an error"); #endif @@ -1887,18 +1889,12 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) { } } +MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) { + return ExprOrVariable(expr); +} + MaybeExpr ExpressionAnalyzer::Analyze(const parser::Variable &variable) { - if (variable.typedExpr) { - return std::make_optional>(variable.typedExpr->v); - } else { - FixMisparsedFunctionReference(context_, variable.u); - if (MaybeExpr result{Analyze(variable.u)}) { - variable.typedExpr.reset(new GenericExprWrapper{common::Clone(*result)}); - return result; - } else { - return std::nullopt; - } - } + return ExprOrVariable(variable); } Expr ExpressionAnalyzer::AnalyzeKindSelector( diff --git a/flang/lib/semantics/expression.h b/flang/lib/semantics/expression.h index ba44ce4..2c61bfe 100644 --- a/flang/lib/semantics/expression.h +++ b/flang/lib/semantics/expression.h @@ -242,6 +242,7 @@ private: // Analysis subroutines int AnalyzeKindParam(const std::optional &, int defaultKind, int kanjiKind = -1); + template MaybeExpr ExprOrVariable(const PARSED &); template MaybeExpr IntLiteralConstant(const PARSED &); MaybeExpr AnalyzeString(std::string &&, int kind); std::optional> AsSubscript(MaybeExpr &&); -- 2.7.4