Hi Jakub,
        I have fixed all the issues you have mentioned below. I am also 
attaching a fixed patch along with ChangeLog entries.  I have also rebased the 
patch to the trunk revision r206786.

        Is this Ok to install?

Thanks,

Balaji V. Iyer.

> -----Original Message-----
> From: Jakub Jelinek [mailto:ja...@redhat.com]
> Sent: Friday, January 17, 2014 12:46 PM
> To: Iyer, Balaji V
> Cc: 'Aldy Hernandez (al...@redhat.com)'; 'gcc-patches@gcc.gnu.org'
> Subject: Re: [GOMP4][PATCH] SIMD-enabled functions (formerly Elemental
> functions) for C++
> 
> On Thu, Dec 19, 2013 at 06:12:29PM +0000, Iyer, Balaji V wrote:
> > 2013-12-19  Balaji V. Iyer  <balaji.v.i...@intel.com>
> >
> >         * parser.c (cp_parser_direct_declarator): When Cilk Plus is enabled
> >         see if there is an attribute after function decl.  If so, then
> >         parse them now.
> >         (cp_parser_late_return_type_opt): Handle parsing of Cilk Plus SIMD
> >         enabled function late parsing.
> >         (cp_parser_gnu_attribute_list): Parse all the tokens for the vector
> >         attribute for a SIMD-enabled function.
> >         (cp_parser_omp_all_clauses): Skip parsing to the end of pragma when
> >         the function is used by SIMD-enabled function (indicated by NULL
> >         pragma token).   Added 3 new clauses: PRAGMA_CILK_CLAUSE_MASK,
> >         PRAGMA_CILK_CLAUSE_NOMASK and
> PRAGMA_CILK_CLAUSE_VECTORLENGTH
> >         (cp_parser_cilk_simd_vectorlength): Modified this function to handle
> >         vectorlength clause in SIMD-enabled function and #pragma SIMD's
> >         vectorlength clause.  Added a new bool parameter to differentiate
> >         between the two.
> >         (cp_parser_cilk_simd_fn_vector_attrs): New function.
> >         (is_cilkplus_vector_p): Likewise.
> >         (cp_parser_late_parsing_elem_fn_info): Likewise.
> >         (cp_parser_omp_clause_name): Added a check for "mask," "nomask"
> 
> The comma should have been after " .
> 

Fixed.

> > +             /* In here, we handle cases where attribute is used after
> > +                the function declaration.  For example:
> > +                void func (int x) __attribute__((vector(..)));  */
> > +             if (flag_enable_cilkplus
> > +                 && cp_next_tokens_can_be_attribute_p (parser))
> 
> As you are just calling cp_parser_gnu_attributes_opt here and not ..._std_...,
> I'd say the above should be cp_next_tokens_can_be_gnu_attribute_p
> rather than cp_next_tokens_can_be_attribute_p.  I think [[...]] attributes at
> this position are ignored, so no need to handle them, not sure about
> whether we allow e.g. combination of GNU and std attributes or vice versa.
> 

Fixed.

> > +               {
> > +                 cp_parser_parse_tentatively (parser);
> > +                 tree attr = cp_parser_gnu_attributes_opt (parser);
> > +                 if (cp_lexer_next_token_is_not (parser->lexer,
> > +                                                 CPP_SEMICOLON)
> > +                     && cp_lexer_next_token_is_not (parser->lexer,
> > +                                                    CPP_OPEN_BRACE))
> > +                   cp_parser_abort_tentative_parse (parser);
> > +                 else if (!cp_parser_parse_definitely (parser))
> > +                   ;
> > +                 else
> > +                   attrs = chainon (attr, attrs);
> > +               }
> >               late_return = (cp_parser_late_return_type_opt
> >                              (parser, declarator,
> >                               memfn ? cv_quals : -1));
> 
> > @@ -17842,6 +17868,10 @@ cp_parser_late_return_type_opt (cp_parser*
> parser, cp_declarator *declarator,
> >        type = cp_parser_trailing_type_id (parser);
> >      }
> >
> > +  if (cilk_simd_fn_vector_p)
> > +    declarator->std_attributes
> > +      = cp_parser_late_parsing_cilk_simd_fn_info (parser,
> > +                                        declarator->std_attributes);
> 
> Please make sure declarator is aligned below parser.
> 

