Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. %{
  2. /*
  3.  * Copyright © 2010 Intel Corporation
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #include <inttypes.h>
  30.  
  31. #include "glcpp.h"
  32. #include "main/core.h" /* for struct gl_extensions */
  33. #include "main/mtypes.h" /* for gl_api enum */
  34.  
  35. static void
  36. yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
  37.  
  38. static void
  39. _define_object_macro (glcpp_parser_t *parser,
  40.                       YYLTYPE *loc,
  41.                       const char *macro,
  42.                       token_list_t *replacements);
  43.  
  44. static void
  45. _define_function_macro (glcpp_parser_t *parser,
  46.                         YYLTYPE *loc,
  47.                         const char *macro,
  48.                         string_list_t *parameters,
  49.                         token_list_t *replacements);
  50.  
  51. static string_list_t *
  52. _string_list_create (void *ctx);
  53.  
  54. static void
  55. _string_list_append_item (string_list_t *list, const char *str);
  56.  
  57. static int
  58. _string_list_contains (string_list_t *list, const char *member, int *index);
  59.  
  60. static const char *
  61. _string_list_has_duplicate (string_list_t *list);
  62.  
  63. static int
  64. _string_list_length (string_list_t *list);
  65.  
  66. static int
  67. _string_list_equal (string_list_t *a, string_list_t *b);
  68.  
  69. static argument_list_t *
  70. _argument_list_create (void *ctx);
  71.  
  72. static void
  73. _argument_list_append (argument_list_t *list, token_list_t *argument);
  74.  
  75. static int
  76. _argument_list_length (argument_list_t *list);
  77.  
  78. static token_list_t *
  79. _argument_list_member_at (argument_list_t *list, int index);
  80.  
  81. /* Note: This function ralloc_steal()s the str pointer. */
  82. static token_t *
  83. _token_create_str (void *ctx, int type, char *str);
  84.  
  85. static token_t *
  86. _token_create_ival (void *ctx, int type, int ival);
  87.  
  88. static token_list_t *
  89. _token_list_create (void *ctx);
  90.  
  91. static void
  92. _token_list_append (token_list_t *list, token_t *token);
  93.  
  94. static void
  95. _token_list_append_list (token_list_t *list, token_list_t *tail);
  96.  
  97. static int
  98. _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
  99.  
  100. static void
  101. _parser_active_list_push (glcpp_parser_t *parser,
  102.                           const char *identifier,
  103.                           token_node_t *marker);
  104.  
  105. static void
  106. _parser_active_list_pop (glcpp_parser_t *parser);
  107.  
  108. static int
  109. _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier);
  110.  
  111. typedef enum {
  112.         EXPANSION_MODE_IGNORE_DEFINED,
  113.         EXPANSION_MODE_EVALUATE_DEFINED
  114. } expansion_mode_t;
  115.  
  116. /* Expand list, and begin lexing from the result (after first
  117.  * prefixing a token of type 'head_token_type').
  118.  */
  119. static void
  120. _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
  121.                                    int head_token_type,
  122.                                    token_list_t *list,
  123.                                    expansion_mode_t mode);
  124.  
  125. /* Perform macro expansion in-place on the given list. */
  126. static void
  127. _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
  128.                                  token_list_t *list,
  129.                                  expansion_mode_t mode);
  130.  
  131. static void
  132. _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
  133.                                          token_list_t *list);
  134.  
  135. static void
  136. _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
  137.                                   int condition);
  138.  
  139. static void
  140. _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
  141.                                     const char *type, int condition);
  142.  
  143. static void
  144. _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc);
  145.  
  146. static void
  147. _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
  148.                                          const char *ident, bool explicitly_set);
  149.  
  150. static int
  151. glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
  152.  
  153. static void
  154. glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list);
  155.  
  156. static void
  157. add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
  158.  
  159. %}
  160.  
  161. %pure-parser
  162. %error-verbose
  163.  
  164. %locations
  165. %initial-action {
  166.         @$.first_line = 1;
  167.         @$.first_column = 1;
  168.         @$.last_line = 1;
  169.         @$.last_column = 1;
  170.         @$.source = 0;
  171. }
  172.  
  173. %parse-param {glcpp_parser_t *parser}
  174. %lex-param {glcpp_parser_t *parser}
  175.  
  176. %expect 0
  177.  
  178.         /* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to
  179.          * HASH, DEFINE, and VERSION) to avoid conflicts with other symbols,
  180.          * (such as the <HASH> and <DEFINE> start conditions in the lexer). */
  181. %token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS
  182. %token PASTE
  183. %type <ival> INTEGER operator SPACE integer_constant
  184. %type <expression_value> expression
  185. %type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA
  186. %type <string_list> identifier_list
  187. %type <token> preprocessing_token
  188. %type <token_list> pp_tokens replacement_list text_line
  189. %left OR
  190. %left AND
  191. %left '|'
  192. %left '^'
  193. %left '&'
  194. %left EQUAL NOT_EQUAL
  195. %left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
  196. %left LEFT_SHIFT RIGHT_SHIFT
  197. %left '+' '-'
  198. %left '*' '/' '%'
  199. %right UNARY
  200.  
  201. %debug
  202.  
  203. %%
  204.  
  205. input:
  206.         /* empty */
  207. |       input line
  208. ;
  209.  
  210. line:
  211.         control_line
  212. |       SPACE control_line
  213. |       text_line {
  214.                 _glcpp_parser_print_expanded_token_list (parser, $1);
  215.                 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
  216.                 ralloc_free ($1);
  217.         }
  218. |       expanded_line
  219. ;
  220.  
  221. expanded_line:
  222.         IF_EXPANDED expression NEWLINE {
  223.                 if (parser->is_gles && $2.undefined_macro)
  224.                         glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
  225.                 _glcpp_parser_skip_stack_push_if (parser, & @1, $2.value);
  226.         }
  227. |       ELIF_EXPANDED expression NEWLINE {
  228.                 if (parser->is_gles && $2.undefined_macro)
  229.                         glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
  230.                 _glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2.value);
  231.         }
  232. |       LINE_EXPANDED integer_constant NEWLINE {
  233.                 parser->has_new_line_number = 1;
  234.                 parser->new_line_number = $2;
  235.                 ralloc_asprintf_rewrite_tail (&parser->output,
  236.                                               &parser->output_length,
  237.                                               "#line %" PRIiMAX "\n",
  238.                                               $2);
  239.         }
  240. |       LINE_EXPANDED integer_constant integer_constant NEWLINE {
  241.                 parser->has_new_line_number = 1;
  242.                 parser->new_line_number = $2;
  243.                 parser->has_new_source_number = 1;
  244.                 parser->new_source_number = $3;
  245.                 ralloc_asprintf_rewrite_tail (&parser->output,
  246.                                               &parser->output_length,
  247.                                               "#line %" PRIiMAX " %" PRIiMAX "\n",
  248.                                               $2, $3);
  249.         }
  250. ;
  251.  
  252. define:
  253.         OBJ_IDENTIFIER replacement_list NEWLINE {
  254.                 _define_object_macro (parser, & @1, $1, $2);
  255.         }
  256. |       FUNC_IDENTIFIER '(' ')' replacement_list NEWLINE {
  257.                 _define_function_macro (parser, & @1, $1, NULL, $4);
  258.         }
  259. |       FUNC_IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE {
  260.                 _define_function_macro (parser, & @1, $1, $3, $5);
  261.         }
  262. ;
  263.  
  264. control_line:
  265.         control_line_success {
  266.                 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
  267.         }
  268. |       control_line_error
  269. |       HASH_TOKEN LINE {
  270.                 glcpp_parser_resolve_implicit_version(parser);
  271.         } pp_tokens NEWLINE {
  272.  
  273.                 if (parser->skip_stack == NULL ||
  274.                     parser->skip_stack->type == SKIP_NO_SKIP)
  275.                 {
  276.                         _glcpp_parser_expand_and_lex_from (parser,
  277.                                                            LINE_EXPANDED, $4,
  278.                                                            EXPANSION_MODE_IGNORE_DEFINED);
  279.                 }
  280.         }
  281. ;
  282.  
  283. control_line_success:
  284.         HASH_TOKEN DEFINE_TOKEN {
  285.                 glcpp_parser_resolve_implicit_version(parser);
  286.         } define
  287. |       HASH_TOKEN UNDEF {
  288.                 glcpp_parser_resolve_implicit_version(parser);
  289.         } IDENTIFIER NEWLINE {
  290.                 macro_t *macro;
  291.                 if (strcmp("__LINE__", $4) == 0
  292.                     || strcmp("__FILE__", $4) == 0
  293.                     || strcmp("__VERSION__", $4) == 0
  294.                     || strncmp("GL_", $4, 3) == 0)
  295.                         glcpp_error(& @1, parser, "Built-in (pre-defined)"
  296.                                     " macro names cannot be undefined.");
  297.  
  298.                 macro = hash_table_find (parser->defines, $4);
  299.                 if (macro) {
  300.                         hash_table_remove (parser->defines, $4);
  301.                         ralloc_free (macro);
  302.                 }
  303.                 ralloc_free ($4);
  304.         }
  305. |       HASH_TOKEN IF {
  306.                 glcpp_parser_resolve_implicit_version(parser);
  307.         } pp_tokens NEWLINE {
  308.                 /* Be careful to only evaluate the 'if' expression if
  309.                  * we are not skipping. When we are skipping, we
  310.                  * simply push a new 0-valued 'if' onto the skip
  311.                  * stack.
  312.                  *
  313.                  * This avoids generating diagnostics for invalid
  314.                  * expressions that are being skipped. */
  315.                 if (parser->skip_stack == NULL ||
  316.                     parser->skip_stack->type == SKIP_NO_SKIP)
  317.                 {
  318.                         _glcpp_parser_expand_and_lex_from (parser,
  319.                                                            IF_EXPANDED, $4,
  320.                                                            EXPANSION_MODE_EVALUATE_DEFINED);
  321.                 }      
  322.                 else
  323.                 {
  324.                         _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
  325.                         parser->skip_stack->type = SKIP_TO_ENDIF;
  326.                 }
  327.         }
  328. |       HASH_TOKEN IF NEWLINE {
  329.                 /* #if without an expression is only an error if we
  330.                  *  are not skipping */
  331.                 if (parser->skip_stack == NULL ||
  332.                     parser->skip_stack->type == SKIP_NO_SKIP)
  333.                 {
  334.                         glcpp_error(& @1, parser, "#if with no expression");
  335.                 }      
  336.                 _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
  337.         }
  338. |       HASH_TOKEN IFDEF {
  339.                 glcpp_parser_resolve_implicit_version(parser);
  340.         } IDENTIFIER junk NEWLINE {
  341.                 macro_t *macro = hash_table_find (parser->defines, $4);
  342.                 ralloc_free ($4);
  343.                 _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
  344.         }
  345. |       HASH_TOKEN IFNDEF {
  346.                 glcpp_parser_resolve_implicit_version(parser);
  347.         } IDENTIFIER junk NEWLINE {
  348.                 macro_t *macro = hash_table_find (parser->defines, $4);
  349.                 ralloc_free ($4);
  350.                 _glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL);
  351.         }
  352. |       HASH_TOKEN ELIF pp_tokens NEWLINE {
  353.                 /* Be careful to only evaluate the 'elif' expression
  354.                  * if we are not skipping. When we are skipping, we
  355.                  * simply change to a 0-valued 'elif' on the skip
  356.                  * stack.
  357.                  *
  358.                  * This avoids generating diagnostics for invalid
  359.                  * expressions that are being skipped. */
  360.                 if (parser->skip_stack &&
  361.                     parser->skip_stack->type == SKIP_TO_ELSE)
  362.                 {
  363.                         _glcpp_parser_expand_and_lex_from (parser,
  364.                                                            ELIF_EXPANDED, $3,
  365.                                                            EXPANSION_MODE_EVALUATE_DEFINED);
  366.                 }
  367.                 else if (parser->skip_stack &&
  368.                     parser->skip_stack->has_else)
  369.                 {
  370.                         glcpp_error(& @1, parser, "#elif after #else");
  371.                 }
  372.                 else
  373.                 {
  374.                         _glcpp_parser_skip_stack_change_if (parser, & @1,
  375.                                                             "elif", 0);
  376.                 }
  377.         }
  378. |       HASH_TOKEN ELIF NEWLINE {
  379.                 /* #elif without an expression is an error unless we
  380.                  * are skipping. */
  381.                 if (parser->skip_stack &&
  382.                     parser->skip_stack->type == SKIP_TO_ELSE)
  383.                 {
  384.                         glcpp_error(& @1, parser, "#elif with no expression");
  385.                 }
  386.                 else if (parser->skip_stack &&
  387.                     parser->skip_stack->has_else)
  388.                 {
  389.                         glcpp_error(& @1, parser, "#elif after #else");
  390.                 }
  391.                 else
  392.                 {
  393.                         _glcpp_parser_skip_stack_change_if (parser, & @1,
  394.                                                             "elif", 0);
  395.                         glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
  396.                 }
  397.         }
  398. |       HASH_TOKEN ELSE { parser->lexing_directive = 1; } NEWLINE {
  399.                 if (parser->skip_stack &&
  400.                     parser->skip_stack->has_else)
  401.                 {
  402.                         glcpp_error(& @1, parser, "multiple #else");
  403.                 }
  404.                 else
  405.                 {
  406.                         _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
  407.                         if (parser->skip_stack)
  408.                                 parser->skip_stack->has_else = true;
  409.                 }
  410.         }
  411. |       HASH_TOKEN ENDIF {
  412.                 _glcpp_parser_skip_stack_pop (parser, & @1);
  413.         } NEWLINE
  414. |       HASH_TOKEN VERSION_TOKEN integer_constant NEWLINE {
  415.                 if (parser->version_resolved) {
  416.                         glcpp_error(& @1, parser, "#version must appear on the first line");
  417.                 }
  418.                 _glcpp_parser_handle_version_declaration(parser, $3, NULL, true);
  419.         }
  420. |       HASH_TOKEN VERSION_TOKEN integer_constant IDENTIFIER NEWLINE {
  421.                 if (parser->version_resolved) {
  422.                         glcpp_error(& @1, parser, "#version must appear on the first line");
  423.                 }
  424.                 _glcpp_parser_handle_version_declaration(parser, $3, $4, true);
  425.         }
  426. |       HASH_TOKEN NEWLINE {
  427.                 glcpp_parser_resolve_implicit_version(parser);
  428.         }
  429. |       HASH_TOKEN PRAGMA NEWLINE {
  430.                 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2);
  431.         }
  432. ;
  433.  
  434. control_line_error:
  435.         HASH_TOKEN ERROR_TOKEN NEWLINE {
  436.                 glcpp_error(& @1, parser, "#%s", $2);
  437.         }
  438. |       HASH_TOKEN DEFINE_TOKEN NEWLINE {
  439.                 glcpp_error (& @1, parser, "#define without macro name");
  440.         }
  441. |       HASH_TOKEN GARBAGE pp_tokens NEWLINE  {
  442.                 glcpp_error (& @1, parser, "Illegal non-directive after #");
  443.         }
  444. ;
  445.  
  446. integer_constant:
  447.         INTEGER_STRING {
  448.                 if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
  449.                         $$ = strtoll ($1 + 2, NULL, 16);
  450.                 } else if ($1[0] == '0') {
  451.                         $$ = strtoll ($1, NULL, 8);
  452.                 } else {
  453.                         $$ = strtoll ($1, NULL, 10);
  454.                 }
  455.         }
  456. |       INTEGER {
  457.                 $$ = $1;
  458.         }
  459.  
  460. expression:
  461.         integer_constant {
  462.                 $$.value = $1;
  463.                 $$.undefined_macro = NULL;
  464.         }
  465. |       IDENTIFIER {
  466.                 $$.value = 0;
  467.                 if (parser->is_gles)
  468.                         $$.undefined_macro = ralloc_strdup (parser, $1);
  469.                 else
  470.                         $$.undefined_macro = NULL;
  471.         }
  472. |       expression OR expression {
  473.                 $$.value = $1.value || $3.value;
  474.  
  475.                 /* Short-circuit: Only flag undefined from right side
  476.                  * if left side evaluates to false.
  477.                  */
  478.                 if ($1.undefined_macro)
  479.                         $$.undefined_macro = $1.undefined_macro;
  480.                 else if (! $1.value)
  481.                         $$.undefined_macro = $3.undefined_macro;
  482.         }
  483. |       expression AND expression {
  484.                 $$.value = $1.value && $3.value;
  485.  
  486.                 /* Short-circuit: Only flag undefined from right-side
  487.                  * if left side evaluates to true.
  488.                  */
  489.                 if ($1.undefined_macro)
  490.                         $$.undefined_macro = $1.undefined_macro;
  491.                 else if ($1.value)
  492.                         $$.undefined_macro = $3.undefined_macro;
  493.         }
  494. |       expression '|' expression {
  495.                 $$.value = $1.value | $3.value;
  496.                 if ($1.undefined_macro)
  497.                         $$.undefined_macro = $1.undefined_macro;
  498.                 else
  499.                         $$.undefined_macro = $3.undefined_macro;
  500.         }
  501. |       expression '^' expression {
  502.                 $$.value = $1.value ^ $3.value;
  503.                 if ($1.undefined_macro)
  504.                         $$.undefined_macro = $1.undefined_macro;
  505.                 else
  506.                         $$.undefined_macro = $3.undefined_macro;
  507.         }
  508. |       expression '&' expression {
  509.                 $$.value = $1.value & $3.value;
  510.                 if ($1.undefined_macro)
  511.                         $$.undefined_macro = $1.undefined_macro;
  512.                 else
  513.                         $$.undefined_macro = $3.undefined_macro;
  514.         }
  515. |       expression NOT_EQUAL expression {
  516.                 $$.value = $1.value != $3.value;
  517.                 if ($1.undefined_macro)
  518.                         $$.undefined_macro = $1.undefined_macro;
  519.                 else
  520.                         $$.undefined_macro = $3.undefined_macro;
  521.         }
  522. |       expression EQUAL expression {
  523.                 $$.value = $1.value == $3.value;
  524.                 if ($1.undefined_macro)
  525.                         $$.undefined_macro = $1.undefined_macro;
  526.                 else
  527.                         $$.undefined_macro = $3.undefined_macro;
  528.         }
  529. |       expression GREATER_OR_EQUAL expression {
  530.                 $$.value = $1.value >= $3.value;
  531.                 if ($1.undefined_macro)
  532.                         $$.undefined_macro = $1.undefined_macro;
  533.                 else
  534.                         $$.undefined_macro = $3.undefined_macro;
  535.         }
  536. |       expression LESS_OR_EQUAL expression {
  537.                 $$.value = $1.value <= $3.value;
  538.                 if ($1.undefined_macro)
  539.                         $$.undefined_macro = $1.undefined_macro;
  540.                 else
  541.                         $$.undefined_macro = $3.undefined_macro;
  542.         }
  543. |       expression '>' expression {
  544.                 $$.value = $1.value > $3.value;
  545.                 if ($1.undefined_macro)
  546.                         $$.undefined_macro = $1.undefined_macro;
  547.                 else
  548.                         $$.undefined_macro = $3.undefined_macro;
  549.         }
  550. |       expression '<' expression {
  551.                 $$.value = $1.value < $3.value;
  552.                 if ($1.undefined_macro)
  553.                         $$.undefined_macro = $1.undefined_macro;
  554.                 else
  555.                         $$.undefined_macro = $3.undefined_macro;
  556.         }
  557. |       expression RIGHT_SHIFT expression {
  558.                 $$.value = $1.value >> $3.value;
  559.                 if ($1.undefined_macro)
  560.                         $$.undefined_macro = $1.undefined_macro;
  561.                 else
  562.                         $$.undefined_macro = $3.undefined_macro;
  563.         }
  564. |       expression LEFT_SHIFT expression {
  565.                 $$.value = $1.value << $3.value;
  566.                 if ($1.undefined_macro)
  567.                         $$.undefined_macro = $1.undefined_macro;
  568.                 else
  569.                         $$.undefined_macro = $3.undefined_macro;
  570.         }
  571. |       expression '-' expression {
  572.                 $$.value = $1.value - $3.value;
  573.                 if ($1.undefined_macro)
  574.                         $$.undefined_macro = $1.undefined_macro;
  575.                 else
  576.                         $$.undefined_macro = $3.undefined_macro;
  577.         }
  578. |       expression '+' expression {
  579.                 $$.value = $1.value + $3.value;
  580.                 if ($1.undefined_macro)
  581.                         $$.undefined_macro = $1.undefined_macro;
  582.                 else
  583.                         $$.undefined_macro = $3.undefined_macro;
  584.         }
  585. |       expression '%' expression {
  586.                 if ($3.value == 0) {
  587.                         yyerror (& @1, parser,
  588.                                  "zero modulus in preprocessor directive");
  589.                 } else {
  590.                         $$.value = $1.value % $3.value;
  591.                 }
  592.                 if ($1.undefined_macro)
  593.                         $$.undefined_macro = $1.undefined_macro;
  594.                 else
  595.                         $$.undefined_macro = $3.undefined_macro;
  596.         }
  597. |       expression '/' expression {
  598.                 if ($3.value == 0) {
  599.                         yyerror (& @1, parser,
  600.                                  "division by 0 in preprocessor directive");
  601.                 } else {
  602.                         $$.value = $1.value / $3.value;
  603.                 }
  604.                 if ($1.undefined_macro)
  605.                         $$.undefined_macro = $1.undefined_macro;
  606.                 else
  607.                         $$.undefined_macro = $3.undefined_macro;
  608.         }
  609. |       expression '*' expression {
  610.                 $$.value = $1.value * $3.value;
  611.                 if ($1.undefined_macro)
  612.                         $$.undefined_macro = $1.undefined_macro;
  613.                 else
  614.                         $$.undefined_macro = $3.undefined_macro;
  615.         }
  616. |       '!' expression %prec UNARY {
  617.                 $$.value = ! $2.value;
  618.                 $$.undefined_macro = $2.undefined_macro;
  619.         }
  620. |       '~' expression %prec UNARY {
  621.                 $$.value = ~ $2.value;
  622.                 $$.undefined_macro = $2.undefined_macro;
  623.         }
  624. |       '-' expression %prec UNARY {
  625.                 $$.value = - $2.value;
  626.                 $$.undefined_macro = $2.undefined_macro;
  627.         }
  628. |       '+' expression %prec UNARY {
  629.                 $$.value = + $2.value;
  630.                 $$.undefined_macro = $2.undefined_macro;
  631.         }
  632. |       '(' expression ')' {
  633.                 $$ = $2;
  634.         }
  635. ;
  636.  
  637. identifier_list:
  638.         IDENTIFIER {
  639.                 $$ = _string_list_create (parser);
  640.                 _string_list_append_item ($$, $1);
  641.                 ralloc_steal ($$, $1);
  642.         }
  643. |       identifier_list ',' IDENTIFIER {
  644.                 $$ = $1;       
  645.                 _string_list_append_item ($$, $3);
  646.                 ralloc_steal ($$, $3);
  647.         }
  648. ;
  649.  
  650. text_line:
  651.         NEWLINE { $$ = NULL; }
  652. |       pp_tokens NEWLINE
  653. ;
  654.  
  655. replacement_list:
  656.         /* empty */ { $$ = NULL; }
  657. |       pp_tokens
  658. ;
  659.  
  660. junk:
  661.         /* empty */
  662. |       pp_tokens {
  663.                 glcpp_error(&@1, parser, "extra tokens at end of directive");
  664.         }
  665. ;
  666.  
  667. pp_tokens:
  668.         preprocessing_token {
  669.                 parser->space_tokens = 1;
  670.                 $$ = _token_list_create (parser);
  671.                 _token_list_append ($$, $1);
  672.         }
  673. |       pp_tokens preprocessing_token {
  674.                 $$ = $1;
  675.                 _token_list_append ($$, $2);
  676.         }
  677. ;
  678.  
  679. preprocessing_token:
  680.         IDENTIFIER {
  681.                 $$ = _token_create_str (parser, IDENTIFIER, $1);
  682.                 $$->location = yylloc;
  683.         }
  684. |       INTEGER_STRING {
  685.                 $$ = _token_create_str (parser, INTEGER_STRING, $1);
  686.                 $$->location = yylloc;
  687.         }
  688. |       operator {
  689.                 $$ = _token_create_ival (parser, $1, $1);
  690.                 $$->location = yylloc;
  691.         }
  692. |       DEFINED {
  693.                 $$ = _token_create_ival (parser, DEFINED, DEFINED);
  694.                 $$->location = yylloc;
  695.         }
  696. |       OTHER {
  697.                 $$ = _token_create_str (parser, OTHER, $1);
  698.                 $$->location = yylloc;
  699.         }
  700. |       SPACE {
  701.                 $$ = _token_create_ival (parser, SPACE, SPACE);
  702.                 $$->location = yylloc;
  703.         }
  704. ;
  705.  
  706. operator:
  707.         '['                     { $$ = '['; }
  708. |       ']'                     { $$ = ']'; }
  709. |       '('                     { $$ = '('; }
  710. |       ')'                     { $$ = ')'; }
  711. |       '{'                     { $$ = '{'; }
  712. |       '}'                     { $$ = '}'; }
  713. |       '.'                     { $$ = '.'; }
  714. |       '&'                     { $$ = '&'; }
  715. |       '*'                     { $$ = '*'; }
  716. |       '+'                     { $$ = '+'; }
  717. |       '-'                     { $$ = '-'; }
  718. |       '~'                     { $$ = '~'; }
  719. |       '!'                     { $$ = '!'; }
  720. |       '/'                     { $$ = '/'; }
  721. |       '%'                     { $$ = '%'; }
  722. |       LEFT_SHIFT              { $$ = LEFT_SHIFT; }
  723. |       RIGHT_SHIFT             { $$ = RIGHT_SHIFT; }
  724. |       '<'                     { $$ = '<'; }
  725. |       '>'                     { $$ = '>'; }
  726. |       LESS_OR_EQUAL           { $$ = LESS_OR_EQUAL; }
  727. |       GREATER_OR_EQUAL        { $$ = GREATER_OR_EQUAL; }
  728. |       EQUAL                   { $$ = EQUAL; }
  729. |       NOT_EQUAL               { $$ = NOT_EQUAL; }
  730. |       '^'                     { $$ = '^'; }
  731. |       '|'                     { $$ = '|'; }
  732. |       AND                     { $$ = AND; }
  733. |       OR                      { $$ = OR; }
  734. |       ';'                     { $$ = ';'; }
  735. |       ','                     { $$ = ','; }
  736. |       '='                     { $$ = '='; }
  737. |       PASTE                   { $$ = PASTE; }
  738. |       PLUS_PLUS               { $$ = PLUS_PLUS; }
  739. |       MINUS_MINUS             { $$ = MINUS_MINUS; }
  740. ;
  741.  
  742. %%
  743.  
  744. string_list_t *
  745. _string_list_create (void *ctx)
  746. {
  747.         string_list_t *list;
  748.  
  749.         list = ralloc (ctx, string_list_t);
  750.         list->head = NULL;
  751.         list->tail = NULL;
  752.  
  753.         return list;
  754. }
  755.  
  756. void
  757. _string_list_append_item (string_list_t *list, const char *str)
  758. {
  759.         string_node_t *node;
  760.  
  761.         node = ralloc (list, string_node_t);
  762.         node->str = ralloc_strdup (node, str);
  763.  
  764.         node->next = NULL;
  765.  
  766.         if (list->head == NULL) {
  767.                 list->head = node;
  768.         } else {
  769.                 list->tail->next = node;
  770.         }
  771.  
  772.         list->tail = node;
  773. }
  774.  
  775. int
  776. _string_list_contains (string_list_t *list, const char *member, int *index)
  777. {
  778.         string_node_t *node;
  779.         int i;
  780.  
  781.         if (list == NULL)
  782.                 return 0;
  783.  
  784.         for (i = 0, node = list->head; node; i++, node = node->next) {
  785.                 if (strcmp (node->str, member) == 0) {
  786.                         if (index)
  787.                                 *index = i;
  788.                         return 1;
  789.                 }
  790.         }
  791.  
  792.         return 0;
  793. }
  794.  
  795. /* Return duplicate string in list (if any), NULL otherwise. */
  796. const char *
  797. _string_list_has_duplicate (string_list_t *list)
  798. {
  799.         string_node_t *node, *dup;
  800.  
  801.         if (list == NULL)
  802.                 return NULL;
  803.  
  804.         for (node = list->head; node; node = node->next) {
  805.                 for (dup = node->next; dup; dup = dup->next) {
  806.                         if (strcmp (node->str, dup->str) == 0)
  807.                                 return node->str;
  808.                 }
  809.         }
  810.  
  811.         return NULL;
  812. }
  813.  
  814. int
  815. _string_list_length (string_list_t *list)
  816. {
  817.         int length = 0;
  818.         string_node_t *node;
  819.  
  820.         if (list == NULL)
  821.                 return 0;
  822.  
  823.         for (node = list->head; node; node = node->next)
  824.                 length++;
  825.  
  826.         return length;
  827. }
  828.  
  829. int
  830. _string_list_equal (string_list_t *a, string_list_t *b)
  831. {
  832.         string_node_t *node_a, *node_b;
  833.  
  834.         if (a == NULL && b == NULL)
  835.                 return 1;
  836.  
  837.         if (a == NULL || b == NULL)
  838.                 return 0;
  839.  
  840.         for (node_a = a->head, node_b = b->head;
  841.              node_a && node_b;
  842.              node_a = node_a->next, node_b = node_b->next)
  843.         {
  844.                 if (strcmp (node_a->str, node_b->str))
  845.                         return 0;
  846.         }
  847.  
  848.         /* Catch the case of lists being different lengths, (which
  849.          * would cause the loop above to terminate after the shorter
  850.          * list). */
  851.         return node_a == node_b;
  852. }
  853.  
  854. argument_list_t *
  855. _argument_list_create (void *ctx)
  856. {
  857.         argument_list_t *list;
  858.  
  859.         list = ralloc (ctx, argument_list_t);
  860.         list->head = NULL;
  861.         list->tail = NULL;
  862.  
  863.         return list;
  864. }
  865.  
  866. void
  867. _argument_list_append (argument_list_t *list, token_list_t *argument)
  868. {
  869.         argument_node_t *node;
  870.  
  871.         node = ralloc (list, argument_node_t);
  872.         node->argument = argument;
  873.  
  874.         node->next = NULL;
  875.  
  876.         if (list->head == NULL) {
  877.                 list->head = node;
  878.         } else {
  879.                 list->tail->next = node;
  880.         }
  881.  
  882.         list->tail = node;
  883. }
  884.  
  885. int
  886. _argument_list_length (argument_list_t *list)
  887. {
  888.         int length = 0;
  889.         argument_node_t *node;
  890.  
  891.         if (list == NULL)
  892.                 return 0;
  893.  
  894.         for (node = list->head; node; node = node->next)
  895.                 length++;
  896.  
  897.         return length;
  898. }
  899.  
  900. token_list_t *
  901. _argument_list_member_at (argument_list_t *list, int index)
  902. {
  903.         argument_node_t *node;
  904.         int i;
  905.  
  906.         if (list == NULL)
  907.                 return NULL;
  908.  
  909.         node = list->head;
  910.         for (i = 0; i < index; i++) {
  911.                 node = node->next;
  912.                 if (node == NULL)
  913.                         break;
  914.         }
  915.  
  916.         if (node)
  917.                 return node->argument;
  918.  
  919.         return NULL;
  920. }
  921.  
  922. /* Note: This function ralloc_steal()s the str pointer. */
  923. token_t *
  924. _token_create_str (void *ctx, int type, char *str)
  925. {
  926.         token_t *token;
  927.  
  928.         token = ralloc (ctx, token_t);
  929.         token->type = type;
  930.         token->value.str = str;
  931.  
  932.         ralloc_steal (token, str);
  933.  
  934.         return token;
  935. }
  936.  
  937. token_t *
  938. _token_create_ival (void *ctx, int type, int ival)
  939. {
  940.         token_t *token;
  941.  
  942.         token = ralloc (ctx, token_t);
  943.         token->type = type;
  944.         token->value.ival = ival;
  945.  
  946.         return token;
  947. }
  948.  
  949. token_list_t *
  950. _token_list_create (void *ctx)
  951. {
  952.         token_list_t *list;
  953.  
  954.         list = ralloc (ctx, token_list_t);
  955.         list->head = NULL;
  956.         list->tail = NULL;
  957.         list->non_space_tail = NULL;
  958.  
  959.         return list;
  960. }
  961.  
  962. void
  963. _token_list_append (token_list_t *list, token_t *token)
  964. {
  965.         token_node_t *node;
  966.  
  967.         node = ralloc (list, token_node_t);
  968.         node->token = token;
  969.         node->next = NULL;
  970.  
  971.         if (list->head == NULL) {
  972.                 list->head = node;
  973.         } else {
  974.                 list->tail->next = node;
  975.         }
  976.  
  977.         list->tail = node;
  978.         if (token->type != SPACE)
  979.                 list->non_space_tail = node;
  980. }
  981.  
  982. void
  983. _token_list_append_list (token_list_t *list, token_list_t *tail)
  984. {
  985.         if (tail == NULL || tail->head == NULL)
  986.                 return;
  987.  
  988.         if (list->head == NULL) {
  989.                 list->head = tail->head;
  990.         } else {
  991.                 list->tail->next = tail->head;
  992.         }
  993.  
  994.         list->tail = tail->tail;
  995.         list->non_space_tail = tail->non_space_tail;
  996. }
  997.  
  998. static token_list_t *
  999. _token_list_copy (void *ctx, token_list_t *other)
  1000. {
  1001.         token_list_t *copy;
  1002.         token_node_t *node;
  1003.  
  1004.         if (other == NULL)
  1005.                 return NULL;
  1006.  
  1007.         copy = _token_list_create (ctx);
  1008.         for (node = other->head; node; node = node->next) {
  1009.                 token_t *new_token = ralloc (copy, token_t);
  1010.                 *new_token = *node->token;
  1011.                 _token_list_append (copy, new_token);
  1012.         }
  1013.  
  1014.         return copy;
  1015. }
  1016.  
  1017. static void
  1018. _token_list_trim_trailing_space (token_list_t *list)
  1019. {
  1020.         token_node_t *tail, *next;
  1021.  
  1022.         if (list->non_space_tail) {
  1023.                 tail = list->non_space_tail->next;
  1024.                 list->non_space_tail->next = NULL;
  1025.                 list->tail = list->non_space_tail;
  1026.  
  1027.                 while (tail) {
  1028.                         next = tail->next;
  1029.                         ralloc_free (tail);
  1030.                         tail = next;
  1031.                 }
  1032.         }
  1033. }
  1034.  
  1035. static int
  1036. _token_list_is_empty_ignoring_space (token_list_t *l)
  1037. {
  1038.         token_node_t *n;
  1039.  
  1040.         if (l == NULL)
  1041.                 return 1;
  1042.  
  1043.         n = l->head;
  1044.         while (n != NULL && n->token->type == SPACE)
  1045.                 n = n->next;
  1046.  
  1047.         return n == NULL;
  1048. }
  1049.  
  1050. int
  1051. _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
  1052. {
  1053.         token_node_t *node_a, *node_b;
  1054.  
  1055.         if (a == NULL || b == NULL) {
  1056.                 int a_empty = _token_list_is_empty_ignoring_space(a);
  1057.                 int b_empty = _token_list_is_empty_ignoring_space(b);
  1058.                 return a_empty == b_empty;
  1059.         }
  1060.  
  1061.         node_a = a->head;
  1062.         node_b = b->head;
  1063.  
  1064.         while (1)
  1065.         {
  1066.                 if (node_a == NULL && node_b == NULL)
  1067.                         break;
  1068.  
  1069.                 if (node_a == NULL || node_b == NULL)
  1070.                         return 0;
  1071.                 /* Make sure whitespace appears in the same places in both.
  1072.                  * It need not be exactly the same amount of whitespace,
  1073.                  * though.
  1074.                  */
  1075.                 if (node_a->token->type == SPACE
  1076.                     && node_b->token->type == SPACE) {
  1077.                         while (node_a->token->type == SPACE)
  1078.                                 node_a = node_a->next;
  1079.                         while (node_b->token->type == SPACE)
  1080.                                 node_b = node_b->next;
  1081.                         continue;
  1082.                 }
  1083.  
  1084.                 if (node_a->token->type != node_b->token->type)
  1085.                         return 0;
  1086.  
  1087.                 switch (node_a->token->type) {
  1088.                 case INTEGER:
  1089.                         if (node_a->token->value.ival !=
  1090.                             node_b->token->value.ival)
  1091.                         {
  1092.                                 return 0;
  1093.                         }
  1094.                         break;
  1095.                 case IDENTIFIER:
  1096.                 case INTEGER_STRING:
  1097.                 case OTHER:
  1098.                         if (strcmp (node_a->token->value.str,
  1099.                                     node_b->token->value.str))
  1100.                         {
  1101.                                 return 0;
  1102.                         }
  1103.                         break;
  1104.                 }
  1105.  
  1106.                 node_a = node_a->next;
  1107.                 node_b = node_b->next;
  1108.         }
  1109.  
  1110.         return 1;
  1111. }
  1112.  
  1113. static void
  1114. _token_print (char **out, size_t *len, token_t *token)
  1115. {
  1116.         if (token->type < 256) {
  1117.                 ralloc_asprintf_rewrite_tail (out, len, "%c", token->type);
  1118.                 return;
  1119.         }
  1120.  
  1121.         switch (token->type) {
  1122.         case INTEGER:
  1123.                 ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival);
  1124.                 break;
  1125.         case IDENTIFIER:
  1126.         case INTEGER_STRING:
  1127.         case OTHER:
  1128.                 ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str);
  1129.                 break;
  1130.         case SPACE:
  1131.                 ralloc_asprintf_rewrite_tail (out, len, " ");
  1132.                 break;
  1133.         case LEFT_SHIFT:
  1134.                 ralloc_asprintf_rewrite_tail (out, len, "<<");
  1135.                 break;
  1136.         case RIGHT_SHIFT:
  1137.                 ralloc_asprintf_rewrite_tail (out, len, ">>");
  1138.                 break;
  1139.         case LESS_OR_EQUAL:
  1140.                 ralloc_asprintf_rewrite_tail (out, len, "<=");
  1141.                 break;
  1142.         case GREATER_OR_EQUAL:
  1143.                 ralloc_asprintf_rewrite_tail (out, len, ">=");
  1144.                 break;
  1145.         case EQUAL:
  1146.                 ralloc_asprintf_rewrite_tail (out, len, "==");
  1147.                 break;
  1148.         case NOT_EQUAL:
  1149.                 ralloc_asprintf_rewrite_tail (out, len, "!=");
  1150.                 break;
  1151.         case AND:
  1152.                 ralloc_asprintf_rewrite_tail (out, len, "&&");
  1153.                 break;
  1154.         case OR:
  1155.                 ralloc_asprintf_rewrite_tail (out, len, "||");
  1156.                 break;
  1157.         case PASTE:
  1158.                 ralloc_asprintf_rewrite_tail (out, len, "##");
  1159.                 break;
  1160.         case PLUS_PLUS:
  1161.                 ralloc_asprintf_rewrite_tail (out, len, "++");
  1162.                 break;
  1163.         case MINUS_MINUS:
  1164.                 ralloc_asprintf_rewrite_tail (out, len, "--");
  1165.                 break;
  1166.         case DEFINED:
  1167.                 ralloc_asprintf_rewrite_tail (out, len, "defined");
  1168.                 break;
  1169.         case PLACEHOLDER:
  1170.                 /* Nothing to print. */
  1171.                 break;
  1172.         default:
  1173.                 assert(!"Error: Don't know how to print token.");
  1174.  
  1175.                 break;
  1176.         }
  1177. }
  1178.  
  1179. /* Return a new token (ralloc()ed off of 'token') formed by pasting
  1180.  * 'token' and 'other'. Note that this function may return 'token' or
  1181.  * 'other' directly rather than allocating anything new.
  1182.  *
  1183.  * Caution: Only very cursory error-checking is performed to see if
  1184.  * the final result is a valid single token. */
  1185. static token_t *
  1186. _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
  1187. {
  1188.         token_t *combined = NULL;
  1189.  
  1190.         /* Pasting a placeholder onto anything makes no change. */
  1191.         if (other->type == PLACEHOLDER)
  1192.                 return token;
  1193.  
  1194.         /* When 'token' is a placeholder, just return 'other'. */
  1195.         if (token->type == PLACEHOLDER)
  1196.                 return other;
  1197.  
  1198.         /* A very few single-character punctuators can be combined
  1199.          * with another to form a multi-character punctuator. */
  1200.         switch (token->type) {
  1201.         case '<':
  1202.                 if (other->type == '<')
  1203.                         combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT);
  1204.                 else if (other->type == '=')
  1205.                         combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL);
  1206.                 break;
  1207.         case '>':
  1208.                 if (other->type == '>')
  1209.                         combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT);
  1210.                 else if (other->type == '=')
  1211.                         combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
  1212.                 break;
  1213.         case '=':
  1214.                 if (other->type == '=')
  1215.                         combined = _token_create_ival (token, EQUAL, EQUAL);
  1216.                 break;
  1217.         case '!':
  1218.                 if (other->type == '=')
  1219.                         combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL);
  1220.                 break;
  1221.         case '&':
  1222.                 if (other->type == '&')
  1223.                         combined = _token_create_ival (token, AND, AND);
  1224.                 break;
  1225.         case '|':
  1226.                 if (other->type == '|')
  1227.                         combined = _token_create_ival (token, OR, OR);
  1228.                 break;
  1229.         }
  1230.  
  1231.         if (combined != NULL) {
  1232.                 /* Inherit the location from the first token */
  1233.                 combined->location = token->location;
  1234.                 return combined;
  1235.         }
  1236.  
  1237.         /* Two string-valued (or integer) tokens can usually just be
  1238.          * mashed together. (We also handle a string followed by an
  1239.          * integer here as well.)
  1240.          *
  1241.          * There are some exceptions here. Notably, if the first token
  1242.          * is an integer (or a string representing an integer), then
  1243.          * the second token must also be an integer or must be a
  1244.          * string representing an integer that begins with a digit.
  1245.          */
  1246.         if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) &&
  1247.             (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER))
  1248.         {
  1249.                 char *str;
  1250.                 int combined_type;
  1251.  
  1252.                 /* Check that pasting onto an integer doesn't create a
  1253.                  * non-integer, (that is, only digits can be
  1254.                  * pasted. */
  1255.                 if (token->type == INTEGER_STRING || token->type == INTEGER)
  1256.                 {
  1257.                         switch (other->type) {
  1258.                         case INTEGER_STRING:
  1259.                                 if (other->value.str[0] < '0' ||
  1260.                                     other->value.str[0] > '9')
  1261.                                         goto FAIL;
  1262.                                 break;
  1263.                         case INTEGER:
  1264.                                 if (other->value.ival < 0)
  1265.                                         goto FAIL;
  1266.                                 break;
  1267.                         default:
  1268.                                 goto FAIL;
  1269.                         }
  1270.                 }
  1271.  
  1272.                 if (token->type == INTEGER)
  1273.                         str = ralloc_asprintf (token, "%" PRIiMAX,
  1274.                                                token->value.ival);
  1275.                 else
  1276.                         str = ralloc_strdup (token, token->value.str);
  1277.                                                
  1278.  
  1279.                 if (other->type == INTEGER)
  1280.                         ralloc_asprintf_append (&str, "%" PRIiMAX,
  1281.                                                 other->value.ival);
  1282.                 else
  1283.                         ralloc_strcat (&str, other->value.str);
  1284.  
  1285.                 /* New token is same type as original token, unless we
  1286.                  * started with an integer, in which case we will be
  1287.                  * creating an integer-string. */
  1288.                 combined_type = token->type;
  1289.                 if (combined_type == INTEGER)
  1290.                         combined_type = INTEGER_STRING;
  1291.  
  1292.                 combined = _token_create_str (token, combined_type, str);
  1293.                 combined->location = token->location;
  1294.                 return combined;
  1295.         }
  1296.  
  1297.     FAIL:
  1298.         glcpp_error (&token->location, parser, "");
  1299.         ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \"");
  1300.         _token_print (&parser->info_log, &parser->info_log_length, token);
  1301.         ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \"");
  1302.         _token_print (&parser->info_log, &parser->info_log_length, other);
  1303.         ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n");
  1304.  
  1305.         return token;
  1306. }
  1307.  
  1308. static void
  1309. _token_list_print (glcpp_parser_t *parser, token_list_t *list)
  1310. {
  1311.         token_node_t *node;
  1312.  
  1313.         if (list == NULL)
  1314.                 return;
  1315.  
  1316.         for (node = list->head; node; node = node->next)
  1317.                 _token_print (&parser->output, &parser->output_length, node->token);
  1318. }
  1319.  
  1320. void
  1321. yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
  1322. {
  1323.         glcpp_error(locp, parser, "%s", error);
  1324. }
  1325.  
  1326. static void add_builtin_define(glcpp_parser_t *parser,
  1327.                                const char *name, int value)
  1328. {
  1329.    token_t *tok;
  1330.    token_list_t *list;
  1331.  
  1332.    tok = _token_create_ival (parser, INTEGER, value);
  1333.  
  1334.    list = _token_list_create(parser);
  1335.    _token_list_append(list, tok);
  1336.    _define_object_macro(parser, NULL, name, list);
  1337. }
  1338.  
  1339. glcpp_parser_t *
  1340. glcpp_parser_create (const struct gl_extensions *extensions, gl_api api)
  1341. {
  1342.         glcpp_parser_t *parser;
  1343.  
  1344.         parser = ralloc (NULL, glcpp_parser_t);
  1345.  
  1346.         glcpp_lex_init_extra (parser, &parser->scanner);
  1347.         parser->defines = hash_table_ctor (32, hash_table_string_hash,
  1348.                                            hash_table_string_compare);
  1349.         parser->active = NULL;
  1350.         parser->lexing_directive = 0;
  1351.         parser->space_tokens = 1;
  1352.         parser->last_token_was_newline = 0;
  1353.         parser->last_token_was_space = 0;
  1354.         parser->first_non_space_token_this_line = 1;
  1355.         parser->newline_as_space = 0;
  1356.         parser->in_control_line = 0;
  1357.         parser->paren_count = 0;
  1358.         parser->commented_newlines = 0;
  1359.  
  1360.         parser->skip_stack = NULL;
  1361.         parser->skipping = 0;
  1362.  
  1363.         parser->lex_from_list = NULL;
  1364.         parser->lex_from_node = NULL;
  1365.  
  1366.         parser->output = ralloc_strdup(parser, "");
  1367.         parser->output_length = 0;
  1368.         parser->info_log = ralloc_strdup(parser, "");
  1369.         parser->info_log_length = 0;
  1370.         parser->error = 0;
  1371.  
  1372.         parser->extensions = extensions;
  1373.         parser->api = api;
  1374.         parser->version_resolved = false;
  1375.  
  1376.         parser->has_new_line_number = 0;
  1377.         parser->new_line_number = 1;
  1378.         parser->has_new_source_number = 0;
  1379.         parser->new_source_number = 0;
  1380.  
  1381.         return parser;
  1382. }
  1383.  
  1384. void
  1385. glcpp_parser_destroy (glcpp_parser_t *parser)
  1386. {
  1387.         glcpp_lex_destroy (parser->scanner);
  1388.         hash_table_dtor (parser->defines);
  1389.         ralloc_free (parser);
  1390. }
  1391.  
  1392. typedef enum function_status
  1393. {
  1394.         FUNCTION_STATUS_SUCCESS,
  1395.         FUNCTION_NOT_A_FUNCTION,
  1396.         FUNCTION_UNBALANCED_PARENTHESES
  1397. } function_status_t;
  1398.  
  1399. /* Find a set of function-like macro arguments by looking for a
  1400.  * balanced set of parentheses.
  1401.  *
  1402.  * When called, 'node' should be the opening-parenthesis token, (or
  1403.  * perhaps preceeding SPACE tokens). Upon successful return *last will
  1404.  * be the last consumed node, (corresponding to the closing right
  1405.  * parenthesis).
  1406.  *
  1407.  * Return values:
  1408.  *
  1409.  *   FUNCTION_STATUS_SUCCESS:
  1410.  *
  1411.  *      Successfully parsed a set of function arguments.       
  1412.  *
  1413.  *   FUNCTION_NOT_A_FUNCTION:
  1414.  *
  1415.  *      Macro name not followed by a '('. This is not an error, but
  1416.  *      simply that the macro name should be treated as a non-macro.
  1417.  *
  1418.  *   FUNCTION_UNBALANCED_PARENTHESES
  1419.  *
  1420.  *      Macro name is not followed by a balanced set of parentheses.
  1421.  */
  1422. static function_status_t
  1423. _arguments_parse (argument_list_t *arguments,
  1424.                   token_node_t *node,
  1425.                   token_node_t **last)
  1426. {
  1427.         token_list_t *argument;
  1428.         int paren_count;
  1429.  
  1430.         node = node->next;
  1431.  
  1432.         /* Ignore whitespace before first parenthesis. */
  1433.         while (node && node->token->type == SPACE)
  1434.                 node = node->next;
  1435.  
  1436.         if (node == NULL || node->token->type != '(')
  1437.                 return FUNCTION_NOT_A_FUNCTION;
  1438.  
  1439.         node = node->next;
  1440.  
  1441.         argument = _token_list_create (arguments);
  1442.         _argument_list_append (arguments, argument);
  1443.  
  1444.         for (paren_count = 1; node; node = node->next) {
  1445.                 if (node->token->type == '(')
  1446.                 {
  1447.                         paren_count++;
  1448.                 }
  1449.                 else if (node->token->type == ')')
  1450.                 {
  1451.                         paren_count--;
  1452.                         if (paren_count == 0)
  1453.                                 break;
  1454.                 }
  1455.  
  1456.                 if (node->token->type == ',' &&
  1457.                          paren_count == 1)
  1458.                 {
  1459.                         _token_list_trim_trailing_space (argument);
  1460.                         argument = _token_list_create (arguments);
  1461.                         _argument_list_append (arguments, argument);
  1462.                 }
  1463.                 else {
  1464.                         if (argument->head == NULL) {
  1465.                                 /* Don't treat initial whitespace as
  1466.                                  * part of the argument. */
  1467.                                 if (node->token->type == SPACE)
  1468.                                         continue;
  1469.                         }
  1470.                         _token_list_append (argument, node->token);
  1471.                 }
  1472.         }
  1473.  
  1474.         if (paren_count)
  1475.                 return FUNCTION_UNBALANCED_PARENTHESES;
  1476.  
  1477.         *last = node;
  1478.  
  1479.         return FUNCTION_STATUS_SUCCESS;
  1480. }
  1481.  
  1482. static token_list_t *
  1483. _token_list_create_with_one_ival (void *ctx, int type, int ival)
  1484. {
  1485.         token_list_t *list;
  1486.         token_t *node;
  1487.  
  1488.         list = _token_list_create (ctx);
  1489.         node = _token_create_ival (list, type, ival);
  1490.         _token_list_append (list, node);
  1491.  
  1492.         return list;
  1493. }
  1494.  
  1495. static token_list_t *
  1496. _token_list_create_with_one_space (void *ctx)
  1497. {
  1498.         return _token_list_create_with_one_ival (ctx, SPACE, SPACE);
  1499. }
  1500.  
  1501. static token_list_t *
  1502. _token_list_create_with_one_integer (void *ctx, int ival)
  1503. {
  1504.         return _token_list_create_with_one_ival (ctx, INTEGER, ival);
  1505. }
  1506.  
  1507. /* Evaluate a DEFINED token node (based on subsequent tokens in the list).
  1508.  *
  1509.  * Note: This function must only be called when "node" is a DEFINED token,
  1510.  * (and will abort with an assertion failure otherwise).
  1511.  *
  1512.  * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token
  1513.  * (optionally preceded and followed by '(' and ')' tokens) then the following
  1514.  * occurs:
  1515.  *
  1516.  *      If the identifier is a defined macro, this function returns 1.
  1517.  *
  1518.  *      If the identifier is not a defined macro, this function returns 0.
  1519.  *
  1520.  *      In either case, *last will be updated to the last node in the list
  1521.  *      consumed by the evaluation, (either the token of the identifier or the
  1522.  *      token of the closing parenthesis).
  1523.  *
  1524.  * In all other cases, (such as "node is the final node of the list", or
  1525.  * "missing closing parenthesis", etc.), this function generates a
  1526.  * preprocessor error, returns -1 and *last will not be set.
  1527.  */
  1528. static int
  1529. _glcpp_parser_evaluate_defined (glcpp_parser_t *parser,
  1530.                                 token_node_t *node,
  1531.                                 token_node_t **last)
  1532. {
  1533.         token_node_t *argument, *defined = node;
  1534.  
  1535.         assert (node->token->type == DEFINED);
  1536.  
  1537.         node = node->next;
  1538.  
  1539.         /* Ignore whitespace after DEFINED token. */
  1540.         while (node && node->token->type == SPACE)
  1541.                 node = node->next;
  1542.  
  1543.         if (node == NULL)
  1544.                 goto FAIL;
  1545.  
  1546.         if (node->token->type == IDENTIFIER || node->token->type == OTHER) {
  1547.                 argument = node;
  1548.         } else if (node->token->type == '(') {
  1549.                 node = node->next;
  1550.  
  1551.                 /* Ignore whitespace after '(' token. */
  1552.                 while (node && node->token->type == SPACE)
  1553.                         node = node->next;
  1554.  
  1555.                 if (node == NULL || (node->token->type != IDENTIFIER &&
  1556.                                      node->token->type != OTHER))
  1557.                 {
  1558.                         goto FAIL;
  1559.                 }
  1560.  
  1561.                 argument = node;
  1562.  
  1563.                 node = node->next;
  1564.  
  1565.                 /* Ignore whitespace after identifier, before ')' token. */
  1566.                 while (node && node->token->type == SPACE)
  1567.                         node = node->next;
  1568.  
  1569.                 if (node == NULL || node->token->type != ')')
  1570.                         goto FAIL;
  1571.         } else {
  1572.                 goto FAIL;
  1573.         }
  1574.  
  1575.         *last = node;
  1576.  
  1577.         return hash_table_find (parser->defines,
  1578.                                 argument->token->value.str) ? 1 : 0;
  1579.  
  1580. FAIL:
  1581.         glcpp_error (&defined->token->location, parser,
  1582.                      "\"defined\" not followed by an identifier");
  1583.         return -1;
  1584. }
  1585.  
  1586. /* Evaluate all DEFINED nodes in a given list, modifying the list in place.
  1587.  */
  1588. static void
  1589. _glcpp_parser_evaluate_defined_in_list (glcpp_parser_t *parser,
  1590.                                         token_list_t *list)
  1591. {
  1592.         token_node_t *node, *node_prev, *replacement, *last = NULL;
  1593.         int value;
  1594.  
  1595.         if (list == NULL)
  1596.                 return;
  1597.  
  1598.         node_prev = NULL;
  1599.         node = list->head;
  1600.  
  1601.         while (node) {
  1602.  
  1603.                 if (node->token->type != DEFINED)
  1604.                         goto NEXT;
  1605.  
  1606.                 value = _glcpp_parser_evaluate_defined (parser, node, &last);
  1607.                 if (value == -1)
  1608.                         goto NEXT;
  1609.  
  1610.                 replacement = ralloc (list, token_node_t);
  1611.                 replacement->token = _token_create_ival (list, INTEGER, value);
  1612.  
  1613.                 /* Splice replacement node into list, replacing from "node"
  1614.                  * through "last". */
  1615.                 if (node_prev)
  1616.                         node_prev->next = replacement;
  1617.                 else
  1618.                         list->head = replacement;
  1619.                 replacement->next = last->next;
  1620.                 if (last == list->tail)
  1621.                         list->tail = replacement;
  1622.  
  1623.                 node = replacement;
  1624.  
  1625.         NEXT:
  1626.                 node_prev = node;
  1627.                 node = node->next;
  1628.         }
  1629. }
  1630.  
  1631. /* Perform macro expansion on 'list', placing the resulting tokens
  1632.  * into a new list which is initialized with a first token of type
  1633.  * 'head_token_type'. Then begin lexing from the resulting list,
  1634.  * (return to the current lexing source when this list is exhausted).
  1635.  *
  1636.  * See the documentation of _glcpp_parser_expand_token_list for a description
  1637.  * of the "mode" parameter.
  1638.  */
  1639. static void
  1640. _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
  1641.                                    int head_token_type,
  1642.                                    token_list_t *list,
  1643.                                    expansion_mode_t mode)
  1644. {
  1645.         token_list_t *expanded;
  1646.         token_t *token;
  1647.  
  1648.         expanded = _token_list_create (parser);
  1649.         token = _token_create_ival (parser, head_token_type, head_token_type);
  1650.         _token_list_append (expanded, token);
  1651.         _glcpp_parser_expand_token_list (parser, list, mode);
  1652.         _token_list_append_list (expanded, list);
  1653.         glcpp_parser_lex_from (parser, expanded);
  1654. }
  1655.  
  1656. static void
  1657. _glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list)
  1658. {
  1659.         token_node_t *node;
  1660.  
  1661.         node = list->head;
  1662.         while (node)
  1663.         {
  1664.                 token_node_t *next_non_space;
  1665.  
  1666.                 /* Look ahead for a PASTE token, skipping space. */
  1667.                 next_non_space = node->next;
  1668.                 while (next_non_space && next_non_space->token->type == SPACE)
  1669.                         next_non_space = next_non_space->next;
  1670.  
  1671.                 if (next_non_space == NULL)
  1672.                         break;
  1673.  
  1674.                 if (next_non_space->token->type != PASTE) {
  1675.                         node = next_non_space;
  1676.                         continue;
  1677.                 }
  1678.  
  1679.                 /* Now find the next non-space token after the PASTE. */
  1680.                 next_non_space = next_non_space->next;
  1681.                 while (next_non_space && next_non_space->token->type == SPACE)
  1682.                         next_non_space = next_non_space->next;
  1683.  
  1684.                 if (next_non_space == NULL) {
  1685.                         yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
  1686.                         return;
  1687.                 }
  1688.  
  1689.                 node->token = _token_paste (parser, node->token, next_non_space->token);
  1690.                 node->next = next_non_space->next;
  1691.                 if (next_non_space == list->tail)
  1692.                         list->tail = node;
  1693.         }
  1694.  
  1695.         list->non_space_tail = list->tail;
  1696. }
  1697.  
  1698. /* This is a helper function that's essentially part of the
  1699.  * implementation of _glcpp_parser_expand_node. It shouldn't be called
  1700.  * except for by that function.
  1701.  *
  1702.  * Returns NULL if node is a simple token with no expansion, (that is,
  1703.  * although 'node' corresponds to an identifier defined as a
  1704.  * function-like macro, it is not followed with a parenthesized
  1705.  * argument list).
  1706.  *
  1707.  * Compute the complete expansion of node (which is a function-like
  1708.  * macro) and subsequent nodes which are arguments.
  1709.  *
  1710.  * Returns the token list that results from the expansion and sets
  1711.  * *last to the last node in the list that was consumed by the
  1712.  * expansion. Specifically, *last will be set as follows: as the
  1713.  * token of the closing right parenthesis.
  1714.  *
  1715.  * See the documentation of _glcpp_parser_expand_token_list for a description
  1716.  * of the "mode" parameter.
  1717.  */
  1718. static token_list_t *
  1719. _glcpp_parser_expand_function (glcpp_parser_t *parser,
  1720.                                token_node_t *node,
  1721.                                token_node_t **last,
  1722.                                expansion_mode_t mode)
  1723. {
  1724.         macro_t *macro;
  1725.         const char *identifier;
  1726.         argument_list_t *arguments;
  1727.         function_status_t status;
  1728.         token_list_t *substituted;
  1729.         int parameter_index;
  1730.  
  1731.         identifier = node->token->value.str;
  1732.  
  1733.         macro = hash_table_find (parser->defines, identifier);
  1734.  
  1735.         assert (macro->is_function);
  1736.  
  1737.         arguments = _argument_list_create (parser);
  1738.         status = _arguments_parse (arguments, node, last);
  1739.  
  1740.         switch (status) {
  1741.         case FUNCTION_STATUS_SUCCESS:
  1742.                 break;
  1743.         case FUNCTION_NOT_A_FUNCTION:
  1744.                 return NULL;
  1745.         case FUNCTION_UNBALANCED_PARENTHESES:
  1746.                 glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
  1747.                 return NULL;
  1748.         }
  1749.  
  1750.         /* Replace a macro defined as empty with a SPACE token. */
  1751.         if (macro->replacements == NULL) {
  1752.                 ralloc_free (arguments);
  1753.                 return _token_list_create_with_one_space (parser);
  1754.         }
  1755.  
  1756.         if (! ((_argument_list_length (arguments) ==
  1757.                 _string_list_length (macro->parameters)) ||
  1758.                (_string_list_length (macro->parameters) == 0 &&
  1759.                 _argument_list_length (arguments) == 1 &&
  1760.                 arguments->head->argument->head == NULL)))
  1761.         {
  1762.                 glcpp_error (&node->token->location, parser,
  1763.                               "Error: macro %s invoked with %d arguments (expected %d)\n",
  1764.                               identifier,
  1765.                               _argument_list_length (arguments),
  1766.                               _string_list_length (macro->parameters));
  1767.                 return NULL;
  1768.         }
  1769.  
  1770.         /* Perform argument substitution on the replacement list. */
  1771.         substituted = _token_list_create (arguments);
  1772.  
  1773.         for (node = macro->replacements->head; node; node = node->next)
  1774.         {
  1775.                 if (node->token->type == IDENTIFIER &&
  1776.                     _string_list_contains (macro->parameters,
  1777.                                            node->token->value.str,
  1778.                                            &parameter_index))
  1779.                 {
  1780.                         token_list_t *argument;
  1781.                         argument = _argument_list_member_at (arguments,
  1782.                                                              parameter_index);
  1783.                         /* Before substituting, we expand the argument
  1784.                          * tokens, or append a placeholder token for
  1785.                          * an empty argument. */
  1786.                         if (argument->head) {
  1787.                                 token_list_t *expanded_argument;
  1788.                                 expanded_argument = _token_list_copy (parser,
  1789.                                                                       argument);
  1790.                                 _glcpp_parser_expand_token_list (parser,
  1791.                                                                  expanded_argument,
  1792.                                                                  mode);
  1793.                                 _token_list_append_list (substituted,
  1794.                                                          expanded_argument);
  1795.                         } else {
  1796.                                 token_t *new_token;
  1797.  
  1798.                                 new_token = _token_create_ival (substituted,
  1799.                                                                 PLACEHOLDER,
  1800.                                                                 PLACEHOLDER);
  1801.                                 _token_list_append (substituted, new_token);
  1802.                         }
  1803.                 } else {
  1804.                         _token_list_append (substituted, node->token);
  1805.                 }
  1806.         }
  1807.  
  1808.         /* After argument substitution, and before further expansion
  1809.          * below, implement token pasting. */
  1810.  
  1811.         _token_list_trim_trailing_space (substituted);
  1812.  
  1813.         _glcpp_parser_apply_pastes (parser, substituted);
  1814.  
  1815.         return substituted;
  1816. }
  1817.  
  1818. /* Compute the complete expansion of node, (and subsequent nodes after
  1819.  * 'node' in the case that 'node' is a function-like macro and
  1820.  * subsequent nodes are arguments).
  1821.  *
  1822.  * Returns NULL if node is a simple token with no expansion.
  1823.  *
  1824.  * Otherwise, returns the token list that results from the expansion
  1825.  * and sets *last to the last node in the list that was consumed by
  1826.  * the expansion. Specifically, *last will be set as follows:
  1827.  *
  1828.  *      As 'node' in the case of object-like macro expansion.
  1829.  *
  1830.  *      As the token of the closing right parenthesis in the case of
  1831.  *      function-like macro expansion.
  1832.  *
  1833.  * See the documentation of _glcpp_parser_expand_token_list for a description
  1834.  * of the "mode" parameter.
  1835.  */
  1836. static token_list_t *
  1837. _glcpp_parser_expand_node (glcpp_parser_t *parser,
  1838.                            token_node_t *node,
  1839.                            token_node_t **last,
  1840.                            expansion_mode_t mode)
  1841. {
  1842.         token_t *token = node->token;
  1843.         const char *identifier;
  1844.         macro_t *macro;
  1845.  
  1846.         /* We only expand identifiers */
  1847.         if (token->type != IDENTIFIER) {
  1848.                 return NULL;
  1849.         }
  1850.  
  1851.         *last = node;
  1852.         identifier = token->value.str;
  1853.  
  1854.         /* Special handling for __LINE__ and __FILE__, (not through
  1855.          * the hash table). */
  1856.         if (strcmp(identifier, "__LINE__") == 0)
  1857.                 return _token_list_create_with_one_integer (parser, node->token->location.first_line);
  1858.  
  1859.         if (strcmp(identifier, "__FILE__") == 0)
  1860.                 return _token_list_create_with_one_integer (parser, node->token->location.source);
  1861.  
  1862.         /* Look up this identifier in the hash table. */
  1863.         macro = hash_table_find (parser->defines, identifier);
  1864.  
  1865.         /* Not a macro, so no expansion needed. */
  1866.         if (macro == NULL)
  1867.                 return NULL;
  1868.  
  1869.         /* Finally, don't expand this macro if we're already actively
  1870.          * expanding it, (to avoid infinite recursion). */
  1871.         if (_parser_active_list_contains (parser, identifier)) {
  1872.                 /* We change the token type here from IDENTIFIER to
  1873.                  * OTHER to prevent any future expansion of this
  1874.                  * unexpanded token. */
  1875.                 char *str;
  1876.                 token_list_t *expansion;
  1877.                 token_t *final;
  1878.  
  1879.                 str = ralloc_strdup (parser, token->value.str);
  1880.                 final = _token_create_str (parser, OTHER, str);
  1881.                 expansion = _token_list_create (parser);
  1882.                 _token_list_append (expansion, final);
  1883.                 return expansion;
  1884.         }
  1885.  
  1886.         if (! macro->is_function)
  1887.         {
  1888.                 token_list_t *replacement;
  1889.  
  1890.                 /* Replace a macro defined as empty with a SPACE token. */
  1891.                 if (macro->replacements == NULL)
  1892.                         return _token_list_create_with_one_space (parser);
  1893.  
  1894.                 replacement = _token_list_copy (parser, macro->replacements);
  1895.                 _glcpp_parser_apply_pastes (parser, replacement);
  1896.                 return replacement;
  1897.         }
  1898.  
  1899.         return _glcpp_parser_expand_function (parser, node, last, mode);
  1900. }
  1901.  
  1902. /* Push a new identifier onto the parser's active list.
  1903.  *
  1904.  * Here, 'marker' is the token node that appears in the list after the
  1905.  * expansion of 'identifier'. That is, when the list iterator begins
  1906.  * examining 'marker', then it is time to pop this node from the
  1907.  * active stack.
  1908.  */
  1909. static void
  1910. _parser_active_list_push (glcpp_parser_t *parser,
  1911.                           const char *identifier,
  1912.                           token_node_t *marker)
  1913. {
  1914.         active_list_t *node;
  1915.  
  1916.         node = ralloc (parser->active, active_list_t);
  1917.         node->identifier = ralloc_strdup (node, identifier);
  1918.         node->marker = marker;
  1919.         node->next = parser->active;
  1920.  
  1921.         parser->active = node;
  1922. }
  1923.  
  1924. static void
  1925. _parser_active_list_pop (glcpp_parser_t *parser)
  1926. {
  1927.         active_list_t *node = parser->active;
  1928.  
  1929.         if (node == NULL) {
  1930.                 parser->active = NULL;
  1931.                 return;
  1932.         }
  1933.  
  1934.         node = parser->active->next;
  1935.         ralloc_free (parser->active);
  1936.  
  1937.         parser->active = node;
  1938. }
  1939.  
  1940. static int
  1941. _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier)
  1942. {
  1943.         active_list_t *node;
  1944.  
  1945.         if (parser->active == NULL)
  1946.                 return 0;
  1947.  
  1948.         for (node = parser->active; node; node = node->next)
  1949.                 if (strcmp (node->identifier, identifier) == 0)
  1950.                         return 1;
  1951.  
  1952.         return 0;
  1953. }
  1954.  
  1955. /* Walk over the token list replacing nodes with their expansion.
  1956.  * Whenever nodes are expanded the walking will walk over the new
  1957.  * nodes, continuing to expand as necessary. The results are placed in
  1958.  * 'list' itself.
  1959.  *
  1960.  * The "mode" argument controls the handling of any DEFINED tokens that
  1961.  * result from expansion as follows:
  1962.  *
  1963.  *      EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be
  1964.  *              left in the final list, unevaluated. This is the correct mode
  1965.  *              for expanding any list in any context other than a
  1966.  *              preprocessor conditional, (#if or #elif).
  1967.  *
  1968.  *      EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be
  1969.  *              evaluated to 0 or 1 tokens depending on whether the following
  1970.  *              token is the name of a defined macro. If the DEFINED token is
  1971.  *              not followed by an (optionally parenthesized) identifier, then
  1972.  *              an error will be generated. This the correct mode for
  1973.  *              expanding any list in the context of a preprocessor
  1974.  *              conditional, (#if or #elif).
  1975.  */
  1976. static void
  1977. _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
  1978.                                  token_list_t *list,
  1979.                                  expansion_mode_t mode)
  1980. {
  1981.         token_node_t *node_prev;
  1982.         token_node_t *node, *last = NULL;
  1983.         token_list_t *expansion;
  1984.         active_list_t *active_initial = parser->active;
  1985.  
  1986.         if (list == NULL)
  1987.                 return;
  1988.  
  1989.         _token_list_trim_trailing_space (list);
  1990.  
  1991.         node_prev = NULL;
  1992.         node = list->head;
  1993.  
  1994.         if (mode == EXPANSION_MODE_EVALUATE_DEFINED)
  1995.                 _glcpp_parser_evaluate_defined_in_list (parser, list);
  1996.  
  1997.         while (node) {
  1998.  
  1999.                 while (parser->active && parser->active->marker == node)
  2000.                         _parser_active_list_pop (parser);
  2001.  
  2002.                 expansion = _glcpp_parser_expand_node (parser, node, &last, mode);
  2003.                 if (expansion) {
  2004.                         token_node_t *n;
  2005.  
  2006.                         if (mode == EXPANSION_MODE_EVALUATE_DEFINED) {
  2007.                                 _glcpp_parser_evaluate_defined_in_list (parser,
  2008.                                                                         expansion);
  2009.                         }
  2010.  
  2011.                         for (n = node; n != last->next; n = n->next)
  2012.                                 while (parser->active &&
  2013.                                        parser->active->marker == n)
  2014.                                 {
  2015.                                         _parser_active_list_pop (parser);
  2016.                                 }
  2017.  
  2018.                         _parser_active_list_push (parser,
  2019.                                                   node->token->value.str,
  2020.                                                   last->next);
  2021.                        
  2022.                         /* Splice expansion into list, supporting a
  2023.                          * simple deletion if the expansion is
  2024.                          * empty. */
  2025.                         if (expansion->head) {
  2026.                                 if (node_prev)
  2027.                                         node_prev->next = expansion->head;
  2028.                                 else
  2029.                                         list->head = expansion->head;
  2030.                                 expansion->tail->next = last->next;
  2031.                                 if (last == list->tail)
  2032.                                         list->tail = expansion->tail;
  2033.                         } else {
  2034.                                 if (node_prev)
  2035.                                         node_prev->next = last->next;
  2036.                                 else
  2037.                                         list->head = last->next;
  2038.                                 if (last == list->tail)
  2039.                                         list->tail = NULL;
  2040.                         }
  2041.                 } else {
  2042.                         node_prev = node;
  2043.                 }
  2044.                 node = node_prev ? node_prev->next : list->head;
  2045.         }
  2046.  
  2047.         /* Remove any lingering effects of this invocation on the
  2048.          * active list. That is, pop until the list looks like it did
  2049.          * at the beginning of this function. */
  2050.         while (parser->active && parser->active != active_initial)
  2051.                 _parser_active_list_pop (parser);
  2052.  
  2053.         list->non_space_tail = list->tail;
  2054. }
  2055.  
  2056. void
  2057. _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
  2058.                                          token_list_t *list)
  2059. {
  2060.         if (list == NULL)
  2061.                 return;
  2062.  
  2063.         _glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED);
  2064.  
  2065.         _token_list_trim_trailing_space (list);
  2066.  
  2067.         _token_list_print (parser, list);
  2068. }
  2069.  
  2070. static void
  2071. _check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
  2072.                                 const char *identifier)
  2073. {
  2074.         /* Section 3.3 (Preprocessor) of the GLSL 1.30 spec (and later) and
  2075.          * the GLSL ES spec (all versions) say:
  2076.          *
  2077.          *     "All macro names containing two consecutive underscores ( __ )
  2078.          *     are reserved for future use as predefined macro names. All
  2079.          *     macro names prefixed with "GL_" ("GL" followed by a single
  2080.          *     underscore) are also reserved."
  2081.          *
  2082.          * The intention is that names containing __ are reserved for internal
  2083.          * use by the implementation, and names prefixed with GL_ are reserved
  2084.          * for use by Khronos.  Since every extension adds a name prefixed
  2085.          * with GL_ (i.e., the name of the extension), that should be an
  2086.          * error.  Names simply containing __ are dangerous to use, but should
  2087.          * be allowed.
  2088.          *
  2089.          * A future version of the GLSL specification will clarify this.
  2090.          */
  2091.         if (strstr(identifier, "__")) {
  2092.                 glcpp_warning(loc, parser,
  2093.                               "Macro names containing \"__\" are reserved "
  2094.                               "for use by the implementation.\n");
  2095.         }
  2096.         if (strncmp(identifier, "GL_", 3) == 0) {
  2097.                 glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
  2098.         }
  2099. }
  2100.  
  2101. static int
  2102. _macro_equal (macro_t *a, macro_t *b)
  2103. {
  2104.         if (a->is_function != b->is_function)
  2105.                 return 0;
  2106.  
  2107.         if (a->is_function) {
  2108.                 if (! _string_list_equal (a->parameters, b->parameters))
  2109.                         return 0;
  2110.         }
  2111.  
  2112.         return _token_list_equal_ignoring_space (a->replacements,
  2113.                                                  b->replacements);
  2114. }
  2115.  
  2116. void
  2117. _define_object_macro (glcpp_parser_t *parser,
  2118.                       YYLTYPE *loc,
  2119.                       const char *identifier,
  2120.                       token_list_t *replacements)
  2121. {
  2122.         macro_t *macro, *previous;
  2123.  
  2124.         /* We define pre-defined macros before we've started parsing the
  2125.          * actual file. So if there's no location defined yet, that's what
  2126.          * were doing and we don't want to generate an error for using the
  2127.          * reserved names. */
  2128.         if (loc != NULL)
  2129.                 _check_for_reserved_macro_name(parser, loc, identifier);
  2130.  
  2131.         macro = ralloc (parser, macro_t);
  2132.  
  2133.         macro->is_function = 0;
  2134.         macro->parameters = NULL;
  2135.         macro->identifier = ralloc_strdup (macro, identifier);
  2136.         macro->replacements = replacements;
  2137.         ralloc_steal (macro, replacements);
  2138.  
  2139.         previous = hash_table_find (parser->defines, identifier);
  2140.         if (previous) {
  2141.                 if (_macro_equal (macro, previous)) {
  2142.                         ralloc_free (macro);
  2143.                         return;
  2144.                 }
  2145.                 glcpp_error (loc, parser, "Redefinition of macro %s\n",
  2146.                              identifier);
  2147.         }
  2148.  
  2149.         hash_table_insert (parser->defines, macro, identifier);
  2150. }
  2151.  
  2152. void
  2153. _define_function_macro (glcpp_parser_t *parser,
  2154.                         YYLTYPE *loc,
  2155.                         const char *identifier,
  2156.                         string_list_t *parameters,
  2157.                         token_list_t *replacements)
  2158. {
  2159.         macro_t *macro, *previous;
  2160.         const char *dup;
  2161.  
  2162.         _check_for_reserved_macro_name(parser, loc, identifier);
  2163.  
  2164.         /* Check for any duplicate parameter names. */
  2165.         if ((dup = _string_list_has_duplicate (parameters)) != NULL) {
  2166.                 glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"",
  2167.                              dup);
  2168.         }
  2169.  
  2170.         macro = ralloc (parser, macro_t);
  2171.         ralloc_steal (macro, parameters);
  2172.         ralloc_steal (macro, replacements);
  2173.  
  2174.         macro->is_function = 1;
  2175.         macro->parameters = parameters;
  2176.         macro->identifier = ralloc_strdup (macro, identifier);
  2177.         macro->replacements = replacements;
  2178.         previous = hash_table_find (parser->defines, identifier);
  2179.         if (previous) {
  2180.                 if (_macro_equal (macro, previous)) {
  2181.                         ralloc_free (macro);
  2182.                         return;
  2183.                 }
  2184.                 glcpp_error (loc, parser, "Redefinition of macro %s\n",
  2185.                              identifier);
  2186.         }
  2187.  
  2188.         hash_table_insert (parser->defines, macro, identifier);
  2189. }
  2190.  
  2191. static int
  2192. glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
  2193. {
  2194.         token_node_t *node;
  2195.         int ret;
  2196.  
  2197.         if (parser->lex_from_list == NULL) {
  2198.                 ret = glcpp_lex (yylval, yylloc, parser->scanner);
  2199.  
  2200.                 /* XXX: This ugly block of code exists for the sole
  2201.                  * purpose of converting a NEWLINE token into a SPACE
  2202.                  * token, but only in the case where we have seen a
  2203.                  * function-like macro name, but have not yet seen its
  2204.                  * closing parenthesis.
  2205.                  *
  2206.                  * There's perhaps a more compact way to do this with
  2207.                  * mid-rule actions in the grammar.
  2208.                  *
  2209.                  * I'm definitely not pleased with the complexity of
  2210.                  * this code here.
  2211.                  */
  2212.                 if (parser->newline_as_space)
  2213.                 {
  2214.                         if (ret == '(') {
  2215.                                 parser->paren_count++;
  2216.                         } else if (ret == ')') {
  2217.                                 parser->paren_count--;
  2218.                                 if (parser->paren_count == 0)
  2219.                                         parser->newline_as_space = 0;
  2220.                         } else if (ret == NEWLINE) {
  2221.                                 ret = SPACE;
  2222.                         } else if (ret != SPACE) {
  2223.                                 if (parser->paren_count == 0)
  2224.                                         parser->newline_as_space = 0;
  2225.                         }
  2226.                 }
  2227.                 else if (parser->in_control_line)
  2228.                 {
  2229.                         if (ret == NEWLINE)
  2230.                                 parser->in_control_line = 0;
  2231.                 }
  2232.                 else if (ret == DEFINE_TOKEN ||
  2233.                          ret == UNDEF || ret == IF ||
  2234.                          ret == IFDEF || ret == IFNDEF ||
  2235.                          ret == ELIF || ret == ELSE ||
  2236.                          ret == ENDIF || ret == HASH_TOKEN)
  2237.                 {
  2238.                         parser->in_control_line = 1;
  2239.                 }
  2240.                 else if (ret == IDENTIFIER)
  2241.                 {
  2242.                         macro_t *macro;
  2243.                         macro = hash_table_find (parser->defines,
  2244.                                                  yylval->str);
  2245.                         if (macro && macro->is_function) {
  2246.                                 parser->newline_as_space = 1;
  2247.                                 parser->paren_count = 0;
  2248.                         }
  2249.                 }
  2250.  
  2251.                 return ret;
  2252.         }
  2253.  
  2254.         node = parser->lex_from_node;
  2255.  
  2256.         if (node == NULL) {
  2257.                 ralloc_free (parser->lex_from_list);
  2258.                 parser->lex_from_list = NULL;
  2259.                 return NEWLINE;
  2260.         }
  2261.  
  2262.         *yylval = node->token->value;
  2263.         ret = node->token->type;
  2264.  
  2265.         parser->lex_from_node = node->next;
  2266.  
  2267.         return ret;
  2268. }
  2269.  
  2270. static void
  2271. glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list)
  2272. {
  2273.         token_node_t *node;
  2274.  
  2275.         assert (parser->lex_from_list == NULL);
  2276.  
  2277.         /* Copy list, eliminating any space tokens. */
  2278.         parser->lex_from_list = _token_list_create (parser);
  2279.  
  2280.         for (node = list->head; node; node = node->next) {
  2281.                 if (node->token->type == SPACE)
  2282.                         continue;
  2283.                 _token_list_append (parser->lex_from_list, node->token);
  2284.         }
  2285.  
  2286.         ralloc_free (list);
  2287.  
  2288.         parser->lex_from_node = parser->lex_from_list->head;
  2289.  
  2290.         /* It's possible the list consisted of nothing but whitespace. */
  2291.         if (parser->lex_from_node == NULL) {
  2292.                 ralloc_free (parser->lex_from_list);
  2293.                 parser->lex_from_list = NULL;
  2294.         }
  2295. }
  2296.  
  2297. static void
  2298. _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
  2299.                                   int condition)
  2300. {
  2301.         skip_type_t current = SKIP_NO_SKIP;
  2302.         skip_node_t *node;
  2303.  
  2304.         if (parser->skip_stack)
  2305.                 current = parser->skip_stack->type;
  2306.  
  2307.         node = ralloc (parser, skip_node_t);
  2308.         node->loc = *loc;
  2309.  
  2310.         if (current == SKIP_NO_SKIP) {
  2311.                 if (condition)
  2312.                         node->type = SKIP_NO_SKIP;
  2313.                 else
  2314.                         node->type = SKIP_TO_ELSE;
  2315.         } else {
  2316.                 node->type = SKIP_TO_ENDIF;
  2317.         }
  2318.  
  2319.         node->has_else = false;
  2320.         node->next = parser->skip_stack;
  2321.         parser->skip_stack = node;
  2322. }
  2323.  
  2324. static void
  2325. _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
  2326.                                     const char *type, int condition)
  2327. {
  2328.         if (parser->skip_stack == NULL) {
  2329.                 glcpp_error (loc, parser, "#%s without #if\n", type);
  2330.                 return;
  2331.         }
  2332.  
  2333.         if (parser->skip_stack->type == SKIP_TO_ELSE) {
  2334.                 if (condition)
  2335.                         parser->skip_stack->type = SKIP_NO_SKIP;
  2336.         } else {
  2337.                 parser->skip_stack->type = SKIP_TO_ENDIF;
  2338.         }
  2339. }
  2340.  
  2341. static void
  2342. _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc)
  2343. {
  2344.         skip_node_t *node;
  2345.  
  2346.         if (parser->skip_stack == NULL) {
  2347.                 glcpp_error (loc, parser, "#endif without #if\n");
  2348.                 return;
  2349.         }
  2350.  
  2351.         node = parser->skip_stack;
  2352.         parser->skip_stack = node->next;
  2353.         ralloc_free (node);
  2354. }
  2355.  
  2356. static void
  2357. _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
  2358.                                          const char *es_identifier,
  2359.                                          bool explicitly_set)
  2360. {
  2361.         const struct gl_extensions *extensions = parser->extensions;
  2362.  
  2363.         if (parser->version_resolved)
  2364.                 return;
  2365.  
  2366.         parser->version_resolved = true;
  2367.  
  2368.         add_builtin_define (parser, "__VERSION__", version);
  2369.  
  2370.         parser->is_gles = (version == 100) ||
  2371.                            (es_identifier &&
  2372.                             (strcmp(es_identifier, "es") == 0));
  2373.  
  2374.         /* Add pre-defined macros. */
  2375.         if (parser->is_gles) {
  2376.            add_builtin_define(parser, "GL_ES", 1);
  2377.            add_builtin_define(parser, "GL_EXT_separate_shader_objects", 1);
  2378.            add_builtin_define(parser, "GL_EXT_draw_buffers", 1);
  2379.  
  2380.            if (extensions != NULL) {
  2381.               if (extensions->OES_EGL_image_external)
  2382.                  add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
  2383.               if (extensions->OES_standard_derivatives)
  2384.                  add_builtin_define(parser, "GL_OES_standard_derivatives", 1);
  2385.            }
  2386.         } else {
  2387.            add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
  2388.            add_builtin_define(parser, "GL_ARB_separate_shader_objects", 1);
  2389.            add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
  2390.            add_builtin_define(parser, "GL_AMD_shader_trinary_minmax", 1);
  2391.  
  2392.  
  2393.            if (extensions != NULL) {
  2394.               if (extensions->EXT_texture_array)
  2395.                  add_builtin_define(parser, "GL_EXT_texture_array", 1);
  2396.  
  2397.               if (extensions->ARB_arrays_of_arrays)
  2398.                   add_builtin_define(parser, "GL_ARB_arrays_of_arrays", 1);
  2399.  
  2400.               if (extensions->ARB_fragment_coord_conventions)
  2401.                  add_builtin_define(parser, "GL_ARB_fragment_coord_conventions",
  2402.                                     1);
  2403.  
  2404.               if (extensions->ARB_fragment_layer_viewport)
  2405.                  add_builtin_define(parser, "GL_ARB_fragment_layer_viewport", 1);
  2406.  
  2407.               if (extensions->ARB_explicit_attrib_location)
  2408.                  add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1);
  2409.  
  2410.               if (extensions->ARB_explicit_uniform_location)
  2411.                  add_builtin_define(parser, "GL_ARB_explicit_uniform_location", 1);
  2412.  
  2413.               if (extensions->ARB_shader_texture_lod)
  2414.                  add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1);
  2415.  
  2416.               if (extensions->ARB_draw_instanced)
  2417.                  add_builtin_define(parser, "GL_ARB_draw_instanced", 1);
  2418.  
  2419.               if (extensions->ARB_conservative_depth) {
  2420.                  add_builtin_define(parser, "GL_AMD_conservative_depth", 1);
  2421.                  add_builtin_define(parser, "GL_ARB_conservative_depth", 1);
  2422.               }
  2423.  
  2424.               if (extensions->ARB_shader_bit_encoding)
  2425.                  add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1);
  2426.  
  2427.               if (extensions->ARB_uniform_buffer_object)
  2428.                  add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1);
  2429.  
  2430.               if (extensions->ARB_texture_cube_map_array)
  2431.                  add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1);
  2432.  
  2433.               if (extensions->ARB_shading_language_packing)
  2434.                  add_builtin_define(parser, "GL_ARB_shading_language_packing", 1);
  2435.  
  2436.               if (extensions->ARB_texture_multisample)
  2437.                  add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
  2438.  
  2439.               if (extensions->ARB_texture_query_levels)
  2440.                  add_builtin_define(parser, "GL_ARB_texture_query_levels", 1);
  2441.  
  2442.               if (extensions->ARB_texture_query_lod)
  2443.                  add_builtin_define(parser, "GL_ARB_texture_query_lod", 1);
  2444.  
  2445.               if (extensions->ARB_gpu_shader5)
  2446.                  add_builtin_define(parser, "GL_ARB_gpu_shader5", 1);
  2447.  
  2448.               if (extensions->ARB_gpu_shader_fp64)
  2449.                  add_builtin_define(parser, "GL_ARB_gpu_shader_fp64", 1);
  2450.  
  2451.               if (extensions->ARB_vertex_attrib_64bit)
  2452.                  add_builtin_define(parser, "GL_ARB_vertex_attrib_64bit", 1);
  2453.  
  2454.               if (extensions->AMD_vertex_shader_layer)
  2455.                  add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1);
  2456.  
  2457.               if (extensions->AMD_vertex_shader_viewport_index)
  2458.                  add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1);
  2459.  
  2460.               if (extensions->ARB_shading_language_420pack)
  2461.                  add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
  2462.  
  2463.               if (extensions->ARB_sample_shading)
  2464.                  add_builtin_define(parser, "GL_ARB_sample_shading", 1);
  2465.  
  2466.               if (extensions->ARB_texture_gather)
  2467.                  add_builtin_define(parser, "GL_ARB_texture_gather", 1);
  2468.  
  2469.               if (extensions->ARB_shader_atomic_counters)
  2470.                  add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1);
  2471.  
  2472.               if (extensions->ARB_viewport_array)
  2473.                  add_builtin_define(parser, "GL_ARB_viewport_array", 1);
  2474.  
  2475.               if (extensions->ARB_compute_shader)
  2476.                  add_builtin_define(parser, "GL_ARB_compute_shader", 1);
  2477.  
  2478.               if (extensions->ARB_shader_image_load_store)
  2479.                  add_builtin_define(parser, "GL_ARB_shader_image_load_store", 1);
  2480.  
  2481.               if (extensions->ARB_derivative_control)
  2482.                  add_builtin_define(parser, "GL_ARB_derivative_control", 1);
  2483.  
  2484.               if (extensions->ARB_shader_precision)
  2485.                  add_builtin_define(parser, "GL_ARB_shader_precision", 1);
  2486.            }
  2487.         }
  2488.  
  2489.         if (extensions != NULL) {
  2490.            if (extensions->EXT_shader_integer_mix)
  2491.               add_builtin_define(parser, "GL_EXT_shader_integer_mix", 1);
  2492.         }
  2493.  
  2494.         if (version >= 150)
  2495.                 add_builtin_define(parser, "GL_core_profile", 1);
  2496.  
  2497.         /* Currently, all ES2/ES3 implementations support highp in the
  2498.          * fragment shader, so we always define this macro in ES2/ES3.
  2499.          * If we ever get a driver that doesn't support highp, we'll
  2500.          * need to add a flag to the gl_context and check that here.
  2501.          */
  2502.         if (version >= 130 || parser->is_gles)
  2503.                 add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
  2504.  
  2505.         if (explicitly_set) {
  2506.            ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length,
  2507.                                          "#version %" PRIiMAX "%s%s", version,
  2508.                                          es_identifier ? " " : "",
  2509.                                          es_identifier ? es_identifier : "");
  2510.         }
  2511. }
  2512.  
  2513. /* GLSL version if no version is explicitly specified. */
  2514. #define IMPLICIT_GLSL_VERSION 110
  2515.  
  2516. /* GLSL ES version if no version is explicitly specified. */
  2517. #define IMPLICIT_GLSL_ES_VERSION 100
  2518.  
  2519. void
  2520. glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser)
  2521. {
  2522.         int language_version = parser->api == API_OPENGLES2 ?
  2523.                                IMPLICIT_GLSL_ES_VERSION :
  2524.                                IMPLICIT_GLSL_VERSION;
  2525.  
  2526.         _glcpp_parser_handle_version_declaration(parser, language_version,
  2527.                                                  NULL, false);
  2528. }
  2529.