diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 34ee800668ca..3070b4675e8e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3180,6 +3180,17 @@ typedef struct gfc_finalizer
 gfc_finalizer;
 #define gfc_get_finalizer() XCNEW (gfc_finalizer)
 
+/* Control clause translation per-directive for gfc_trans_omp_clauses.  Also
+   used for gfc_omp_instantiate_mappers.  */
+
+enum toc_directive
+{
+  TOC_OPENMP,
+  TOC_OPENMP_DECLARE_SIMD,
+  TOC_OPENMP_EXIT_DATA,
+  TOC_OPENACC,
+  TOC_OPENACC_DECLARE
+};
 
 /************************ Function prototypes *************************/
 
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index a9dc1a617be5..829b28b24c79 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -2404,11 +2404,13 @@ static vec<tree, va_heap, vl_embed> *doacross_steps;
 /* Translate an array section or array element.  */
 
 static void
-gfc_trans_omp_array_section (stmtblock_t *block, gfc_exec_op op,
+gfc_trans_omp_array_section (stmtblock_t *block, toc_directive cd,
 			     gfc_omp_namelist *n, tree decl, bool element,
-			     bool openmp, gomp_map_kind ptr_kind, tree &node,
+			     gomp_map_kind ptr_kind, tree &node,
 			     tree &node2, tree &node3, tree &node4)
 {
+  bool openmp = (cd < TOC_OPENACC);
+  bool omp_exit_data = (cd == TOC_OPENMP_EXIT_DATA);
   gfc_se se;
   tree ptr, ptr2;
   tree elemsz = NULL_TREE;
@@ -2460,7 +2462,7 @@ gfc_trans_omp_array_section (stmtblock_t *block, gfc_exec_op op,
   if (POINTER_TYPE_P (TREE_TYPE (decl))
       && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
       && ptr_kind == GOMP_MAP_POINTER
-      && op != EXEC_OMP_TARGET_EXIT_DATA
+      && !omp_exit_data
       && OMP_CLAUSE_MAP_KIND (node) != GOMP_MAP_RELEASE
       && OMP_CLAUSE_MAP_KIND (node) != GOMP_MAP_DELETE)
 
@@ -2479,8 +2481,7 @@ gfc_trans_omp_array_section (stmtblock_t *block, gfc_exec_op op,
       gomp_map_kind map_kind;
       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DELETE)
 	map_kind = OMP_CLAUSE_MAP_KIND (node);
-      else if (op == EXEC_OMP_TARGET_EXIT_DATA
-	       || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE)
+      else if (omp_exit_data || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE)
 	map_kind = GOMP_MAP_RELEASE;
       else
 	map_kind = GOMP_MAP_TO;
@@ -2499,11 +2500,10 @@ gfc_trans_omp_array_section (stmtblock_t *block, gfc_exec_op op,
       OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DELETE
 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE
-	  || op == EXEC_OMP_TARGET_EXIT_DATA)
+	  || omp_exit_data)
 	{
-	  gomp_map_kind map_kind
-	    = (op == EXEC_OMP_TARGET_EXIT_DATA) ? GOMP_MAP_RELEASE
-						: OMP_CLAUSE_MAP_KIND (node);
+	  gomp_map_kind map_kind = omp_exit_data ? GOMP_MAP_RELEASE
+						 : OMP_CLAUSE_MAP_KIND (node);
 	  OMP_CLAUSE_SET_MAP_KIND (node2, map_kind);
 	  OMP_CLAUSE_RELEASE_DESCRIPTOR (node2) = 1;
 	}
@@ -2681,9 +2681,11 @@ get_symbol_rooted_namelist (hash_map<gfc_symbol *,
 
 static tree
 gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
-		       locus where, bool declare_simd = false,
-		       bool openacc = false, gfc_exec_op op = EXEC_NOP)
+		       locus where, toc_directive cd = TOC_OPENMP)
 {
+  bool declare_simd = (cd == TOC_OPENMP_DECLARE_SIMD);
+  bool openacc = (cd >= TOC_OPENACC);
+  bool omp_exit_data = (cd == TOC_OPENMP_EXIT_DATA);
   tree omp_clauses = NULL_TREE, prev_clauses, chunk_size, c;
   tree iterator = NULL_TREE;
   tree tree_block = NULL_TREE;
@@ -3250,7 +3252,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		      && n->sym->ts.deferred
 		      && n->sym->attr.omp_declare_target
 		      && (always_modifier || n->sym->attr.pointer)
-		      && op != EXEC_OMP_TARGET_EXIT_DATA
+		      && !omp_exit_data
 		      && n->u.map_op != OMP_MAP_DELETE
 		      && n->u.map_op != OMP_MAP_RELEASE)
 		    {
@@ -3313,14 +3315,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 							     NULL_TREE));
 			}
 		      /* For descriptor types, the unmapping happens below.  */