Fixed.

> > +  token->type = CPP_PRAGMA_EOL;
> > +  parser->lexer->next_token = token;
> > +  cp_lexer_consume_token (parser->lexer);
> > +
> > +  struct cp_token_cache *cp =
> > +    cp_token_cache_new (v_token, cp_lexer_peek_token
> > + (parser->lexer));
> 
> The = should already go on the next line.
> 

Fixed.

> > +/* Handles the delayed parsing of the Cilk Plus SIMD-enabled function.
> > +   This function is modelled similar to the late parsing of omp declare
> > +   simd.  */
> > +
> > +static tree
> > +cp_parser_late_parsing_cilk_simd_fn_info (cp_parser *parser, tree
> > +attrs) {
> > +  struct cp_token_cache *ce;
> > +  cp_omp_declare_simd_data *info = parser->cilk_simd_fn_info;
> > +  int ii = 0;
> > +
> > +  if (parser->omp_declare_simd != NULL)
> > +    {
> > +      error ("%<#pragma omp declare simd%> cannot be used in the same
> function"
> > +        " marked as a Cilk Plus SIMD-enabled function");
> > +      parser->cilk_simd_fn_info = NULL;
> 
> This will leak parser->cilk_simd_fn_info memory.  Please XDELETE it first.
> 

Fixed

> > +      return attrs;
> > +    }
> > +  if (!info->error_seen && info->fndecl_seen)
> > +    {
> > +      error ("vector attribute not immediately followed by a single 
> > function"
> > +        " declaration or definition");
> > +      info->error_seen = true;
> > +    }
> > +  if (info->error_seen)
> > +    return attrs;
> > +
> > +  /* Vector attributes are converted to #pragma omp declare simd values
> and
> > +     so we need them enabled.  */
> > +  flag_openmp = 1;
> 
> The C FE doesn't do this.  I thought all the omp-low.c spots are now guarded
> by flag_openmp || flag_enable_cilkplus etc. conditions.

Fixed. The above "orring" was omitted in decl.c and pt.c . I have put them in.

> 
> > +      c = build_tree_list (get_identifier ("cilk simd function"),
> > + cl);
> 
> Please use NULL_TREE instead of cl here and please fix up the C FE as well,
> the "cilk simd function" attribute should be just an attribute without value,
> serving only as a boolean, if present, decl with "omp declare simd" attribute
> is Cilk+, otherwise OpenMP.
> 
> > +      TREE_CHAIN (c) = attrs;
> > +      if (processing_template_decl)
> > +   ATTR_IS_DEPENDENT (c) = 1;
> 

Fixed.

> But, as a boolean attribute it doesn't and shouldn't be ATTR_IS_DEPENDENT,
> there is nothing to adjust in it.
> > --- a/gcc/cp/pt.c
> > +++ b/gcc/cp/pt.c
> > @@ -8602,9 +8602,12 @@ apply_late_template_attributes (tree *decl_p,
> tree attributes, int attr_flags,
> >         {
> >           *p = TREE_CHAIN (t);
> >           TREE_CHAIN (t) = NULL_TREE;
> > -         if (flag_openmp
> > -             && is_attribute_p ("omp declare simd",
> > -                                get_attribute_name (t))
> > +         if (((flag_openmp
> > +               && is_attribute_p ("omp declare simd",
> > +                                  get_attribute_name (t)))
> > +              || (flag_enable_cilkplus
> > +                  && is_attribute_p ("cilk simd function",
> > +                                     get_attribute_name (t))))
> >               && TREE_VALUE (t))
> >             {
> >               tree clauses = TREE_VALUE (TREE_VALUE (t));
> 
> And this change is unnecessary after the above suggested change.
> 

Fixed.

>       Jakub
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 4490210..bbf5287 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -12924,7 +12924,8 @@ c_finish_omp_declare_simd (c_parser *parser, tree 
fndecl, tree parms,
        c = tree_cons (NULL_TREE, c, NULL_TREE);
       if (is_cilkplus_cilk_simd_fn) 
        { 
-         tree k = build_tree_list (get_identifier ("cilk simd function"), c);
+         tree k = build_tree_list (get_identifier ("cilk simd function"), 
+                                   NULL_TREE);
          TREE_CHAIN (k) = DECL_ATTRIBUTES (fndecl);
          DECL_ATTRIBUTES (fndecl) = k;
        } 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5906653..9918416 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7674,7 +7674,7 @@ grokfndecl (tree ctype,
   if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
     TREE_NOTHROW (decl) = 1;
 
-  if (flag_openmp)
+  if (flag_openmp || flag_enable_cilkplus)
     {
       /* Adjust "omp declare simd" attributes.  */
       tree ods = lookup_attribute ("omp declare simd", *attrlist);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c3016bc..971fe8f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -241,6 +241,8 @@ static void cp_parser_cilk_simd
   (cp_parser *, cp_token *);
 static bool cp_parser_omp_declare_reduction_exprs
   (tree, cp_parser *);
+static tree cp_parser_cilk_simd_vectorlength 
+  (cp_parser *, tree, bool);
 
 /* Manifest constants.  */
 #define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
@@ -2115,6 +2117,9 @@ static bool 
cp_parser_ctor_initializer_opt_and_function_body
 static tree cp_parser_late_parsing_omp_declare_simd
   (cp_parser *, tree);
 
+static tree cp_parser_late_parsing_cilk_simd_fn_info
+  (cp_parser *, tree);
+
 static tree synthesize_implicit_template_parm
   (cp_parser *);
 static tree finish_fully_implicit_template
@@ -17121,6 +17126,24 @@ cp_parser_direct_declarator (cp_parser* parser,
 
                  attrs = cp_parser_std_attribute_spec_seq (parser);
 
+                 /* In here, we handle cases where attribute is used after
+                    the function declaration.  For example:
+                    void func (int x) __attribute__((vector(..)));  */
+                 if (flag_enable_cilkplus
+                     && cp_next_tokens_can_be_gnu_attribute_p (parser))
+                   {
+                     cp_parser_parse_tentatively (parser);
+                     tree attr = cp_parser_gnu_attributes_opt (parser);
+                     if (cp_lexer_next_token_is_not (parser->lexer,
+                                                     CPP_SEMICOLON)
+                         && cp_lexer_next_token_is_not (parser->lexer,
+                                                        CPP_OPEN_BRACE))
+                       cp_parser_abort_tentative_parse (parser);
+                     else if (!cp_parser_parse_definitely (parser))
+                       ;
+                     else
+                       attrs = chainon (attr, attrs);
+                   }
                  late_return = (cp_parser_late_return_type_opt
                                 (parser, declarator,
                                  memfn ? cv_quals : -1));
@@ -17829,7 +17852,7 @@ parsing_nsdmi (void)
    Returns the type indicated by the type-id.
 
    In addition to this this parses any queued up omp declare simd
-   clauses.
+   clauses and Cilk Plus SIMD-enabled function's vector attributes.
 
    QUALS is either a bitmask of cv_qualifiers or -1 for a non-member
    function.  */
@@ -17844,10 +17867,13 @@ cp_parser_late_return_type_opt (cp_parser* parser, 
cp_declarator *declarator,
                         && declarator
                         && declarator->kind == cdk_id);
 
+  bool cilk_simd_fn_vector_p = (parser->cilk_simd_fn_info 
+                               && declarator && declarator->kind == cdk_id);
+  
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
   /* A late-specified return type is indicated by an initial '->'. */
-  if (token->type != CPP_DEREF && !declare_simd_p)
+  if (token->type != CPP_DEREF && !(declare_simd_p || cilk_simd_fn_vector_p))
     return NULL_TREE;
 
   tree save_ccp = current_class_ptr;
@@ -17866,6 +17892,10 @@ cp_parser_late_return_type_opt (cp_parser* parser, 
cp_declarator *declarator,
       type = cp_parser_trailing_type_id (parser);
     }
 
+  if (cilk_simd_fn_vector_p)
+    declarator->std_attributes
+      = cp_parser_late_parsing_cilk_simd_fn_info (parser,
+                                                 declarator->std_attributes);
   if (declare_simd_p)
     declarator->std_attributes
       = cp_parser_late_parsing_omp_declare_simd (parser,
@@ -21399,6 +21429,56 @@ cp_parser_attributes_opt (cp_parser *parser)
   return cp_parser_std_attribute_spec_seq (parser);
 }
 
+#define CILK_SIMD_FN_CLAUSE_MASK                                 \
+       ((OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_VECTORLENGTH)   \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_LINEAR)       \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_UNIFORM)      \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_MASK)         \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_NOMASK))
+
+/* Parses the Cilk Plus SIMD-enabled function's attribute.  Syntax:
+   vector [(<clauses>)]  */
+
+static void
+cp_parser_cilk_simd_fn_vector_attrs (cp_parser *parser, cp_token *v_token)
+{  
+  bool first_p = parser->cilk_simd_fn_info == NULL;
+  cp_token *token = v_token;
+  if (first_p)
+    {
+      parser->cilk_simd_fn_info = XNEW (cp_omp_declare_simd_data);
+      parser->cilk_simd_fn_info->error_seen = false;
+      parser->cilk_simd_fn_info->fndecl_seen = false;
+      parser->cilk_simd_fn_info->tokens = vNULL;
+    }
+  int paren_scope = 0;
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+    {
+      cp_lexer_consume_token (parser->lexer);
+      v_token = cp_lexer_peek_token (parser->lexer);
+      paren_scope++;
+    }
+  while (paren_scope > 0)
+    {
+      token = cp_lexer_peek_token (parser->lexer);
+      if (token->type == CPP_OPEN_PAREN)
+       paren_scope++;
+      else if (token->type == CPP_CLOSE_PAREN)
+       paren_scope--;
+      /* Do not push the last ')'  */
+      if (!(token->type == CPP_CLOSE_PAREN && paren_scope == 0))
+       cp_lexer_consume_token (parser->lexer);
+    }
+
+  token->type = CPP_PRAGMA_EOL;
+  parser->lexer->next_token = token;
+  cp_lexer_consume_token (parser->lexer);
+
+  struct cp_token_cache *cp
+    = cp_token_cache_new (v_token, cp_lexer_peek_token (parser->lexer));
+  parser->cilk_simd_fn_info->tokens.safe_push (cp);
+}
+
 /* Parse an (optional) series of attributes.
 
    attributes:
@@ -21457,6 +21537,17 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
   return attributes;
 }
 
+/* Returns true of NAME is an IDENTIFIER_NODE with identiifer "vector,"
+   "__vector" or "__vector__."  */
+
+static inline bool
+is_cilkplus_vector_p (tree name)
+{ 
+  if (flag_enable_cilkplus && is_attribute_p ("vector", name)) 
+    return true;
+  return false;
+}
+
 /* Parse a GNU attribute-list.
 
    attribute-list:
@@ -21495,8 +21586,9 @@ cp_parser_gnu_attribute_list (cp_parser* parser)
        {
          tree arguments = NULL_TREE;
 
-         /* Consume the token.  */
-         token = cp_lexer_consume_token (parser->lexer);
+         /* Consume the token, but save it since we need it for the
+            SIMD enabled function parsing.  */
+         cp_token *id_token = cp_lexer_consume_token (parser->lexer);
 
          /* Save away the identifier that indicates which attribute
             this is.  */
@@ -21504,7 +21596,7 @@ cp_parser_gnu_attribute_list (cp_parser* parser)
            /* For keywords, use the canonical spelling, not the
               parsed identifier.  */
            ? ridpointers[(int) token->keyword]
-           : token->u.value;
+           : id_token->u.value;
          
          attribute = build_tree_list (identifier, NULL_TREE);
 
@@ -21516,10 +21608,16 @@ cp_parser_gnu_attribute_list (cp_parser* parser)
              vec<tree, va_gc> *vec;
              int attr_flag = (attribute_takes_identifier_p (identifier)
                               ? id_attr : normal_attr);
-             vec = cp_parser_parenthesized_expression_list
-                   (parser, attr_flag, /*cast_p=*/false,
-                    /*allow_expansion_p=*/false,
-                    /*non_constant_p=*/NULL);
+             if (is_cilkplus_vector_p (identifier))
+               {
+                 cp_parser_cilk_simd_fn_vector_attrs (parser, id_token);
+                 continue;
+               }
+             else
+               vec = cp_parser_parenthesized_expression_list 
+                 (parser, attr_flag, /*cast_p=*/false, 
+                  /*allow_expansion_p=*/false, 
+                  /*non_constant_p=*/NULL);
              if (vec == NULL)
                arguments = error_mark_node;
              else
@@ -21530,6 +21628,11 @@ cp_parser_gnu_attribute_list (cp_parser* parser)
              /* Save the arguments away.  */
              TREE_VALUE (attribute) = arguments;
            }
+         else if (is_cilkplus_vector_p (identifier))
+           {
+             cp_parser_cilk_simd_fn_vector_attrs (parser, id_token);
+             continue;
+           }
 
          if (arguments != error_mark_node)
            {
@@ -26809,12 +26912,16 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_MAP;
          else if (!strcmp ("mergeable", p))
            result = PRAGMA_OMP_CLAUSE_MERGEABLE;
+         else if (flag_enable_cilkplus && !strcmp ("mask", p))
+           result = PRAGMA_CILK_CLAUSE_MASK;
          break;
        case 'n':
          if (!strcmp ("notinbranch", p))
            result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
          else if (!strcmp ("nowait", p))
            result = PRAGMA_OMP_CLAUSE_NOWAIT;
+         else if (flag_enable_cilkplus && !strcmp ("nomask", p))
+           result = PRAGMA_CILK_CLAUSE_NOMASK;
          else if (!strcmp ("num_teams", p))
            result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
          else if (!strcmp ("num_threads", p))
@@ -26860,6 +26967,10 @@ cp_parser_omp_clause_name (cp_parser *parser)
          else if (!strcmp ("untied", p))
            result = PRAGMA_OMP_CLAUSE_UNTIED;
          break;
+       case 'v':
+         if (flag_enable_cilkplus && !strcmp ("vectorlength", p))
+           result = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
+         break;
        }
     }
 
@@ -27612,7 +27723,8 @@ cp_parser_omp_clause_aligned (cp_parser *parser, tree 
list)
    linear ( variable-list : expression )  */
 
 static tree
-cp_parser_omp_clause_linear (cp_parser *parser, tree list)
+cp_parser_omp_clause_linear (cp_parser *parser, tree list, 
+                            bool is_cilk_simd_fn)
 {
   tree nlist, c, step = integer_one_node;
   bool colon;
@@ -27627,6 +27739,11 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree 
list)
     {
       step = cp_parser_expression (parser, false, NULL);
 
+      if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL)
+       {
+         sorry ("using parameters for %<linear%> step is not supported yet");
+         step = integer_one_node;
+       }
       if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
        cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                               /*or_comma=*/false,
@@ -27948,6 +28065,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
   tree clauses = NULL;
   bool first = true;
   cp_token *token = NULL;
+  bool cilk_simd_fn = false;
 
   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
     {
@@ -28044,11 +28162,13 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
          c_name = "untied";
          break;
        case PRAGMA_OMP_CLAUSE_INBRANCH:
+       case PRAGMA_CILK_CLAUSE_MASK:
          clauses = cp_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
                                                 clauses, token->location);
          c_name = "inbranch";
          break;
        case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
+       case PRAGMA_CILK_CLAUSE_NOMASK:
          clauses = cp_parser_omp_clause_branch (parser,
                                                 OMP_CLAUSE_NOTINBRANCH,
                                                 clauses, token->location);
@@ -28117,7 +28237,9 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
          c_name = "aligned";
          break;
        case PRAGMA_OMP_CLAUSE_LINEAR:
-         clauses = cp_parser_omp_clause_linear (parser, clauses);
+         if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0)
+           cilk_simd_fn = true;
+         clauses = cp_parser_omp_clause_linear (parser, clauses, cilk_simd_fn);
          c_name = "linear";
          break;
        case PRAGMA_OMP_CLAUSE_DEPEND:
@@ -28153,6 +28275,10 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
                                                  token->location);
          c_name = "simdlen";
          break;
+       case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
+         clauses = cp_parser_cilk_simd_vectorlength (parser, clauses, true);
+         c_name = "simdlen";
+         break;
        default:
          cp_parser_error (parser, "expected %<#pragma omp%> clause");
          goto saw_error;
@@ -28169,7 +28295,10 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
        }
     }
  saw_error:
