[flang] Character length conversion on structure constructor component assignments
authorpeter klausler <pklausler@nvidia.com>
Thu, 28 Feb 2019 21:31:34 +0000 (13:31 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 5 Mar 2019 00:30:24 +0000 (16:30 -0800)
Original-commit: flang-compiler/f18@051c1dd923a3b321d1a19768414caf93732a3426
Reviewed-on: https://github.com/flang-compiler/f18/pull/311
Tree-same-pre-rewrite: false

flang/lib/evaluate/expression.cc
flang/lib/evaluate/fold.cc
flang/lib/evaluate/type.cc
flang/test/semantics/CMakeLists.txt

index 4725162..21bc222 100644 (file)
@@ -298,7 +298,7 @@ std::ostream &StructureConstructor::AsFortran(std::ostream &o) const {
 
 std::ostream &DerivedTypeSpecAsFortran(
     std::ostream &o, const semantics::DerivedTypeSpec &spec) {
-  o << "TYPE("s << spec.typeSymbol().name().ToString();
+  o << spec.typeSymbol().name().ToString();
   if (!spec.parameters().empty()) {
     char ch{'('};
     for (const auto &[name, value] : spec.parameters()) {
index ee91d7d..b9241fe 100644 (file)
@@ -702,6 +702,24 @@ Expr<Type<TypeCategory::Character, KIND>> FoldOperation(
   return Expr<Result>{std::move(x)};
 }
 
+template<int KIND>
+Expr<Type<TypeCategory::Character, KIND>> FoldOperation(
+    FoldingContext &context, SetLength<KIND> &&x) {
+  using Result = Type<TypeCategory::Character, KIND>;
+  if (auto folded{FoldOperands(context, x.left(), x.right())}) {
+    auto oldLength{static_cast<std::int64_t>(folded->first.size())};
+    auto newLength{folded->second.ToInt64()};
+    if (newLength < oldLength) {
+      folded->first.erase(newLength);
+    } else {
+      folded->first.append(newLength - oldLength, ' ');
+    }
+    CHECK(static_cast<std::int64_t>(folded->first.size()) == newLength);
+    return Expr<Result>{Constant<Result>{std::move(folded->first)}};
+  }
+  return Expr<Result>{std::move(x)};
+}
+
 template<typename T>
 Expr<LogicalResult> FoldOperation(
     FoldingContext &context, Relational<T> &&relation) {
index 252aad8..7516114 100644 (file)
@@ -207,7 +207,7 @@ bool SomeKind<TypeCategory::Derived>::operator==(
 
 std::string SomeDerived::AsFortran() const {
   std::stringstream out;
-  DerivedTypeSpecAsFortran(out, spec());
+  DerivedTypeSpecAsFortran(out << "TYPE(", spec()) << ')';
   return out.str();
 }
 }
index 2df6257..74eda1e 100644 (file)
@@ -117,6 +117,7 @@ set(MODFILE_TESTS
   modfile19.f90
   modfile20.f90
   modfile21.f90
+  modfile22.f90
 )
 
 set(LABEL_TESTS