gomp-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gomp-discuss] C parser patch for parsing omp pragmas


From: Kurochkin Dmitriy
Subject: [Gomp-discuss] C parser patch for parsing omp pragmas
Date: Fri, 18 Feb 2005 02:19:56 +0300
User-agent: Mutt/1.5.6+20040523i

Hello.

The patch for C parser by Joseph S. Myers taken from
http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01969.html.

It is not fully functional yet, but it gives an idea of parsing omp
pragmas. It follows the grammar from OpenMP standart (p.210 OpenMP 2.5
public draft). All the pragmas and clauses are just written to stdout.

"#pragma omp section" is not handled. Variables are not checked to be
declared. And more...

The patch hasn't been properly tested.

To enable OpenMP pragmas handling use '-fopenmp' flag.

Feedback is welcomed!

PS. Sorry for my english.

Best regards,
                Dmitriy


--- orig/gcc/c-parser.c
+++ mod/gcc/c-parser.c
@@ -56,6 +56,8 @@
 #include "ggc.h"
 #include "c-common.h"
 
+#include <ctype.h>
+
 
 /* Miscellaneous data and functions needed for the parser.  */
 
@@ -256,10 +258,30 @@
   C_ID_NONE
 } c_id_kind;
 
+typedef enum pragma_omp_kind {
+  PRAGMA_OMP_NONE = 0,
+
+  PRAGMA_OMP_ATOMIC,
+  PRAGMA_OMP_BARRIER,
+  PRAGMA_OMP_CRITICAL,
+  PRAGMA_OMP_FLUSH,
+  PRAGMA_OMP_FOR,
+  PRAGMA_OMP_MASTER,
+  PRAGMA_OMP_ORDERED,
+  PRAGMA_OMP_PARALLEL,
+  PRAGMA_OMP_PARALLEL_FOR,
+  PRAGMA_OMP_PARALLEL_SECTIONS,
+  PRAGMA_OMP_SECTION,
+  PRAGMA_OMP_SECTIONS,
+  PRAGMA_OMP_SINGLE,
+  PRAGMA_OMP_THREADPRIVATE
+} pragma_omp_kind;
+
 /* A single C token after string literal concatenation and conversion
    of preprocessing tokens to tokens.  */
 typedef struct c_token GTY (())
 {
+  ENUM_BITFIELD (pragma_omp_kind) omp_kind : 8;
   /* The kind of token.  */
   ENUM_BITFIELD (cpp_ttype) type : 8;
   /* If this token is a CPP_NAME, this value indicates whether also
@@ -300,6 +322,9 @@
   token->type = c_lex (&token->value);
   token->location = input_location;
   token->in_system_header = in_system_header;
+
+  token->omp_kind = PRAGMA_OMP_NONE;
+
   switch (token->type)
     {
     case CPP_NAME:
@@ -380,6 +405,65 @@
       token->id_kind = C_ID_NONE;
       token->keyword = RID_MAX;
       break;
+    case CPP_PRAGMA:
+      token->id_kind = C_ID_NONE;
+      token->keyword = RID_MAX;
+      
+      if (flag_openmp)
+       {
+         const char *p = TREE_STRING_POINTER (token->value);
+
+         /* parsing "omp" */
+         while (*p != '\n' && isspace (*p))
+           ++p;
+
+         if (strncmp ("omp", p, 3))
+           break;
+
+         p += 3;
+         if (!isspace (*p) || *p == '\n')
+           break;
+
+         /* parsing first word */
+         while (*p != '\n' && isspace (*p))
+           ++p;
+
+         if (!strncmp ("atomic", p, 6) && isspace (*(p + 6)))
+           token->omp_kind = PRAGMA_OMP_ATOMIC;
+         else if (!strncmp ("barrier", p, 7) && isspace (*(p + 7)))
+           token->omp_kind = PRAGMA_OMP_BARRIER;
+         else if (!strncmp ("critical", p, 8) && isspace (*(p + 8)))
+           token->omp_kind = PRAGMA_OMP_CRITICAL;
+         else if (!strncmp ("flush", p, 5) && isspace (*(p + 5)))
+           token->omp_kind = PRAGMA_OMP_FLUSH;
+         else if (!strncmp ("for", p, 3) && isspace (*(p + 3)))
+           token->omp_kind = PRAGMA_OMP_FOR;
+         else if (!strncmp ("master", p, 6) && isspace (*(p + 6)))
+           token->omp_kind = PRAGMA_OMP_MASTER;
+         else if (!strncmp ("ordered", p, 7) && isspace (*(p + 7)))
+           token->omp_kind = PRAGMA_OMP_ORDERED;
+         else if (!strncmp ("parallel", p, 8) && isspace (*(p += 8)))
+           {
+             /* parsing second word */
+             while (*p != '\n' && isspace (*p))
+               ++p;
+             if (!strncmp ("for", p, 3) && isspace (*(p + 3)))
+               token->omp_kind = PRAGMA_OMP_PARALLEL_FOR;
+             else if (!strncmp ("sections", p, 8) && isspace (*(p + 8)))
+               token->omp_kind = PRAGMA_OMP_PARALLEL_SECTIONS;
+             else
+               token->omp_kind = PRAGMA_OMP_PARALLEL;
+           }
+         else if (!strncmp ("section", p, 7) && isspace (*(p + 7)))
+           token->omp_kind = PRAGMA_OMP_SECTION;
+         else if (!strncmp ("sections", p, 8) && isspace (*(p + 8)))
+           token->omp_kind = PRAGMA_OMP_SECTIONS;
+         else if (!strncmp ("single", p, 6) && isspace (*(p + 6)))
+           token->omp_kind = PRAGMA_OMP_SINGLE;
+         else if (!strncmp ("threadprivate", p, 13) && isspace (*(p + 13)))
+           token->omp_kind = PRAGMA_OMP_THREADPRIVATE;
+       }
+      break;
     default:
       token->id_kind = C_ID_NONE;
       token->keyword = RID_MAX;