-  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+  /* In Cilk Plus SIMD enabled functions there is no pragma_token, so
+     no reason to skip to the end.  */
+  if (!(flag_enable_cilkplus && pragma_tok == NULL))
+    cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   if (finish_p)
     return finish_omp_clauses (clauses);
   return clauses;
@@ -30171,6 +30300,63 @@ cp_parser_omp_declare_simd (cp_parser *parser, 
cp_token *pragma_tok,
     }
 }
 
+/* Handles the delayed parsing of the Cilk Plus SIMD-enabled function.  
+   This function is modelled similar to the late parsing of omp declare 
+   simd.  */
+
+static tree
+cp_parser_late_parsing_cilk_simd_fn_info (cp_parser *parser, tree attrs)
+{
+  struct cp_token_cache *ce;
+  cp_omp_declare_simd_data *info = parser->cilk_simd_fn_info;
+  int ii = 0;
+
+  if (parser->omp_declare_simd != NULL)
+    {
+      error ("%<#pragma omp declare simd%> cannot be used in the same function"
+            " marked as a Cilk Plus SIMD-enabled function");
+      XDELETE (parser->cilk_simd_fn_info);
+      parser->cilk_simd_fn_info = NULL;
+      return attrs;
+    }
+  if (!info->error_seen && info->fndecl_seen)
+    {
+      error ("vector attribute not immediately followed by a single function"
+            " declaration or definition");
+      info->error_seen = true;
+    }
+  if (info->error_seen)
+    return attrs;
+
+  FOR_EACH_VEC_ELT (info->tokens, ii, ce)
+    {
+      tree c, cl;
+
+      cp_parser_push_lexer_for_tokens (parser, ce);
+      parser->lexer->in_pragma = true;
+      cl = cp_parser_omp_all_clauses (parser, CILK_SIMD_FN_CLAUSE_MASK,
+                                     "SIMD-enabled functions attribute", 
+                                     NULL);
+      cp_parser_pop_lexer (parser);
+      if (cl)
+       cl = tree_cons (NULL_TREE, cl, NULL_TREE);
+
+      c = build_tree_list (get_identifier ("cilk simd function"), NULL_TREE);
+      TREE_CHAIN (c) = attrs;
+      attrs = c;
+
+      c = build_tree_list (get_identifier ("omp declare simd"), cl);
+      TREE_CHAIN (c) = attrs;
+      if (processing_template_decl)
+       ATTR_IS_DEPENDENT (c) = 1;
+      attrs = c;
+    }
+  info->fndecl_seen = true;
+  XDELETE (parser->cilk_simd_fn_info);
+  parser->cilk_simd_fn_info = NULL;
+  return attrs;
+}
+
 /* Finalize #pragma omp declare simd clauses after direct declarator has
    been parsed, and put that into "omp declare simd" attribute.  */
 
