[flang] Length conversions in array constructors, and fix their formatting
authorpeter klausler <pklausler@nvidia.com>
Fri, 1 Mar 2019 00:30:55 +0000 (16:30 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 5 Mar 2019 00:30:24 +0000 (16:30 -0800)
Original-commit: flang-compiler/f18@88cdb49f4892a20f2628f11373a0f1c9c32a6c1e
Reviewed-on: https://github.com/flang-compiler/f18/pull/311
Tree-same-pre-rewrite: false

flang/lib/evaluate/constant.cc
flang/test/semantics/modfile22.f90 [new file with mode: 0644]

index 0fcf972..d09a4d3 100644 (file)
@@ -16,6 +16,7 @@
 #include "expression.h"
 #include "type.h"
 #include "../parser/characters.h"
+#include <string>
 
 namespace Fortran::evaluate {
 
@@ -124,7 +125,7 @@ Constant<Type<TypeCategory::Character, KIND>>::Constant(ScalarValue &&str)
 template<int KIND>
 Constant<Type<TypeCategory::Character, KIND>>::Constant(std::int64_t len,
     std::vector<ScalarValue> &&strings, std::vector<std::int64_t> &&dims)
-  : length_{len} {
+  : length_{len}, shape_{std::move(dims)} {
   values_.assign(strings.size() * length_,
       static_cast<typename ScalarValue::value_type>(' '));
   std::int64_t at{0};
@@ -184,15 +185,17 @@ std::ostream &Constant<Type<TypeCategory::Character, KIND>>::AsFortran(
     o << "reshape(";
   }
   if (Rank() > 0) {
-    o << '[' << GetType().AsFortran() << "::";
+    o << '[' << GetType().AsFortran(std::to_string(length_)) << "::";
   }
   auto total{static_cast<std::int64_t>(size())};
   for (std::int64_t j{0}; j < total; ++j) {
     ScalarValue value{values_.substr(j * length_, length_)};
     if (j > 0) {
       o << ',';
+    } else if (Rank() == 0) {
+      o << Result::kind << '_';
     }
-    o << Result::kind << '_' << parser::QuoteCharacterLiteral(value);
+    o << parser::QuoteCharacterLiteral(value);
   }
   if (Rank() > 0) {
     o << ']';
diff --git a/flang/test/semantics/modfile22.f90 b/flang/test/semantics/modfile22.f90
new file mode 100644 (file)
index 0000000..4bf99eb
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (c) 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.
+! You may obtain a copy of the License at
+!
+!     http://www.apache.org/licenses/LICENSE-2.0
+!
+! Unless required by applicable law or agreed to in writing, software
+! distributed under the License is distributed on an "AS IS" BASIS,
+! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+! See the License for the specific language governing permissions and
+! limitations under the License.
+
+! Test character length conversions in constructors
+
+module m
+type :: t(k)
+  integer, kind :: k = 1
+  character(kind=k,len=1) :: a
+  character(kind=k,len=3) :: b
+end type t
+type(t), parameter :: p = t(k=1)(a='xx',b='xx')
+character(len=2), parameter :: c2(3) = [character(len=2) :: 'x', 'xx', 'xxx']
+end module m
+
+!Expect: m.mod
+!module m
+!type::t(k)
+!integer(4),kind::k=1_4
+!character(1_4,int(k,kind=8))::a
+!character(3_4,int(k,kind=8))::b
+!end type
+!type(t),parameter::p=t(k=1_4)(a=1_"x",b=1_"xx ")
+!character(2_4,1),parameter::c2(1_8:3_8)=[CHARACTER(KIND=1,LEN=2)::"x ","xx","xx"]
+!end