[flang] Lots of debugging and refinement
authorpeter klausler <pklausler@nvidia.com>
Mon, 8 Apr 2019 23:16:55 +0000 (16:16 -0700)
committerpeter klausler <pklausler@nvidia.com>
Mon, 8 Apr 2019 23:16:55 +0000 (16:16 -0700)
Original-commit: flang-compiler/f18@1c3c30b5401ff04550d2289b25bafe6229a4a2cc
Reviewed-on: https://github.com/flang-compiler/f18/pull/390
Tree-same-pre-rewrite: false

16 files changed:
flang/lib/common/idioms.h
flang/lib/common/template.h
flang/lib/evaluate/common.h
flang/lib/evaluate/constant.h
flang/lib/evaluate/integer.h
flang/lib/evaluate/shape.cc
flang/lib/evaluate/variable.h
flang/lib/parser/message.cc
flang/lib/parser/message.h
flang/lib/parser/parse-state.h
flang/lib/parser/parse-tree.cc
flang/lib/parser/prescan.h
flang/lib/semantics/assignment.cc
flang/lib/semantics/expression.h
flang/lib/semantics/resolve-names.cc
flang/lib/semantics/rewrite-parse-tree.cc

index c72b2b9..cb09898 100644 (file)
@@ -141,7 +141,9 @@ template<typename A> A Clone(const A &x) { return x; }
 // confusing C++ reference forwarding semantics, e.g.
 //   template<typename A, NOT_LVALUE_REFERENCE(A)> void foo(A &&);
 // Works on parameter packs as well.
-#define NOT_LVALUE_REFERENCE(X) bool = !std::is_lvalue_reference_v<X>
-#define NO_LVALUE_REFERENCE(X) bool = (... && !std::is_lvalue_reference_v<X>)
+#define NOT_LVALUE_REFERENCE(X) \
+  typename = std::enable_if_t<!std::is_lvalue_reference_v<X>, int>
+#define NO_LVALUE_REFERENCE(X) \
+  typename = std::enable_if_t<(... && !std::is_lvalue_reference_v<X>), int>
 }
 #endif  // FORTRAN_COMMON_IDIOMS_H_
index 2c88bd4..8f5647c 100644 (file)
@@ -111,6 +111,12 @@ std::optional<A> JoinOptional(std::optional<std::optional<A>> &&x) {
   return std::nullopt;
 }
 
+// Copy a value from one variant type to another.  The types allowed in the
+// source variant must all be allowed in the destination variant type.
+template<typename TOV, typename FROMV> TOV CopyVariant(const FROMV &u) {
+  return std::visit([](const auto &x) -> TOV { return {x}; }, std::move(u));
+}
+
 // Move a value from one variant type to another.  The types allowed in the
 // source variant must all be allowed in the destination variant type.
 template<typename TOV, typename FROMV, NOT_LVALUE_REFERENCE(FROMV)>
index 63f9950..a8a778c 100644 (file)
@@ -190,9 +190,8 @@ using HostUnsignedInt =
 #define EVALUATE_UNION_CLASS_BOILERPLATE(t) \
   CLASS_BOILERPLATE(t) \
   template<typename _A> explicit t(const _A &x) : u{x} {} \
-  template<typename _A> \
-  explicit t(std::enable_if_t<!std::is_reference_v<_A>, _A> &&x) \
-    : u(std::move(x)) {} \
+  template<typename _A, NOT_LVALUE_REFERENCE(_A)> \
+  explicit t(_A &&x) : u(std::move(x)) {} \
   bool operator==(const t &that) const { return u == that.u; }
 
 // Forward definition of Expr<> so that it can be indirectly used in its own
index 1858f1d..80757f3 100644 (file)
@@ -43,11 +43,11 @@ public:
   using ScalarValue = SCALAR;
 
   template<typename A> ConstantBase(const A &x) : values_{x} {}
-  template<typename A>
-  ConstantBase(std::enable_if_t<!std::is_reference_v<A>, A> &&x)
-    : values_{std::move(x)} {}
+  template<typename A, NOT_LVALUE_REFERENCE(A)>
+  ConstantBase(A &&x) : values_{std::move(x)} {}
   ConstantBase(std::vector<ScalarValue> &&x, std::vector<std::int64_t> &&dims)
     : values_(std::move(x)), shape_(std::move(dims)) {}
