Walk(elem, mutator);
}
}
+// When a list constitutes a Block, invoke the visitor or mutator.
+template<typename V> void Walk(const Block &x, V &visitor) {
+ if (visitor.Pre(x)) {
+ for (const auto &elem : x) {
+ Walk(elem, visitor);
+ }
+ visitor.Post(x);
+ }
+}
+template<typename M> void Walk(Block &x, M &mutator) {
+ if (mutator.Pre(x)) {
+ for (auto &elem : x) {
+ Walk(elem, mutator);
+ }
+ }
+ mutator.Post(x);
+}
template<std::size_t I = 0, typename Func, typename T>
void ForEachInTuple(const T &tuple, Func func) {
if constexpr (I < std::tuple_size_v<T>) {
#include "canonicalize-do.h"
#include "../parser/parse-tree-visitor.h"
+#include <variant>
+#include <vector>
namespace Fortran::parser {
CanonicalizationOfDoLoops canonicalizationOfDoLoops{labelInfos};
Walk(program, canonicalizationOfDoLoops);
}
-
} // namespace Fortran::parser
! See the License for the specific language governing permissions and
! limitations under the License.
+! negative test -- invalid labels, out of range
+
! RUN: ${F18} -funparse-with-symbols %s 2>&1 | ${FileCheck} %s
! CHECK: end do
! See the License for the specific language governing permissions and
! limitations under the License.
+! negative test -- invalid labels, out of range
+
! RUN: ${F18} -funparse-with-symbols %s 2>&1 | ${FileCheck} %s
! CHECK: end do
! See the License for the specific language governing permissions and
! limitations under the License.
+! negative test -- invalid labels, out of range
+
! RUN: ${F18} -funparse-with-symbols %s 2>&1 | ${FileCheck} %s
! CHECK: 10 continue
! CHECK: end do
print *, j1, j2, j3
do 2 j4=1,2
print *, j3, j4
-2 continue
+2 end do
else
do 3 j3=3,4
print *, j1, j2, j3
do 3 j4=3,4
print *, j3, j4
-3 continue
+3 end do
end if
print *, j1, j2
1 continue
+ do 4 j1=3,4 ! adjacent non-block DO loops
+4 print *, j1
+ do 5 j1=5,6 ! non-block DO loop at end of execution part
+5 print *, j1
end