@@ -31351,35 +31537,63 @@ c_parse_file (void)
   the_parser = NULL;
 }
 
-/* Parses the Cilk Plus #pragma simd vectorlength clause:
+/* Parses the Cilk Plus #pragma simd and SIMD-enabled function attribute's 
+   vectorlength clause:
    Syntax:
    vectorlength ( constant-expression )  */
 
 static tree
-cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses)
+cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
+                                 bool is_simd_fn)
 {
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   tree expr;
-  /* The vectorlength clause behaves exactly like OpenMP's safelen
-     clause.  Thus, vectorlength is represented as OMP 4.0
-     safelen.  */
-  check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength", loc);
-  
+  /* The vectorlength clause in #pragma simd behaves exactly like OpenMP's
+     safelen clause.  Thus, vectorlength is represented as OMP 4.0
+     safelen.  For SIMD-enabled function it is represented by OMP 4.0
+     simdlen.  */
+  if (!is_simd_fn)
+    check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength", 
+                              loc);
+  else
+    check_no_duplicate_clause (clauses, OMP_CLAUSE_SIMDLEN, "vectorlength",
+                              loc);
+
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return error_mark_node;
   
   expr = cp_parser_constant_expression (parser, false, NULL);
   expr = maybe_constant_value (expr);