+  DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ConstantBase)
   ~ConstantBase();
 
   int Rank() const { return static_cast<int>(shape_.size()); }
index 834cf65..d1a5b6e 100644 (file)
@@ -118,11 +118,13 @@ public:
   // Constructors and value-generating static functions
   constexpr Integer() { Clear(); }  // default constructor: zero
   constexpr Integer(const Integer &) = default;
+  constexpr Integer(Integer &&) = default;
 
   // C++'s integral types can all be converted to Integer
   // with silent truncation.
-  template<typename INT> constexpr Integer(INT n) {
-    static_assert(std::is_integral_v<INT>);
+  template<typename INT,
+      typename = std::enable_if_t<std::is_integral_v<INT>, int>>
+  constexpr Integer(INT n) {
     constexpr int nBits = CHAR_BIT * sizeof n;
     if constexpr (nBits < partBits) {
       if constexpr (std::is_unsigned_v<INT>) {
index 9103a6b..3a9d182 100644 (file)
@@ -39,8 +39,8 @@ std::optional<Shape> AsShape(ExtentExpr &&arrayExpr) {
   }
   if (auto *constructor{UnwrapExpr<ArrayConstructor<ExtentType>>(arrayExpr)}) {
     Shape result;
-    for (const auto &value : constructor->values()) {
-      if (const auto *expr{std::get_if<ExtentExpr>(&value.u)}) {
+    for (auto &value : constructor->values()) {
+      if (auto *expr{std::get_if<ExtentExpr>(&value.u)}) {
         if (expr->Rank() == 0) {
           result.emplace_back(std::move(*expr));
           continue;
index 02b4d7d..9e193c4 100644 (file)
@@ -348,7 +348,7 @@ public:
   static_assert(IsSpecificIntrinsicType<Result> ||
       std::is_same_v<Result, SomeKind<TypeCategory::Derived>>);
   EVALUATE_UNION_CLASS_BOILERPLATE(Designator)
-  Designator(const DataRef &that) : u{common::MoveVariant<Variant>(that.u)} {}
+  Designator(const DataRef &that) : u{common::CopyVariant<Variant>(that.u)} {}
   Designator(DataRef &&that)
     : u{common::MoveVariant<Variant>(std::move(that.u))} {}
 
index 9878637..d1a747e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION.  All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -292,9 +292,10 @@ void Messages::Emit(
 }
 
 void Messages::AttachTo(Message &msg) {
-  for (const Message &m : messages_) {
-    msg.Attach(m);
+  for (Message &m : messages_) {
+    msg.Attach(std::move(m));
   }
+  messages_.clear();
 }
 
 bool Messages::AnyFatalError() const {
index 8c7bddb..fbe97bb 100644 (file)
@@ -151,9 +151,8 @@ public:
     attachmentIsContext_ = true;
   }
   Message &Attach(Message *);
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  Message &Attach(A &&... args) {
-    return Attach(new Message{std::move(args)...});  // reference-counted
+  template<typename... A> Message &Attach(A &&... args) {
+    return Attach(new Message{std::forward<A>(args)...});  // reference-counted
   }
 
   bool SortBefore(const Message &that) const;
@@ -205,8 +204,8 @@ public:
 
   bool empty() const { return messages_.empty(); }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)> Message &Say(A... args) {
-    last_ = messages_.emplace_after(last_, std::move(args)...);
+  template<typename... A> Message &Say(A... args) {
+    last_ = messages_.emplace_after(last_, std::forward<A>(args)...);
     return *last_;
   }
 
@@ -254,17 +253,16 @@ public:
     return common::ScopedSet(at_, std::move(at));
   }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  Message *Say(CharBlock at, A &&... args) {
+  template<typename... A> Message *Say(CharBlock at, A &&... args) {
     if (messages_ != nullptr) {
-      return &messages_->Say(at, std::move(args)...);
+      return &messages_->Say(at, std::forward<A>(args)...);
     } else {
       return nullptr;
     }
   }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)> Message *Say(A &&... args) {
-    return Say(at_, std::move(args)...);
+  template<typename... A> Message *Say(A &&... args) {
+    return Say(at_, std::forward<A>(args)...);
   }
 
 private:
index 13f25f9..65ec9ec 100644 (file)
@@ -143,21 +143,19 @@ public:
     context_ = context_->attachment();
   }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  void Say(CharBlock range, A &&... args) {
+  template<typename... A> void Say(CharBlock range, A &&... args) {
     if (deferMessages_) {
       anyDeferredMessages_ = true;
     } else {
-      messages_.Say(range, std::move(args)...).SetContext(context_.get());
+      messages_.Say(range, std::forward<A>(args)...).SetContext(context_.get());
     }
   }
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  void Say(const MessageFixedText &text, A &&... args) {
-    Say(p_, text, std::move(args)...);
+  template<typename... A> void Say(const MessageFixedText &text, A &&... args) {
+    Say(p_, text, std::forward<A>(args)...);
   }
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
+  template<typename... A>
   void Say(const MessageExpectedText &text, A &&... args) {
-    Say(p_, text, std::move(args)...);
+    Say(p_, text, std::forward<A>(args)...);
   }
 
   void Nonstandard(LanguageFeature lf, const MessageFixedText &msg) {
index 114dc20..9497d64 100644 (file)
@@ -87,8 +87,9 @@ bool DoConstruct::IsDoConcurrent() const {
   return control && std::holds_alternative<LoopControl::Concurrent>(control->u);
 }
 
-static Designator MakeArrayElementRef(Name &name, std::list<Expr> &subscripts) {
-  ArrayElement arrayElement{name, std::list<SectionSubscript>{}};
+static Designator MakeArrayElementRef(
+    const Name &name, std::list<Expr> &subscripts) {
+  ArrayElement arrayElement{Name{name.source}, std::list<SectionSubscript>{}};
   for (Expr &expr : subscripts) {
     arrayElement.subscripts.push_back(SectionSubscript{
         Scalar{Integer{common::Indirection{std::move(expr)}}}});
@@ -162,7 +163,8 @@ Statement<ActionStmt> StmtFunctionStmt::ConvertToAssignment() {
   auto &funcExpr{std::get<Scalar<Expr>>(t).thing};
   std::list<Expr> subscripts;
   for (Name &arg : funcArgs) {
-    subscripts.push_back(Expr{common::Indirection{Designator{arg}}});
+    subscripts.push_back(
+        Expr{common::Indirection{Designator{Name{arg.source}}}});
   }
   auto variable{
       Variable{common::Indirection{MakeArrayElementRef(funcName, subscripts)}}};
index 1214159..948fc3f 100644 (file)
@@ -70,8 +70,8 @@ public:
   TokenSequence TokenizePreprocessorDirective();
   Provenance GetCurrentProvenance() const { return GetProvenance(at_); }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)> Message &Say(A &&... a) {
-    Message &m{messages_.Say(std::move(a)...)};
+  template<typename... A> Message &Say(A &&... a) {
+    Message &m{messages_.Say(std::forward<A>(a)...)};
     std::optional<ProvenanceRange> range{m.GetProvenanceRange(cooked_)};
     CHECK(!range.has_value() || cooked_.IsValid(*range));
     return m;
index 8f31981..0ff23af 100644 (file)
@@ -120,9 +120,8 @@ private:
 
   MaskExpr GetMask(const parser::LogicalExpr &, bool defaultValue = true) const;
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  parser::Message *Say(A &&... args) {
-    return messages_.Say(std::move(args)...);
+  template<typename... A> parser::Message *Say(A &&... args) {
+    return messages_.Say(std::forward<A>(args)...);
   }
 
   SemanticsContext &context_;
index 604981c..ce01c7a 100644 (file)
@@ -80,14 +80,13 @@ public:
     return GetFoldingContext().messages();
   }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  parser::Message *Say(A &&... args) {
-    return GetContextualMessages().Say(std::move(args)...);
+  template<typename... A> parser::Message *Say(A &&... args) {
+    return GetContextualMessages().Say(std::forward<A>(args)...);
   }
 
-  template<typename T, typename... A, NO_LVALUE_REFERENCE(A)>
+  template<typename T, typename... A>
   parser::Message *SayAt(const T &parsed, A &&... args) {
-    return Say(parser::FindSourceLocation(parsed), std::move(args)...);
+    return Say(parser::FindSourceLocation(parsed), std::forward<A>(args)...);
   }
 
   int GetDefaultKind(common::TypeCategory);
index bcb2277..c1305b8 100644 (file)
@@ -172,12 +172,13 @@ public:
     }
   }
 
-  template<typename... A, NO_LVALUE_REFERENCE(A)>
-  Message &Say(const parser::Name &name, A &&... args) {
-    return messageHandler_.Say(name.source, std::move(args)...);
+  template<typename... A> Message &Say(A &&... args) {
+    return messageHandler_.Say(std::forward<A>(args)...);
   }
-  template<typename... A, NO_LVALUE_REFERENCE(A)> Message &Say(A &&... args) {
-    return messageHandler_.Say(std::move(args)...);
+  template<typename... A>
+  Message &Say(
+      const parser::Name &name, MessageFixedText &&text, const A &... args) {
+    return messageHandler_.Say(name.source, std::move(text), args...);
   }
 
 private:
@@ -491,7 +492,7 @@ public:
       SayAlreadyDeclared(name, *symbol);
       // replace the old symbol with a new one with correct details
       EraseSymbol(*symbol);
-      return MakeSymbol(name, attrs, details);
+      return MakeSymbol(name, attrs, std::move(details));
     }
   }
 
@@ -2186,14 +2187,14 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
         }
       }
     }
-    details.add_dummyArg(MakeSymbol(dummyName, dummyDetails));
+    details.add_dummyArg(MakeSymbol(dummyName, std::move(dummyDetails)));
   }
   EraseSymbol(name);  // added by PushSubprogramScope
   EntityDetails resultDetails;
   if (resultType) {
     resultDetails.set_type(*resultType);
   }
-  details.set_result(MakeSymbol(name, resultDetails));
+  details.set_result(MakeSymbol(name, std::move(resultDetails)));
   return true;
 }
 
@@ -2318,7 +2319,8 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
   // add function result to function scope
   EntityDetails funcResultDetails;
   funcResultDetails.set_funcResult(true);
-  funcInfo_.resultSymbol = &MakeSymbol(*funcResultName, funcResultDetails);
+  funcInfo_.resultSymbol =
+      &MakeSymbol(*funcResultName, std::move(funcResultDetails));
   details.set_result(*funcInfo_.resultSymbol);
 }
 
@@ -3457,7 +3459,7 @@ void DeclarationVisitor::CheckSaveStmts() {
           "Explicit SAVE of '%s' is redundant due to global SAVE statement"_err_en_US,
           *saveInfo_.saveAll, "Global SAVE statement"_en_US);
     } else if (auto msg{CheckSaveAttr(*symbol)}) {
-      Say(name, *msg);
+      Say(name, std::move(*msg));
     } else {
       SetSaveAttr(*symbol);
     }
@@ -3800,7 +3802,7 @@ Symbol *DeclarationVisitor::MakeTypeSymbol(
         std::holds_alternative<ProcBindingDetails>(details)) {
       attrs.set(Attr::PRIVATE);
     }
-    Symbol &result{MakeSymbol(name, attrs, details)};
+    Symbol &result{MakeSymbol(name, attrs, std::move(details))};
     if (result.has<TypeParamDetails>()) {
       derivedType.symbol()->get<DerivedTypeDetails>().add_paramDecl(result);
     }
index 1788f11..a1cd773 100644 (file)
@@ -91,10 +91,11 @@ void RewriteMutator::Post(parser::SpecificationPart &x) {
 bool RewriteMutator::Pre(parser::ExecutionPart &x) {
   auto origFirst{x.v.begin()};  // insert each elem before origFirst
   for (stmtFuncType &sf : stmtFuncsToConvert_) {
-    auto &&stmt = sf.statement.value().ConvertToAssignment();
+    auto stmt{sf.statement.value().ConvertToAssignment()};
     stmt.source = sf.source;
     x.v.insert(origFirst,
-        parser::ExecutionPartConstruct{parser::ExecutableConstruct{stmt}});
+        parser::ExecutionPartConstruct{
+            parser::ExecutableConstruct{std::move(stmt)}});
   }
   stmtFuncsToConvert_.clear();
   return true;