@@ -564,7 +648,10 @@
   else
     {
       gcc_assert (parser->tokens_avail == 1);
+      /* We CAN get CPP_EOF while handling deferred pragma */
+      /*
       gcc_assert (parser->tokens[0].type != CPP_EOF);
+      */
     }
   parser->tokens_avail--;
 }
@@ -865,6 +952,8 @@
 static struct c_expr c_parser_expression (c_parser *);
 static tree c_parser_expr_list (c_parser *);
 
+static void c_parser_pragma (c_parser *);
+
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
    translation-unit:
@@ -997,7 +1086,12 @@
    absence is diagnosed through the diagnosis of implicit int.  In GNU
    C we also allow but diagnose declarations without declaration
    specifiers, but only at top level (elsewhere they conflict with
-   other syntax).  */
+   other syntax).
+   
+   OpenMP:
+   
+   declaration:
+     threadprivate-directive  */
 
 static void
 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
@@ -1007,6 +1101,14 @@
   tree prefix_attrs;
   tree all_prefix_attrs;
   bool diagnosed_no_specs = false;
+
+  if (c_parser_next_token_is (parser, CPP_PRAGMA)
+      && c_parser_peek_token (parser)->omp_kind == PRAGMA_OMP_THREADPRIVATE)
+    {
+      c_parser_pragma (parser);
+      return;
+    }
+
   specs = build_null_declspecs ();
   c_parser_declspecs (parser, specs, true, true, start_attr_ok);
   if (parser->error)
@@ -2800,7 +2902,12 @@
    prefix attributes on the declaration.  ??? The syntax follows the
    old parser in requiring something after label declarations.
    Although they are erroneous if the labels declared aren't defined,
-   is it useful for the syntax to be this way?  */
+   is it useful for the syntax to be this way?
+   
+   OpenMP:
+   
+   block-item:
+     openmp-directive  */
 
 static tree
 c_parser_compound_statement (c_parser *parser)
@@ -2927,6 +3034,18 @@
          else
            goto statement;
        }
