[flang] address review comments
authorpeter klausler <pklausler@nvidia.com>
Tue, 4 Dec 2018 00:44:25 +0000 (16:44 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 4 Dec 2018 00:44:25 +0000 (16:44 -0800)
Original-commit: flang-compiler/f18@2f4b7ac97cd35e7a4d1e4ea558a8bb98c34b663a
Reviewed-on: https://github.com/flang-compiler/f18/pull/234
Tree-same-pre-rewrite: false

flang/lib/evaluate/expression.h
flang/lib/semantics/expression.cc
flang/lib/semantics/expression.h

index 83499df..f323e26 100644 (file)
@@ -612,6 +612,10 @@ class Expr<SomeKind<CAT>> : public ExpressionBase<SomeKind<CAT>> {
 public:
   using Result = SomeKind<CAT>;
   EVALUATE_UNION_CLASS_BOILERPLATE(Expr)
+  int GetKind() const {
+    return std::visit(
+        [](const auto &x) { return decltype(x)::Result::kind; }, u);
+  }
   common::MapTemplate<Expr, CategoryTypes<CAT>> u;
 };
 
index 94258a6..1812e90 100644 (file)
@@ -42,12 +42,14 @@ using common::TypeCategory;
 
 // Constraint checking
 void ExpressionAnalysisContext::CheckConstraints(MaybeExpr &expr) {
-  if (inner_ != nullptr) {
-    inner_->CheckConstraints(expr);
-  }
-  if (constraint_ != nullptr && expr.has_value()) {
-    if (!(this->*constraint_)(*expr)) {
-      expr.reset();
+  if (expr.has_value()) {
+    if (inner_ != nullptr) {
+      inner_->CheckConstraints(expr);
+    }
+    if (constraint_ != nullptr) {
+      if (!(this->*constraint_)(*expr)) {
+        expr.reset();
+      }
     }
   }
 }
@@ -78,6 +80,23 @@ bool ExpressionAnalysisContext::IntegerConstraint(Expr<SomeType> &expr) {
   return false;
 }
 
+bool ExpressionAnalysisContext::LogicalConstraint(Expr<SomeType> &expr) {
+  if (std::holds_alternative<Expr<SomeLogical>>(expr.u)) {
+    return true;
+  }
+  Say("expression must be LOGICAL"_err_en_US);
+  return false;
+}
+
+bool ExpressionAnalysisContext::DefaultCharConstraint(Expr<SomeType> &expr) {
+  if (auto *charExpr{std::get_if<Expr<SomeCharacter>>(&expr.u)}) {
+    return charExpr->GetKind() ==
+        context.defaultKinds.GetDefaultKind(TypeCategory::Character);
+  }
+  Say("expression must be default CHARACTER"_err_en_US);
+  return false;
+}
+
 // If a generic expression simply wraps a DataRef, extract it.
 // TODO: put in tools.h?
 template<typename A> std::optional<DataRef> ExtractDataRef(A &&) {
@@ -142,9 +161,6 @@ struct CallAndArguments {
 // Forward declarations of additional AnalyzeExpr specializations
 template<typename... As>
 MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &, const std::variant<As...> &);
-template<typename A>
-MaybeExpr AnalyzeExpr(
-    ExpressionAnalysisContext &, const common::Indirection<A> &);
 template<>
 MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &, const parser::Designator &);
 template<>
@@ -294,19 +310,13 @@ MaybeExpr AnalyzeExpr(
 template MaybeExpr AnalyzeExpr(
     ExpressionAnalysisContext &, const parser::Expr &);
 
-// Variants and indirections are silently traversed by AnalyzeExpr().
+// Variants are silently traversed by AnalyzeExpr().
 template<typename... As>
 MaybeExpr AnalyzeExpr(
     ExpressionAnalysisContext &context, const std::variant<As...> &u) {
   return std::visit([&](const auto &x) { return AnalyzeExpr(context, x); }, u);
 }
 
-template<typename A>
-MaybeExpr AnalyzeExpr(
-    ExpressionAnalysisContext &context, const common::Indirection<A> &x) {
-  return AnalyzeExpr(context, *x);
-}
-
 // Wraps a object in an explicitly typed representation (e.g., Designator<>
 // or FunctionRef<>) that has been instantiated on a dynamically chosen type.
 // TODO: move to tools.h?
index 160463a..630093e 100644 (file)
@@ -27,6 +27,8 @@ struct Program;
 template<typename> struct Scalar;
 template<typename> struct Integer;
 template<typename> struct Constant;
+template<typename> struct Logical;
+template<typename> struct DefaultChar;
 }
 
 // The expression semantic analysis code has its implementation in
@@ -68,6 +70,8 @@ public:
   bool ScalarConstraint(Expr<SomeType> &);
   bool ConstantConstraint(Expr<SomeType> &);
   bool IntegerConstraint(Expr<SomeType> &);
+  bool LogicalConstraint(Expr<SomeType> &);
+  bool DefaultCharConstraint(Expr<SomeType> &);
 
 protected:
   semantics::SemanticsContext &context_;
@@ -86,6 +90,33 @@ std::optional<Expr<SomeType>> AnalyzeExpr(
 extern template std::optional<Expr<SomeType>> AnalyzeExpr(
     ExpressionAnalysisContext &, const parser::Expr &);
 
+// Forward declarations of exposed specializations
+template<typename A>
+MaybeExpr AnalyzeExpr(
+    ExpressionAnalysisContext &, const common::Indirection<A> &);
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &, const parser::Scalar<A> &);
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &, const parser::Constant<A> &);
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &, const parser::Integer<A> &);
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &, const parser::Logical<A> &);
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &, const parser::DefaultChar<A> &);
+
+// Indirections are silently traversed by AnalyzeExpr().
+template<typename A>
+MaybeExpr AnalyzeExpr(
+    ExpressionAnalysisContext &context, const common::Indirection<A> &x) {
+  return AnalyzeExpr(context, *x);
+}
+
 // These specializations create nested expression analysis contexts
 // to implement constraint checking.
 
@@ -109,7 +140,22 @@ template<typename A>
 std::optional<Expr<SomeType>> AnalyzeExpr(
     ExpressionAnalysisContext &context, const parser::Integer<A> &expr) {
   ExpressionAnalysisContext withCheck{
-      context, &ExpressionAnalysisContext::ConstantConstraint};
+      context, &ExpressionAnalysisContext::IntegerConstraint};
+  return AnalyzeExpr(withCheck, expr.thing);
+}
+
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &context, const parser::Logical<A> &expr) {
+  ExpressionAnalysisContext withCheck{
+      context, &ExpressionAnalysisContext::LogicalConstraint};
+  return AnalyzeExpr(withCheck, expr.thing);
+}
+template<typename A>
+std::optional<Expr<SomeType>> AnalyzeExpr(
+    ExpressionAnalysisContext &context, const parser::DefaultChar<A> &expr) {
+  ExpressionAnalysisContext withCheck{
+      context, &ExpressionAnalysisContext::DefaultCharConstraint};
   return AnalyzeExpr(withCheck, expr.thing);
 }
 }