[flang] Share code for analyzing Expr and Variable
authorTim Keith <tkeith@nvidia.com>
Fri, 19 Apr 2019 19:55:36 +0000 (12:55 -0700)
committerTim Keith <tkeith@nvidia.com>
Fri, 19 Apr 2019 19:55:36 +0000 (12:55 -0700)
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
flang/lib/semantics/expression.cc
flang/lib/semantics/expression.h

index fbe97bb2ae92057fe5dc49aeb26900c24db6b1a3..b9b80ef31070ff889f631c57e0bf38a0eee7ec26 100644 (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));
   }
 
index 480e70a9a0a33f1849f26d77d192d15752af07f3..9c727590f34e17e9759666a99876b195ed575565 100644 (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(
index ba44ce422fa6ebfb4a52b32ddab3573758aff34f..2c61bfee5b333903987ce6893732bb679b8e8137 100644 (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 &&);