+      else if (c_parser_next_token_is (parser, CPP_PRAGMA))
+       {
+         switch (c_parser_peek_token (parser)->omp_kind)
+           {
+           case PRAGMA_OMP_BARRIER:
+           case PRAGMA_OMP_FLUSH:
+             c_parser_pragma (parser);
+             break;
+           default:
+             goto statement;
+           }
+       }
       else
        {
        statement:
@@ -3050,7 +3169,11 @@
      goto * expression ;
 
    TODO: Objective-C.
-*/
+
+   OpenMP:
+
+   statement:
+     openmp-construct  */
 
 static void
 c_parser_statement (c_parser *parser)
@@ -3139,6 +3262,24 @@
     case CPP_SEMICOLON:
       c_parser_consume_token (parser);
       break;
+    case CPP_PRAGMA:
+      switch (c_parser_peek_token (parser)->omp_kind)
+       {
+       case PRAGMA_OMP_ATOMIC:
+       case PRAGMA_OMP_CRITICAL:
+       case PRAGMA_OMP_FOR:
+       case PRAGMA_OMP_MASTER:
+       case PRAGMA_OMP_ORDERED:
+       case PRAGMA_OMP_PARALLEL:
+       case PRAGMA_OMP_PARALLEL_FOR:
+       case PRAGMA_OMP_PARALLEL_SECTIONS:
+       case PRAGMA_OMP_SECTIONS:
+       case PRAGMA_OMP_SINGLE:
+         c_parser_pragma (parser);
+         break;
+       default:
+         goto expr_stmt;
+       }
     default:
     expr_stmt:
       stmt = c_finish_expr_stmt (c_parser_expression (parser).value);
@@ -4792,17 +4933,838 @@
   return ret;
 }
 
