PR c++/85462
[official-gcc.git] / gcc / testsuite / g++.dg / pr57662.C
blob2180914ce4650f6fdcecce4a966c626daf3f6f79
1 /* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
2 /* { dg-options "-O2 -fselective-scheduling2 -fsel-sched-pipelining" } */
3 /* { dg-additional-options "-Wno-return-type" } */
5 extern "C" {
6         typedef struct _IO_FILE FILE;
7         extern int putc(int __c, FILE * __stream);
8         extern int strcmp(__const char *__s1, __const char *__s2) throw()
9             __attribute__ ((__pure__)) __attribute__ ((__nonnull__(1, 2)));
10 } typedef union tree_node *tree;
11 struct gcc_options {
12         int x_flag_openmp;
14 extern struct gcc_options global_options;
15 struct ht_identifier {
16         const unsigned char *str;
18 enum cpp_ttype {
19         CPP_SEMICOLON, CPP_NAME
21 struct vl_embed {
23 struct va_heap {
25 struct va_gc {
26         typedef vl_embed default_layout;
28 template < typename T, typename A = va_heap, typename L =
29     typename A::default_layout > struct vec {
31 enum tree_code {
32         ERROR_MARK,
33         IDENTIFIER_NODE,
34         OMP_SIMD,
35         MAX_TREE_CODES
37 struct tree_identifier {
38         struct ht_identifier
39          id;
41 union tree_node {
42         struct tree_identifier
43          identifier;
45 inline tree
46 tree_check(tree __t, const char *__f, int __l, const char *__g, tree_code __c)
50 extern tree chainon(tree, tree);
51 extern vec < tree, va_gc > *make_tree_vector(void);
52 typedef unsigned long omp_clause_mask;
53 enum c_omp_clause_split {
54         C_OMP_CLAUSE_SPLIT_TARGET = 0, C_OMP_CLAUSE_SPLIT_COUNT
56 typedef struct cxx_saved_binding {
57         tree attributes;
58 } cp_decl_specifier_seq;
59 typedef enum pragma_kind {
60         PRAGMA_NONE = 0, PRAGMA_OMP_DECLARE_REDUCTION, PRAGMA_OMP_TARGET
61 } pragma_kind;
62 typedef enum pragma_omp_clause {
63         PRAGMA_OMP_CLAUSE_NONE =
64             0, PRAGMA_OMP_CLAUSE_DEVICE, PRAGMA_OMP_CLAUSE_IF,
65             PRAGMA_OMP_CLAUSE_MAP
66 } pragma_omp_clause;
67 typedef struct cp_token {
68         enum cpp_ttype type:8;
69         union cp_token_value {
70                 tree value;
71         } u;
72 } cp_token;
73 typedef struct cp_token *cp_token_position;
74 typedef struct cp_lexer {
75         cp_token_position next_token;
76         bool debugging_p;
77         cp_lexer *lexer;
78 } cp_parser;
79 static FILE *cp_lexer_debug_stream;
80 static inline bool cp_lexer_debugging_p(cp_lexer * lexer)
82         return lexer->debugging_p;
85 static inline cp_token *cp_lexer_peek_token(cp_lexer * lexer)
87         if (cp_lexer_debugging_p(lexer)) {
88                 putc('\n', cp_lexer_debug_stream);
89         }
90         return lexer->next_token;
93 static inline bool cp_lexer_next_token_is(cp_lexer * lexer, enum cpp_ttype type)
97 enum {
98         CP_PARSER_FLAGS_NONE = 0x0, CP_PARSER_FLAGS_OPTIONAL =
99             0x1, CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES =
100             0x2, CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS =
101             0x4, CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8
103 typedef int cp_parser_flags;
104 extern tree
105 cp_parser_type_specifier(cp_parser *, cp_parser_flags,
106                          cp_decl_specifier_seq *, bool, int *, bool *);
107 static void
108 cp_parser_type_specifier_seq(cp_parser *, bool, bool, cp_decl_specifier_seq *);
109 extern bool cp_next_tokens_can_be_attribute_p(cp_parser *);
110 extern tree cp_parser_attributes_opt(cp_parser *);
111 enum pragma_context {
112         pragma_external,
113         pragma_member,
114         pragma_objc_icode,
115         pragma_stmt,
116         pragma_compound
118 static bool cp_parser_pragma(cp_parser *, enum pragma_context);
119 static bool cp_parser_translation_unit(cp_parser * parser)
121         while (true) {
122                 cp_token *token;
123                 if (token->type == CPP_SEMICOLON) {
124                         cp_parser_pragma(parser, pragma_external);
125                 }
126         }
129 static tree
130 cp_parser_type_id_1(cp_parser * parser, bool is_template_arg,
131                     bool is_trailing_return)
133         cp_decl_specifier_seq type_specifier_seq;
134         cp_parser_type_specifier_seq(parser, false, is_trailing_return,
135                                      &type_specifier_seq);
138 static tree cp_parser_type_id(cp_parser * parser)
140         return cp_parser_type_id_1(parser, false, false);
143 static void
144 cp_parser_type_specifier_seq(cp_parser * parser, bool is_declaration,
145                              bool is_trailing_return,
146                              cp_decl_specifier_seq * type_specifier_seq)
148         cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL;
149         cp_token *start_token = __null;
150         while (true) {
151                 tree type_specifier;
152                 bool is_cv_qualifier;
153                 if (cp_next_tokens_can_be_attribute_p(parser)) {
154                         type_specifier_seq->attributes =
155                             chainon(type_specifier_seq->attributes,
156                                     cp_parser_attributes_opt(parser));
157                         continue;
158                 }
159                 if (!start_token)
160                         start_token = cp_lexer_peek_token(parser->lexer);
161                 type_specifier =
162                     cp_parser_type_specifier(parser, flags, type_specifier_seq,
163                                              false, __null, &is_cv_qualifier);
164                 if (!type_specifier) {
165                         break;
166                 }
167                 if (is_declaration && !is_cv_qualifier)
168                         flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
169         }
172 static bool
173 cp_parser_omp_for_loop_init(cp_parser * parser, bool parsing_openmp,
174                             tree & this_pre_body, vec < tree,
175                             va_gc > *for_block, tree & init, tree & decl,
176                             tree & real_decl)
178         cp_decl_specifier_seq type_specifiers;
179         cp_parser_type_specifier_seq(parser, true, false, &type_specifiers);
182 static tree
183 cp_parser_omp_for_loop(cp_parser * parser, enum tree_code code, tree clauses,
184                        tree * cclauses)
186         tree init, cond, incr, body, decl, pre_body = (tree) __null, ret;
187         tree real_decl, initv, condv, incrv, declv;
188         tree this_pre_body, cl;
189         int i, collapse = 1, nbraces = 0;
190         vec < tree, va_gc > *for_block = make_tree_vector();
191         for (i = 0; i < collapse; i++) {
192                 bool add_private_clause = false;
193                 add_private_clause |=
194                     cp_parser_omp_for_loop_init(parser, true,
195                                                 this_pre_body, for_block, init,
196                                                 decl, real_decl);
197         }
200 static tree
201 cp_parser_omp_simd(cp_parser * parser, cp_token * pragma_tok, char *p_name,
202                    omp_clause_mask mask, tree * cclauses)
204         tree clauses, sb, ret;
205         ret = cp_parser_omp_for_loop(parser, OMP_SIMD, clauses, cclauses);
208 static tree
209 cp_parser_omp_distribute(cp_parser * parser, cp_token * pragma_tok,
210                          char *p_name, omp_clause_mask mask, tree * cclauses)
212         if (cp_lexer_next_token_is(parser->lexer, CPP_NAME)) {
213                 tree id = cp_lexer_peek_token(parser->lexer)->u.value;
214                 const char *p =
215                     ((const char
216                       *)(tree_check((id),
217                                     "/home/bonzo/develop/trunk/gcc/cp/parser.c",
218                                     29966, __FUNCTION__,
219                                     (IDENTIFIER_NODE)))->identifier.id.str);
220                 bool simd = false;
221                 bool parallel = false;
222                 if (strcmp(p, "simd") == 0)
223                         simd = true;
224                 if (parallel || simd) {
225                         if (!global_options.x_flag_openmp) {
226                                 if (simd)
227                                         return cp_parser_omp_simd(parser,
228                                                                   pragma_tok,
229                                                                   p_name, mask,
230                                                                   cclauses);
231                         }
232                 }
233         }
236 static tree
237 cp_parser_omp_teams(cp_parser * parser, cp_token * pragma_tok, char *p_name,
238                     omp_clause_mask mask, tree * cclauses)
240         if (cp_lexer_next_token_is(parser->lexer, CPP_NAME)) {
241                 tree id = cp_lexer_peek_token(parser->lexer)->u.value;
242                 const char *p =
243                     ((const char
244                       *)(tree_check((id),
245                                     "/home/bonzo/develop/trunk/gcc/cp/parser.c",
246                                     30062, __FUNCTION__,
247                                     (IDENTIFIER_NODE)))->identifier.id.str);
248                 if (strcmp(p, "distribute") == 0) {
249                         if (!global_options.x_flag_openmp)
250                                 return cp_parser_omp_distribute(parser,
251                                                                 pragma_tok,
252                                                                 p_name, mask,
253                                                                 cclauses);
254                 }
255         }
258 static bool
259 cp_parser_omp_target(cp_parser * parser, cp_token * pragma_tok,
260                      enum pragma_context context)
262         if (context != pragma_stmt && context != pragma_compound) {
263                 tree id = cp_lexer_peek_token(parser->lexer)->u.value;
264                 const char *p =
265                     ((const char
266                       *)(tree_check((id),
267                                     "/home/bonzo/develop/trunk/gcc/cp/parser.c",
268                                     30201, __FUNCTION__,
269                                     (IDENTIFIER_NODE)))->identifier.id.str);
270                 if (strcmp(p, "teams") == 0) {
271                         tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
272                         char p_name[sizeof
273                                     ("#pragma omp target teams distribute "
274                                      "parallel for simd")];
275                         if (!global_options.x_flag_openmp)
276                                 return cp_parser_omp_teams(parser, pragma_tok,
277                                                            p_name,
278                                                            ((((omp_clause_mask)
279                                                               1) <<
280                                                              PRAGMA_OMP_CLAUSE_DEVICE)
281                                                             |
282                                                             (((omp_clause_mask)
283                                                               1) <<
284                                                              PRAGMA_OMP_CLAUSE_MAP)
285                                                             |
286                                                             (((omp_clause_mask)
287                                                               1) <<
288                                                              PRAGMA_OMP_CLAUSE_IF)),
289                                                            cclauses);
290                 }
291         }
294 static void
295 cp_parser_omp_declare_reduction(cp_parser * parser, cp_token * pragma_tok,
296                                 enum pragma_context)
298         tree reduc_id = (tree) __null, orig_reduc_id = (tree) __null, type;
299         while (true) {
300                 type = cp_parser_type_id(parser);
301         }
304 static void
305 cp_parser_omp_declare(cp_parser * parser, cp_token * pragma_tok,
306                       enum pragma_context context)
308         if (cp_lexer_next_token_is(parser->lexer, CPP_NAME)) {
309                 tree id = cp_lexer_peek_token(parser->lexer)->u.value;
310                 const char *p =
311                     ((const char
312                       *)(tree_check((id),
313                                     "/home/bonzo/develop/trunk/gcc/cp/parser.c",
314                                     30883, __FUNCTION__,
315                                     (IDENTIFIER_NODE)))->identifier.id.str);
316                 if (strcmp(p, "simd") == 0) {
317                         cp_parser_omp_declare_reduction(parser, pragma_tok,
318                                                         context);
319                 }
320         }
323 static cp_parser *the_parser;
324 static bool cp_parser_pragma(cp_parser * parser, enum pragma_context context)
326         cp_token *pragma_tok;
327         unsigned int id;
328         switch (id) {
329         case PRAGMA_OMP_DECLARE_REDUCTION:
330                 cp_parser_omp_declare(parser, pragma_tok, context);
331         case PRAGMA_OMP_TARGET:
332                 return cp_parser_omp_target(parser, pragma_tok, context);
333         }
336 void c_parse_file(void)
338         cp_parser_translation_unit(the_parser);