-
-  if (TREE_CONSTANT (expr)
+  
+  /* If expr == error_mark_node, then don't emit any errors nor
+     create a clause.  if any of the above functions returns
+     error mark node then they would have emitted an error message.  */
+  if (expr == error_mark_node)
+    ;
+  else if (!TREE_TYPE (expr)
+          || !TREE_CONSTANT (expr)
+          || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
+    error_at (loc, "vectorlength must be an integer constant");
+  else if (TREE_CONSTANT (expr)
           && exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
     error_at (loc, "vectorlength must be a power of 2");
-  else if (expr != error_mark_node)
+  else 
     {
-      tree c = build_omp_clause (loc, OMP_CLAUSE_SAFELEN);
-      OMP_CLAUSE_SAFELEN_EXPR (c) = expr;
-      OMP_CLAUSE_CHAIN (c) = clauses;
-      clauses = c;
+      tree c;
+      if (!is_simd_fn)
+       { 
+         c = build_omp_clause (loc, OMP_CLAUSE_SAFELEN); 
+         OMP_CLAUSE_SAFELEN_EXPR (c) = expr; 
+         OMP_CLAUSE_CHAIN (c) = clauses; 
+         clauses = c;
+       }
+      else
+       {
+         c = build_omp_clause (loc, OMP_CLAUSE_SIMDLEN);
+         OMP_CLAUSE_SIMDLEN_EXPR (c) = expr;
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
     }
 
   if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
@@ -31542,7 +31756,7 @@ cp_parser_cilk_simd_all_clauses (cp_parser *parser, 
cp_token *pragma_token)
       pragma_omp_clause c_kind;
       c_kind = cp_parser_cilk_simd_clause_name (parser);
       if (c_kind == PRAGMA_CILK_CLAUSE_VECTORLENGTH)
-       clauses = cp_parser_cilk_simd_vectorlength (parser, clauses);
+       clauses = cp_parser_cilk_simd_vectorlength (parser, clauses, false);
       else if (c_kind == PRAGMA_CILK_CLAUSE_LINEAR)
        clauses = cp_parser_cilk_simd_linear (parser, clauses);
       else if (c_kind == PRAGMA_CILK_CLAUSE_PRIVATE)
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index 484a8cd..d558c60 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -362,6 +362,13 @@ typedef struct GTY(()) cp_parser {
      data structure with everything needed for parsing the clauses.  */
   cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd;
 
+  /* When parsing the vector attribute in Cilk Plus SIMD-enabled function,
+     this is a pointer to data structure with everything needed for parsing
+     the clauses.  The cp_omp_declare_simd_data struct will hold all the
+     necessary information, so creating another struct for this is not
+     necessary.  */
+  cp_omp_declare_simd_data * GTY((skip)) cilk_simd_fn_info;
+
   /* Nonzero if parsing a parameter list where 'auto' should trigger an 
implicit
      template parameter.  */
   bool auto_is_implicit_function_template_parm_p;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2e7cf60..a91df4c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8613,7 +8613,7 @@ apply_late_template_attributes (tree *decl_p, tree 
attributes, int attr_flags,
            {
              *p = TREE_CHAIN (t);
              TREE_CHAIN (t) = NULL_TREE;
-             if (flag_openmp
+             if ((flag_openmp || flag_enable_cilkplus)
                  && is_attribute_p ("omp declare simd",
                                     get_attribute_name (t))
                  && TREE_VALUE (t))
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c 
b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c
index ab55fae..195e9f1 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c
@@ -1,9 +1,9 @@
 /* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-options "-fcilkplus -Wall" } */
 
-__attribute__((vector (linear (x:y))))
+__attribute__((vector (linear (x:y)))) /* { dg-message "parameter" "" { target 
c++ } } */
 int func2 (int x, int y) 
-{ /* { dg-message "using parameters for" } */
+{ /* { dg-message "using parameters for" "" { target c } } */
   return (x+y);
 }
 
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c 
b/gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c
index 38d610a..1bcf2a2 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c
@@ -5,7 +5,8 @@
 
 int z = Q;
 
-__attribute__ ((vector (uniform(x), vectorlength (), linear (y:1) ))) /* { 
dg-error "expected expression" } */
+__attribute__ ((vector (uniform(x), vectorlength (), linear (y:1) ))) /* { 
dg-error "expected expression" "" { target c } } */ 
+     /* { dg-error "expected primary-expression" "" { target c++ }  8 } */ 
 int func2 (int x, int y)
 {
   int zq = 5;
@@ -19,7 +20,8 @@ int func3 (int x, int y)
   return x + (y*zq);
 }
 
-__attribute__ ((vector (uniform(x), linear (y:1), vectorlength (z) ))) /* { 
dg-error "vectorlength must be an integer" } */
+__attribute__ ((vector (uniform(x), linear (y:1), vectorlength (z) ))) /* { 
dg-error "vectorlength must be an integer" "" { target c } } */ 
+     /* { dg-error "constant" "" { target c++ } 23 } */
 int func4 (int x, int y)
 {
   int zq = 5;
@@ -33,7 +35,8 @@ int func5 (int x, int y)
   return x + (y*zq);
 }
 
-__attribute__ ((vector (uniform(x), vectorlength (z), linear (y:1)))) /* { 
dg-error "vectorlength must be an integer" } */
+__attribute__ ((vector (uniform(x), vectorlength (z), linear (y:1)))) /* { 
dg-error "vectorlength must be an integer" ""  { target c } } */ 
+     /* { dg-error "constant" "" { target c++ }  38 } */
 int func6 (int x, int y)
 {
   int zq = 5;
diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp 
b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
index 37b8ccb..204a754 100644
--- a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
+++ b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
@@ -33,6 +33,9 @@ set TEST_EXTRA_LIBS "-L${library_var}/libcilkrts/.libs"
 dg-init
 # Run the tests that are shared with C.
 g++-dg-runtest [lsort [glob -nocomplain 
$srcdir/c-c++-common/cilk-plus/PS/*.c]] ""
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] 
"-O3" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] " 
" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] 
"-g -O2" " "
 # Run the C++ only tests.
 g++-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] ""
 dg-finish
diff --git a/gcc/testsuite/g++.dg/cilk-plus/ef_test.C 
b/gcc/testsuite/g++.dg/cilk-plus/ef_test.C
new file mode 100644
index 0000000..3e75cbd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/ef_test.C
@@ -0,0 +1,37 @@
+/* { dg-do run }  */
+/* { dg-options "-fcilkplus" } */
+
+
+__attribute__((vector (nomask), vector(mask), vector(mask,linear(x:1))))
+int func (int x)
+{
+  return x+5;
+}
+
+
+__attribute__((vector(mask,uniform (y), linear(x:1))))
+__attribute__((vector (nomask, uniform (x), linear(y:1))))
+int func2 (int x, int y)
+{
+  return x+y;
+}
+
+int func4 (int x, int y) __attribute__((vector, vector (nomask), vector 
(uniform(y), linear(x:1))));
+
+
+template <class T, class R>
+__attribute__((vector, vector(mask,uniform (y), linear(x:1))))
+T func3 (T x, R y)
+{
+  return x+(T)y;
+}
+
+
+
+int main (void)
+{
+  if ((func3 (5, 4) + func2 (5, 4) + func (5) + (int) func3<long, int> (5, 4)) 
!= 
+      (5 + 4) + (5 + 4) + (5 + 5) + (int) ((long)5 +(int)4))
+    __builtin_abort ();
+  return 0;
+}

Attachment: ChangeLog.elem_fn
Description: ChangeLog.elem_fn

Reply via email to