-		      if (op != EXEC_OMP_TARGET_EXIT_DATA
+		      if (!omp_exit_data
 			  || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
 			{
 			  enum gomp_map_kind gmk = GOMP_MAP_POINTER;
-			  if (op == EXEC_OMP_TARGET_EXIT_DATA
-			      && n->u.map_op == OMP_MAP_DELETE)
+			  if (omp_exit_data && n->u.map_op == OMP_MAP_DELETE)
 			    gmk = GOMP_MAP_DELETE;
-			  else if (op == EXEC_OMP_TARGET_EXIT_DATA)
+			  else if (omp_exit_data)
 			    gmk = GOMP_MAP_RELEASE;
 			  tree size;
 			  if (gmk == GOMP_MAP_RELEASE || gmk == GOMP_MAP_DELETE)
@@ -3340,10 +3341,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 			      || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
 			{
 			  enum gomp_map_kind gmk;
-			  if (op == EXEC_OMP_TARGET_EXIT_DATA
-			      && n->u.map_op == OMP_MAP_DELETE)
+			  if (omp_exit_data && n->u.map_op == OMP_MAP_DELETE)
 			    gmk = GOMP_MAP_DELETE;
-			  else if (op == EXEC_OMP_TARGET_EXIT_DATA)
+			  else if (omp_exit_data)
 			    gmk = GOMP_MAP_RELEASE;
 			  else
 			    gmk = GOMP_MAP_POINTER;
@@ -3375,14 +3375,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		      OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
 		      if (n->u.map_op == OMP_MAP_DELETE)
 			map_kind = GOMP_MAP_DELETE;
-		      else if (op == EXEC_OMP_TARGET_EXIT_DATA
-			       || n->u.map_op == OMP_MAP_RELEASE)
+		      else if (omp_exit_data || n->u.map_op == OMP_MAP_RELEASE)
 			map_kind = GOMP_MAP_RELEASE;
 		      else
 			map_kind = GOMP_MAP_TO_PSET;
 		      OMP_CLAUSE_SET_MAP_KIND (node2, map_kind);
 
-		      if (op != EXEC_OMP_TARGET_EXIT_DATA
+		      if (!omp_exit_data
 			  && n->u.map_op != OMP_MAP_DELETE
 			  && n->u.map_op != OMP_MAP_RELEASE)
 			{
@@ -3581,9 +3580,8 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		      && !(POINTER_TYPE_P (type)
 			   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))))
 		    k = GOMP_MAP_FIRSTPRIVATE_POINTER;
-		  gfc_trans_omp_array_section (block, op, n, decl, element,
-					       !openacc, k, node, node2,
-					       node3, node4);
+		  gfc_trans_omp_array_section (block, cd, n, decl, element,
+					       k, node, node2, node3, node4);
 		}
 	      else if (n->expr
 		       && n->expr->expr_type == EXPR_VARIABLE
@@ -3643,7 +3641,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 			  gomp_map_kind kind;
 			  if (n->u.map_op == OMP_MAP_DELETE)
 			    kind = GOMP_MAP_DELETE;
-			  else if (op == EXEC_OMP_TARGET_EXIT_DATA)
+			  else if (omp_exit_data)
 			    kind = GOMP_MAP_RELEASE;
 			  else
 			    kind = GOMP_MAP_TO;
@@ -3828,7 +3826,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 			  else if (n->u.map_op == OMP_MAP_RELEASE
 				   || n->u.map_op == OMP_MAP_DELETE)
 			    ;
-			  else if (op == EXEC_OMP_TARGET_EXIT_DATA)
+			  else if (omp_exit_data)
 			    map_kind = GOMP_MAP_RELEASE;
 			  else
 			    map_kind = GOMP_MAP_ALLOC;
@@ -3968,9 +3966,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		      /* An array element or section.  */
 		      bool element = lastref->u.ar.type == AR_ELEMENT;
 		      gomp_map_kind kind = GOMP_MAP_ATTACH_DETACH;
-		      gfc_trans_omp_array_section (block, op, n, inner, element,
-						   !openacc, kind, node, node2,
-						   node3, node4);
+		      gfc_trans_omp_array_section (block, cd, n, inner, element,
+						   kind, node, node2, node3,
+						   node4);
 		    }
 		  else
 		    gcc_unreachable ();
@@ -4906,7 +4904,7 @@ gfc_trans_oacc_construct (gfc_code *code)
 
   gfc_start_block (&block);
   oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
-					code->loc, false, true);
+					code->loc, TOC_OPENACC);
   pushlevel ();
   stmt = gfc_trans_omp_code (code->block->next, true);
   stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
