[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@7fd422f025
Reviewed-on: https://github.com/flang-compiler/f18/pull/422
This commit is contained in:
Tim Keith 2019-04-19 12:55:36 -07:00
parent ed26a23f8a
commit b12a146b1b
3 changed files with 21 additions and 21 deletions

View File

@ -250,6 +250,9 @@ public:
// Set CharBlock for messages; restore when the returned value is deleted
common::Restorer<CharBlock> SetLocation(CharBlock at) {
if (at.empty()) {
at = at_;
}
return common::ScopedSet(at_, std::move(at));
}

View File

@ -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<typename PARSED>
MaybeExpr ExpressionAnalyzer::ExprOrVariable(const PARSED &x) {
if (x.typedExpr) {
// Expression was already checked by ExprChecker
return std::make_optional<Expr<SomeType>>(expr.typedExpr->v);
return std::make_optional<Expr<SomeType>>(x.typedExpr->v);
} else {
FixMisparsedFunctionReference(context_, expr.u);
FixMisparsedFunctionReference(context_, x.u);
MaybeExpr result;
if (!expr.source.empty()) {
if constexpr (std::is_same_v<PARSED, parser::Expr>) {
// 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<Expr<SomeType>>(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<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(

View File

@ -242,6 +242,7 @@ private:
// Analysis subroutines
int AnalyzeKindParam(const std::optional<parser::KindParam> &,
int defaultKind, int kanjiKind = -1);
template<typename PARSED> MaybeExpr ExprOrVariable(const PARSED &);
template<typename PARSED> MaybeExpr IntLiteralConstant(const PARSED &);
MaybeExpr AnalyzeString(std::string &&, int kind);
std::optional<Expr<SubscriptInteger>> AsSubscript(MaybeExpr &&);