+/* ====== */
+
+typedef enum pragma_omp_clause {
+  PRAGMA_OMP_CLAUSE_NONE = 0,
+
+  PRAGMA_OMP_CLAUSE_COPYIN,
+  PRAGMA_OMP_CLAUSE_DEFAULT,
+  PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
+  PRAGMA_OMP_CLAUSE_IF,
+  PRAGMA_OMP_CLAUSE_LASTPRIVATE,
+  PRAGMA_OMP_CLAUSE_NOWAIT,
+  PRAGMA_OMP_CLAUSE_ORDERED,
+  PRAGMA_OMP_CLAUSE_PRIVATE,
+  PRAGMA_OMP_CLAUSE_REDUCTION,
+  PRAGMA_OMP_CLAUSE_SCHEDULE,
+  PRAGMA_OMP_CLAUSE_SHARED
+} pragma_omp_clause;
+
+static pragma_omp_clause c_parser_pragma_omp_clause (c_parser *);
+
+static pragma_omp_clause
+c_parser_pragma_omp_clause (c_parser *parser)
+{
+  pragma_omp_clause result;
+
+  if (c_parser_next_token_is_keyword (parser, RID_IF))
+    {
+      result = PRAGMA_OMP_CLAUSE_IF;
+    }
+  else if (c_parser_next_token_is_not (parser, CPP_NAME))
+    {
+      result = PRAGMA_OMP_CLAUSE_NONE;
+    }
+  else
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (!strcmp ("copyin", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_COPYIN;
+       }
+      else if (!strcmp ("default", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_DEFAULT;
+       }
+      else if (!strcmp ("firstprivate", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
+       }
+      else if (!strcmp ("lastprivate", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
+       }
+      else if (!strcmp ("nowait", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_NOWAIT;
+       }
+      else if (!strcmp ("ordered", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_ORDERED;
+       }
+      else if (!strcmp ("private", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_PRIVATE;
+       }
+      else if (!strcmp ("reduction", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_REDUCTION;
+       }
+      else if (!strcmp ("schedule", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_SCHEDULE;
+       }
+      else if (!strcmp ("shared", p))
+       {
+         result = PRAGMA_OMP_CLAUSE_SHARED;
+       }
+      else
+       {
+         result = PRAGMA_OMP_CLAUSE_NONE;
+       }
+    }
+
+  if (result != PRAGMA_OMP_CLAUSE_NONE)
+    {
+      c_parser_consume_token (parser);
+    }
+  return result;
+}
+
+static void c_parser_pragma_omp_variable_list (c_parser *);
+
+static void
+c_parser_pragma_omp_variable_list (c_parser *parser)
+{
+  printf ("Variable list: ");
+
+  while (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      printf ("%s", IDENTIFIER_POINTER (c_parser_peek_token (parser)->value));
+      c_parser_consume_token (parser);
+
+      if (c_parser_next_token_is_not (parser, CPP_COMMA))
+       {
+         break;
+       }
+      c_parser_consume_token (parser);
+
+      printf (", ");
+    }
+  printf ("\n");
+}
+
+static void c_parser_pragma_omp_clause_copyin (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_copyin (c_parser *parser)
+{
+  printf ("copyin\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_default (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_default (c_parser *parser)
+{
+  printf ("default: ");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+  {
+    if (c_parser_next_token_is (parser, CPP_NAME))
+      {
+       const char *p = IDENTIFIER_POINTER (c_parser_peek_token 
(parser)->value);
+       if (!strcmp ("none", p))
+         {
+           printf ("none\n");
+         }
+       else if (!strcmp ("shared", p))
+         {
+           printf ("shared\n");
+         }
+       else
+         {
+           goto error;
+         }
+       c_parser_consume_token (parser);
+       c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+      }
+    else
+      {
+      error:
+       c_parser_error (parser, "'none' or 'shared' expected");
+      }
+  }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_firstprivate (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_firstprivate (c_parser *parser)
+{
+  printf ("firstprivate\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_if (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_if (c_parser *parser)
+{
+  printf ("if, NOT working now\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_lastprivate (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_lastprivate (c_parser *parser)
+{
+  printf ("lastprivate\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_clause_nowait (c_parser *);
+
+static inline void
+c_parser_pragma_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED)
+{
+  printf ("nowait\n");
+}
+
+static inline void c_parser_pragma_omp_clause_ordered (c_parser *);
+
+static inline void
+c_parser_pragma_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED)
+{
+  printf ("ordered\n");
+}
+
+static void c_parser_pragma_omp_clause_private (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_private (c_parser *parser)
+{
+  printf ("private\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_reduction (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_reduction (c_parser *parser)
+{
+  printf ("reduction\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      switch (c_parser_peek_token (parser)->type)
+       {
+       case CPP_PLUS:
+         printf ("\treduction-operator: '+'\n");
+         break;
+       case CPP_MULT:
+         printf ("\treduction-operator: '*'\n");
+         break;
+       case CPP_MINUS:
+         printf ("\treduction-operator: '-'\n");
+         break;
+       case CPP_AND:
+         printf ("\treduction-operator: '&'\n");
+         break;
+       case CPP_XOR:
+         printf ("\treduction-operator: '^'\n");
+         break;
+       case CPP_OR:
+         printf ("\treduction-operator: '|'\n");
+         break;
+       case CPP_AND_AND:
+         printf ("\treduction-operator: '&&'\n");
+         break;
+       case CPP_OR_OR:
+         printf ("\treduction-operator: '||'\n");
+         break;
+       default:
+         c_parser_error (parser, "reduction-operator expected");
+         goto error;
+       }
+      c_parser_consume_token (parser);
+      if (c_parser_require (parser, CPP_COLON, "':' expected"))
+       {
+         c_parser_pragma_omp_variable_list (parser);
+         c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+       }
+    }
+ error:
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_schedule (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_schedule (c_parser *parser)
+{
+  printf ("schedule: ");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      if (c_parser_next_token_is (parser, CPP_NAME))
+       {
+         const char *p = IDENTIFIER_POINTER (c_parser_peek_token 
(parser)->value);
+         if (!strcmp ("dynamic", p))
+           {
+             printf ("dynamic");
+           }
+         else if (!strcmp ("guided", p))
+           {
+             printf ("guided");
+           }
+         else if (!strcmp ("runtime", p))
+           {
+             printf ("runtime");
+             c_parser_consume_token (parser);
+             goto skip_chunk;
+           }
+         else if (!strcmp ("static", p))
+           {
+             printf ("static");
+           }
+         else
+           {
+             goto error;
+           }
+         c_parser_consume_token (parser);
+         if (c_parser_next_token_is (parser, CPP_COMMA))
+           {
+             c_parser_consume_token (parser);
+             if (c_parser_next_token_is_not (parser, CPP_NAME))
+               {
+                 c_parser_error (parser, "ONLY CPP_NAME accepted now");
+                 c_parser_skip_until_found (parser, CPP_EOF, 0);
+                 return;
+               }
+             printf (", %s\n", IDENTIFIER_POINTER (c_parser_peek_token 
(parser)->value));
+             c_parser_consume_token (parser);
+           }
+       skip_chunk:
+         c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+       }
+      else
+       {
+       error:
+         c_parser_error (parser, "unknown schedule kind");
+       }
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static void c_parser_pragma_omp_clause_shared (c_parser *);
+
+static void
+c_parser_pragma_omp_clause_shared (c_parser *parser)
+{
+  printf ("copyin\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, 0);
+}
+
+static inline void c_parser_pragma_omp_atomic (c_parser *);
+
+static inline void
+c_parser_pragma_omp_atomic (c_parser *parser)
+{
+  printf ("#pragma omp atomic\n");
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_barrier (c_parser *);
+
+static inline void
+c_parser_pragma_omp_barrier (c_parser *parser)
+{
+  printf ("#pragma omp barrier\n");
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_critical (c_parser *);
+
+static inline void
+c_parser_pragma_omp_critical (c_parser *parser)
+{
+  printf ("#pragma omp critical\n");
+
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      if (c_parser_next_token_is_not (parser, CPP_NAME))
+       {
+         c_parser_error (parser, "identifier expected");
+         c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+         return;
+       }
+      printf ("region-phrase: %s\n",
+             IDENTIFIER_POINTER (c_parser_peek_token (parser)->value));
+      c_parser_consume_token (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_flush (c_parser *);
+
+static inline void
+c_parser_pragma_omp_flush (c_parser *parser)
+{
+  printf ("#pragma omp flush\n");
+
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_for (c_parser *);
+
+static inline void
+c_parser_pragma_omp_for (c_parser *parser)
+{
+  printf ("#pragma omp for\n");
+  while (c_parser_next_token_is_not (parser, CPP_EOF))
+    {
+      const pragma_omp_clause c = c_parser_pragma_omp_clause (parser);
+
+      switch (c)
+       {
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         c_parser_pragma_omp_clause_firstprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
+         c_parser_pragma_omp_clause_lastprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_NOWAIT:
+         c_parser_pragma_omp_clause_nowait (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_ORDERED:
+         c_parser_pragma_omp_clause_ordered (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         c_parser_pragma_omp_clause_private (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_REDUCTION:
+         c_parser_pragma_omp_clause_reduction (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_SCHEDULE:
+         c_parser_pragma_omp_clause_schedule (parser);
+         break;
+       default:
+         c_parser_skip_until_found (parser, CPP_EOF, "unknown clause");
+         return;
+       }
+    }
+  c_parser_consume_token (parser);
+}
+
+static inline void c_parser_pragma_omp_master (c_parser *);
+
+static inline void
+c_parser_pragma_omp_master (c_parser *parser)
+{
+  printf ("#pragma omp master\n");
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_ordered (c_parser *);
+
+static inline void
+c_parser_pragma_omp_ordered (c_parser *parser)
+{
+  printf ("#pragma omp ordered\n");
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_parallel (c_parser *);
+
+static inline void
+c_parser_pragma_omp_parallel (c_parser *parser)
+{
+  printf ("#pragma omp parallel\n");
+  while (c_parser_next_token_is_not (parser, CPP_EOF))
+    {
+      const pragma_omp_clause c = c_parser_pragma_omp_clause (parser);
+
+      switch (c)
+       {
+       case PRAGMA_OMP_CLAUSE_COPYIN:
+         c_parser_pragma_omp_clause_copyin (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_DEFAULT:
+         c_parser_pragma_omp_clause_default (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         c_parser_pragma_omp_clause_firstprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_IF:
+         c_parser_pragma_omp_clause_if (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         c_parser_pragma_omp_clause_private (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_REDUCTION:
+         c_parser_pragma_omp_clause_reduction (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_SHARED:
+         c_parser_pragma_omp_clause_shared (parser);
+         break;
+       default:
+         c_parser_skip_until_found (parser, CPP_EOF, "unknown clause");
+         return;
+       }
+    }
+  c_parser_consume_token (parser);
+}
+
+static inline void c_parser_pragma_omp_parallel_for (c_parser *);
+
+static inline void
+c_parser_pragma_omp_parallel_for (c_parser *parser)
+{
+  printf ("#pragma omp parallel for\n");
+  while (c_parser_next_token_is_not (parser, CPP_EOF))
+    {
+      const pragma_omp_clause c = c_parser_pragma_omp_clause (parser);
+
+      switch (c)
+       {
+       case PRAGMA_OMP_CLAUSE_COPYIN:
+         c_parser_pragma_omp_clause_copyin (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_DEFAULT:
+         c_parser_pragma_omp_clause_default (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         c_parser_pragma_omp_clause_firstprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_IF:
+         c_parser_pragma_omp_clause_if (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
+         c_parser_pragma_omp_clause_lastprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_ORDERED:
+         c_parser_pragma_omp_clause_ordered (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         c_parser_pragma_omp_clause_private (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_REDUCTION:
+         c_parser_pragma_omp_clause_reduction (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_SCHEDULE:
+         c_parser_pragma_omp_clause_schedule (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_SHARED:
+         c_parser_pragma_omp_clause_shared (parser);
+         break;
+       default:
+         c_parser_skip_until_found (parser, CPP_EOF, "unknown clause");
+         return;
+       }
+    }
+  c_parser_consume_token (parser);
+}
+
+static inline void c_parser_pragma_omp_parallel_sections (c_parser *);
+
+static inline void
+c_parser_pragma_omp_parallel_sections (c_parser *parser)
+{
+  printf ("#pragma omp parallel sections\n");
+  while (c_parser_next_token_is_not (parser, CPP_EOF))
+    {
+      const pragma_omp_clause c = c_parser_pragma_omp_clause (parser);
+
+      switch (c)
+       {
+       case PRAGMA_OMP_CLAUSE_COPYIN:
+         c_parser_pragma_omp_clause_copyin (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_DEFAULT:
+         c_parser_pragma_omp_clause_default (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         c_parser_pragma_omp_clause_firstprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_IF:
+         c_parser_pragma_omp_clause_if (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
+         c_parser_pragma_omp_clause_lastprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         c_parser_pragma_omp_clause_private (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_REDUCTION:
+         c_parser_pragma_omp_clause_reduction (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_SHARED:
+         c_parser_pragma_omp_clause_shared (parser);
+         break;
+       default:
+         c_parser_skip_until_found (parser, CPP_EOF, "unknown clause");
+         return;
+       }
+    }
+  c_parser_consume_token (parser);
+}
+
+static inline void c_parser_pragma_omp_section (c_parser *);
+
+static inline void
+c_parser_pragma_omp_section (c_parser *parser)
+{
+  printf ("#pragma omp section\n");
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+static inline void c_parser_pragma_omp_sections (c_parser *);
+
+static inline void
+c_parser_pragma_omp_sections (c_parser *parser)
+{
+  printf ("#pragma omp sections\n");
+  while (c_parser_next_token_is_not (parser, CPP_EOF))
+    {
+      const pragma_omp_clause c = c_parser_pragma_omp_clause (parser);
+
+      switch (c)
+       {
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         c_parser_pragma_omp_clause_firstprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
+         c_parser_pragma_omp_clause_lastprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_NOWAIT:
+         c_parser_pragma_omp_clause_nowait (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         c_parser_pragma_omp_clause_private (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_REDUCTION:
+         c_parser_pragma_omp_clause_reduction (parser);
+         break;
+       default:
+         c_parser_skip_until_found (parser, CPP_EOF, "unknown clause");
+         return;
+       }
+    }
+  c_parser_consume_token (parser);
+}
+
+static inline void c_parser_pragma_omp_single (c_parser *);
+
+static inline void
+c_parser_pragma_omp_single (c_parser *parser)
+{
+  printf ("#pragma omp single\n");
+  while (c_parser_next_token_is_not (parser, CPP_EOF))
+    {
+      const pragma_omp_clause c = c_parser_pragma_omp_clause (parser);
+
+      switch (c)
+       {
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         c_parser_pragma_omp_clause_firstprivate (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_NOWAIT:
+         c_parser_pragma_omp_clause_nowait (parser);
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         c_parser_pragma_omp_clause_private (parser);
+         break;
+       default:
+         c_parser_skip_until_found (parser, CPP_EOF, "unknown clause");
+         return;
+       }
+    }
+  c_parser_consume_token (parser);
+}
+
+static inline void c_parser_pragma_omp_threadprivate (c_parser *);
+
+static inline void
+c_parser_pragma_omp_threadprivate (c_parser *parser)
+{
+  printf ("#pragma omp threadprivate\n");
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "'(' expected"))
+    {
+      c_parser_pragma_omp_variable_list (parser);
+      c_parser_require (parser, CPP_CLOSE_PAREN, "')' expected");
+    }
+  c_parser_skip_until_found (parser, CPP_EOF, "EOF expected");
+}
+
+/* Consume and handle a pragma token.
+   Taken from gcc/cp/parser.c: cp_lexer_handle_pragma (). */
+
+static void
+c_parser_pragma (c_parser *parser)
+{
+  cpp_string s;
+  c_token *token = c_parser_peek_token (parser);
+  c_parser_consume_token (parser);
+  gcc_assert (token->type == CPP_PRAGMA);
+  gcc_assert (token->value);
+
+  s.len = TREE_STRING_LENGTH (token->value);
+  s.text = TREE_STRING_POINTER (token->value);
+
+  cpp_handle_deferred_pragma (parse_in, &s);
+
+  /* Clearing token->value here means that we will get an ICE if we
+     try to process this #pragma again (which should be impossible).  */
+  token->value = NULL; // ???
+}
+
 
 /* The actual parser and external interface.  ??? Does this need to be
    garbage-collected?  */
 
 static GTY (()) c_parser *the_parser;
 
+/* Handle pragma omp. */
+
+static void c_parser_handle_pragma_omp (cpp_reader *);
+
+static void
+c_parser_handle_pragma_omp (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+  gcc_assert (c_parser_next_token_is (the_parser, CPP_NAME)
+             || c_parser_next_token_is_keyword (the_parser, RID_FOR));
+
+  if (c_parser_next_token_is (the_parser, CPP_NAME))
+    {
+      const c_token *token = c_parser_peek_token (the_parser);
+      const char *p = IDENTIFIER_POINTER (token->value);
+      switch (*p)
+       {
+       case 'a':
+         c_parser_consume_token (the_parser);
+         c_parser_pragma_omp_atomic (the_parser);
+         break;
+       case 'b':
+         c_parser_consume_token (the_parser);
+         c_parser_pragma_omp_barrier (the_parser);
+         break;
+       case 'c':
+         c_parser_consume_token (the_parser);
+         c_parser_pragma_omp_critical (the_parser);
+         break;
+       case 'f':
+         c_parser_consume_token (the_parser);
+         c_parser_pragma_omp_flush (the_parser);
+         break;
+       case 'm':
+         c_parser_consume_token (the_parser);
+         c_parser_pragma_omp_master (the_parser);
+         break;
+       case 'p':
+         c_parser_consume_token (the_parser);
+         if (c_parser_next_token_is_keyword (the_parser, RID_FOR))
+           {
+             c_parser_consume_token (the_parser);
+             c_parser_pragma_omp_parallel_for (the_parser);
+           }
+         else if (c_parser_next_token_is (the_parser, CPP_NAME)
+                  && !strcmp ("sections", TREE_STRING_POINTER
+                              (c_parser_peek_token (the_parser)->value)))
+           {
+             c_parser_consume_token (the_parser);
+             c_parser_pragma_omp_parallel_sections (the_parser);
+           }
+         else
+           {
+             c_parser_consume_token (the_parser);
+             c_parser_pragma_omp_parallel (the_parser);
+           }
+         break;
+       case 's':
+         if (*(p + 1) == 'e')
+           {
+             if (TREE_STRING_LENGTH (token->value) == 7)
+               {
+                 c_parser_consume_token (the_parser);
+                 c_parser_pragma_omp_section (the_parser);
+               }
+             else
+               {
+                 c_parser_consume_token (the_parser);
+                 c_parser_pragma_omp_sections (the_parser);
+               }
+           }
+         else
+           {
+             c_parser_consume_token (the_parser);
+             c_parser_pragma_omp_single (the_parser);
+           }
+         break;
+       case 't':
+         c_parser_consume_token (the_parser);
+         c_parser_pragma_omp_threadprivate (the_parser);
+         break;
+       }
+    }
+  else
+    {
+      c_parser_consume_token (the_parser);
+      c_parser_pragma_omp_for (the_parser);
+    }
+}
+
 /* Parse a single source file.  */
 
 void
 c_parse_file (void)
 {
+  if (flag_openmp)
+    {
+      /* we want to handle deferred pragmas */
+      cpp_get_options (parse_in)->defer_pragmas = true;
+      /* register OpenMP pragmas handler */
+      c_register_pragma (0, "omp", c_parser_handle_pragma_omp);
+    }
+
   the_parser = c_parser_new ();
   c_parser_translation_unit (the_parser);
   the_parser = NULL;


--- orig/gcc/c.opt
+++ mod/gcc/c.opt
@@ -600,6 +600,10 @@
 ObjC ObjC++
 Enable Objective-C setjmp exception handling runtime
 
+fopenmp
+C Var(flag_openmp)
+Enable OpenMP
+
 foperator-names
 C++ ObjC++
 Recognize C++ kewords like \"compl\" and \"xor\"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]