@@ -4944,7 +4942,7 @@ gfc_trans_oacc_executable_directive (gfc_code *code)
 
   gfc_start_block (&block);
   oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
-					code->loc, false, true, code->op);
+					code->loc, TOC_OPENACC);
   stmt = build1_loc (input_location, construct_code, void_type_node, 
 		     oacc_clauses);
   gfc_add_expr_to_block (&block, stmt);
@@ -6143,7 +6141,7 @@ gfc_trans_oacc_combined_directive (gfc_code *code)
       if (construct_code == OACC_KERNELS)
 	construct_clauses.lists[OMP_LIST_REDUCTION] = NULL;
       oacc_clauses = gfc_trans_omp_clauses (&block, &construct_clauses,
-					    code->loc, false, true);
+					    code->loc, TOC_OPENACC);
     }
   if (!loop_clauses.seq)
     pblock = &block;
@@ -7889,7 +7887,7 @@ gfc_trans_omp_target_exit_data (gfc_code *code)
 
   gfc_start_block (&block);
   omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
-				       code->loc, false, false, code->op);
+				       code->loc, TOC_OPENMP_EXIT_DATA);
   stmt = build1_loc (input_location, OMP_TARGET_EXIT_DATA, void_type_node,
 		     omp_clauses);
   gfc_add_expr_to_block (&block, stmt);
@@ -8088,7 +8086,7 @@ gfc_trans_oacc_declare (gfc_code *code)
   gfc_start_block (&block);
 
   oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.oacc_declare->clauses,
-					code->loc, false, true);
+					code->loc, TOC_OPENACC_DECLARE);
   stmt = gfc_trans_omp_code (code->block->next, true);
   stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
 		     oacc_clauses);
@@ -8262,7 +8260,8 @@ gfc_trans_omp_declare_simd (gfc_namespace *ns)
   gfc_omp_declare_simd *ods;
   for (ods = ns->omp_declare_simd; ods; ods = ods->next)
     {
-      tree c = gfc_trans_omp_clauses (NULL, ods->clauses, ods->where, true);
+      tree c = gfc_trans_omp_clauses (NULL, ods->clauses, ods->where,
+				      TOC_OPENMP_DECLARE_SIMD);
       tree fndecl = ns->proc_name->backend_decl;
       if (c != NULL_TREE)
 	c = tree_cons (NULL_TREE, c, NULL_TREE);
@@ -8389,8 +8388,10 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns)
 		      }
 		      break;
 		    case CTX_PROPERTY_SIMD:
-		      properties = gfc_trans_omp_clauses (NULL, otp->clauses,
-							  odv->where, true);
+		      properties
+			= gfc_trans_omp_clauses (NULL, otp->clauses,
+						 odv->where,
+						 TOC_OPENMP_DECLARE_SIMD);
 		      break;
 		    default:
 		      gcc_unreachable ();
