home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Compilers⁄Interps / GCC-2.3.3r12 / Sources-C / c-pragma.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-21  |  9.6 KB  |  411 lines  |  [TEXT/MPS ]

  1. /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
  2.    Copyright (C) 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "config.h"
  22. #include "tree.h"
  23.  
  24. #ifdef HANDLE_SYSV_PRAGMA
  25.  
  26. /* Support #pragma weak by default if WEAK_ASM_OP is defined.  */
  27. #if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (SET_ASM_OP)
  28. #define HANDLE_PRAGMA_WEAK 1
  29. #endif
  30.  
  31. /* When structure field packing is in effect, this variable is the
  32.    number of bits to use as the maximum alignment.  When packing is not
  33.    in effect, this is zero. */
  34.  
  35. extern int maximum_field_alignment;
  36.  
  37. /* File used for outputting assembler code.  */
  38. extern FILE *asm_out_file;
  39.  
  40. /* Handle one token of a pragma directive.  TOKEN is the
  41.    current token, and STRING is its printable form.  */
  42.  
  43. void
  44. handle_pragma_token (string, token)
  45.      char *string;
  46.      tree token;
  47. {
  48.   static enum pragma_state
  49.     {
  50.       ps_start,
  51.       ps_done,
  52.       ps_bad,
  53.       ps_weak,
  54.       ps_name,
  55.       ps_equals,
  56.       ps_value,
  57.       ps_pack,
  58.       ps_left,
  59.       ps_align,
  60.       ps_right
  61.       } state = ps_start, type;
  62.   static char *name;
  63.   static char *value;
  64.   static int align;
  65.  
  66.   if (string == 0)
  67.     {
  68.       if (type == ps_pack)
  69.     {
  70.       if (state == ps_right)
  71.         maximum_field_alignment = align * 8;
  72.       else
  73.         warning ("malformed `#pragma pack'");
  74.     }
  75.       else if (type == ps_weak)
  76.     {
  77. #ifdef HANDLE_PRAGMA_WEAK
  78.       if (HANDLE_PRAGMA_WEAK)
  79.         {
  80.           if (state == ps_name || state == ps_value)
  81.         {
  82.           fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
  83.           ASM_OUTPUT_LABELREF (asm_out_file, name);
  84.           fputc ('\n', asm_out_file);
  85.           if (state == ps_value)
  86.             {
  87.               fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
  88.               ASM_OUTPUT_LABELREF (asm_out_file, name);
  89.               fputc (',', asm_out_file);
  90.               ASM_OUTPUT_LABELREF (asm_out_file, value);
  91.               fputc ('\n', asm_out_file);
  92.             }
  93.         }
  94.           else if (! (state == ps_done || state == ps_start))
  95.         warning ("malformed `#pragma weak'");
  96.         }
  97. #endif /* HANDLE_PRAMA_WEAK */
  98.     }
  99.  
  100.       type = state = ps_start;
  101.       return;
  102.     }
  103.  
  104.   switch (state)
  105.     {
  106.     case ps_start:
  107.       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  108.     {
  109.       if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
  110.         type = state = ps_pack;
  111.       else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
  112.         type = state = ps_weak;
  113.       else
  114.         type = state = ps_done;
  115.     }
  116.       else
  117.     type = state = ps_done;
  118.       break;
  119.  
  120.     case ps_weak:
  121.       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  122.     {
  123.       name = IDENTIFIER_POINTER (token);
  124.       state = ps_name;
  125.     }
  126.       else
  127.     state = ps_bad;
  128.       break;
  129.  
  130.     case ps_name:
  131.       state = (strcmp (string, "=") ? ps_bad : ps_equals);
  132.       break;
  133.  
  134.     case ps_equals:
  135.       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  136.     {
  137.       value = IDENTIFIER_POINTER (token);
  138.       state = ps_value;
  139.     }
  140.       else
  141.     state = ps_bad;
  142.       break;
  143.  
  144.     case ps_value:
  145.       state = ps_bad;
  146.       break;
  147.  
  148.     case ps_pack:
  149.       if (strcmp (string, "(") == 0)
  150.     state = ps_left;
  151.       else
  152.     state = ps_bad;
  153.       break;
  154.  
  155.     case ps_left:
  156.       if (token && TREE_CODE (token) == INTEGER_CST
  157.       && TREE_INT_CST_HIGH (token) == 0)
  158.     switch (TREE_INT_CST_LOW (token))
  159.       {
  160.       case 1:
  161.       case 2:
  162.       case 4:
  163.         align = TREE_INT_CST_LOW (token);
  164.         state = ps_align;
  165.         break;
  166.  
  167.       default:
  168.         state = ps_bad;
  169.       }
  170.       else if (! token && strcmp (string, ")") == 0)
  171.     {
  172.       align = 0;
  173.       state = ps_right;
  174.     }
  175.       else
  176.     state = ps_bad;
  177.       break;
  178.  
  179.     case ps_align:
  180.       if (strcmp (string, ")") == 0)
  181.     state = ps_right;
  182.       else
  183.     state = ps_bad;
  184.       break;
  185.  
  186.     case ps_right:
  187.       state = ps_bad;
  188.       break;
  189.  
  190.     case ps_bad:
  191.     case ps_done:
  192.       break;
  193.  
  194.     default:
  195.       abort ();
  196.     }
  197. }
  198. #endif /* HANDLE_SYSV_PRAGMA */
  199.  
  200. int parameter_pragma_supplied = 0;
  201.  
  202. #ifdef SPECIAL_CALLING_CONVENTIONS
  203. SPECIAL_CALLING_CONVENTIONS current_call_convention;
  204. #endif
  205.  
  206. char current_name_in_pragma[1000];
  207.  
  208. #ifdef HANDLE_MPW_PRAGMA
  209.  
  210. /* Handle one token of a pragma directive.  TOKEN is the
  211.    current token, and STRING is its printable form.  */
  212.  
  213. void
  214. handle_pragma_token (string, token)
  215.      char *string;
  216.      tree token;
  217. {
  218.   /* This enum defines all the states that our miniature pragma parser
  219.      can be in. */
  220.   static enum pragma_state
  221.     {
  222.       ps_start,
  223.       ps_parameter,
  224.       ps_parameter_result,
  225.       ps_parameter_function,
  226.       ps_parameter_open,
  227.       ps_parameter_arg,
  228.       ps_parameter_comma,
  229.       ps_parameter_close,
  230.       ps_trace,
  231.       ps_done,
  232.       ps_bad
  233.       } state = ps_start, type;
  234.   static int nextreg;
  235.   extern int flag_gen_trace_calls, flag_trace_pragma_override;
  236.   int i, regn;
  237.  
  238.   /* Handle the case of a empty token string, which is what we get
  239.      here when the pragma reader is at the end of the line. */
  240.   if (string == 0)
  241.     {
  242.       switch (type)
  243.     {
  244.     case ps_parameter:
  245.       if (state == ps_parameter_close)
  246.         parameter_pragma_supplied = 1;
  247.       else if (state == ps_parameter_function)
  248.         parameter_pragma_supplied = 1;
  249.       else
  250.         warning ("malformed `#pragma parameter'");
  251.       break;
  252.     }
  253.  
  254.       /* Reset the type and state for the next pragma. */
  255.       type = state = ps_start;
  256.       return;
  257.     }
  258.  
  259. /*  printf("String is %s, type is %d, state is %d\n", string, type, state); */
  260.  
  261.   switch (state)
  262.     {
  263.     case ps_start:
  264.       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  265.     {
  266.       if (strcmp (IDENTIFIER_POINTER (token), "dump") == 0)
  267.         {
  268.           warning ("Don't know how to dump precompiled info");
  269.           type = state = ps_done;
  270.         }
  271.       else if (strcmp (IDENTIFIER_POINTER (token), "force_active") == 0)
  272.         {
  273.           warning ("Don't know how to dump precompiled info");
  274.           type = state = ps_done;
  275.         }
  276.       else if (strcmp (IDENTIFIER_POINTER (token), "load") == 0)
  277.         {
  278.           warning ("Don't know how to load precompiled info");
  279.           type = state = ps_done;
  280.         }
  281.       else if (strcmp (IDENTIFIER_POINTER (token), "mbg") == 0)
  282.         {
  283.           warning ("unimplemented pragma");
  284.           type = state = ps_done;
  285.         }
  286.       else if (strcmp (IDENTIFIER_POINTER (token), "opt") == 0)
  287.         {
  288.           warning ("unimplemented pragma");
  289.           type = state = ps_done;
  290.         }
  291.       else if (strcmp (IDENTIFIER_POINTER (token), "parameter") == 0)
  292.         {
  293.           /* Reset the contents of the pragma we're working on. */
  294. #ifdef SPECIAL_CALLING_CONVENTIONS
  295.           /* (should be attached to the target machine better) */
  296.           current_call_convention.pascalp = 0;
  297.           current_call_convention.return_regno = -1;
  298.           for (i = 0; i < 5; ++i)
  299.         current_call_convention.parameter_regno[i] = -1;
  300. #endif
  301.           strcpy (current_name_in_pragma, "");
  302.           type = state = ps_parameter;
  303.         }
  304.       else if (strcmp (IDENTIFIER_POINTER (token), "pop") == 0)
  305.         {
  306.           warning ("unimplemented pragma");
  307.           type = state = ps_done;
  308.         }
  309.       else if (strcmp (IDENTIFIER_POINTER (token), "processor") == 0)
  310.         {
  311.           warning ("unimplemented pragma");
  312.           type = state = ps_done;
  313.         }
  314.       else if (strcmp (IDENTIFIER_POINTER (token), "push") == 0)
  315.         {
  316.           warning ("unimplemented pragma");
  317.           type = state = ps_done;
  318.         }
  319.       else if (strcmp (IDENTIFIER_POINTER (token), "trace") == 0)
  320.         {
  321.           type = state = (flag_trace_pragma_override ? ps_done : ps_trace);
  322.         }
  323.       else if (strcmp (IDENTIFIER_POINTER (token), "warnings") == 0)
  324.         {
  325.           warning ("unimplemented pragma");
  326.           type = state = ps_done;
  327.         }
  328.       else
  329.         /* This is a pragma we don't understand.  Don't complain
  330.            though, just ignore it and get out of here. */
  331.         type = state = ps_done;
  332.     }
  333.       else
  334.     type = state = ps_done;
  335.       break;
  336.  
  337.     case ps_parameter:
  338.       if ((regn = parsereg (string)) >= 0)
  339.     {
  340. #ifdef SPECIAL_CALLING_CONVENTIONS
  341.       current_call_convention.return_regno = regn;
  342. #endif
  343.       state = ps_parameter_result;
  344.     }
  345.       else
  346.     {
  347.       strcpy(current_name_in_pragma, string);
  348.       state = ps_parameter_function;
  349.     }
  350.       break;
  351.  
  352.     case ps_parameter_result:
  353.       strcpy(current_name_in_pragma, string);
  354.       state = ps_parameter_function;
  355.       break;
  356.  
  357.     case ps_parameter_function:
  358.       if (strcmp (string, "(") == 0)
  359.     state = ps_parameter_open;
  360.       else
  361.     state = ps_bad;
  362.       break;
  363.  
  364.     case ps_parameter_open:
  365.       nextreg = 0;
  366.     case ps_parameter_comma:
  367. #ifdef SPECIAL_CALLING_CONVENTIONS
  368.       if ((regn = parsereg (string)) >= 0)
  369.     {
  370.       current_call_convention.parameter_regno[nextreg++] = regn;
  371.       state = ps_parameter_arg;
  372.     }
  373.       else
  374. #endif
  375.     state = ps_bad;
  376.       break;
  377.  
  378.     case ps_parameter_arg:
  379.       if (strcmp (string, ")") == 0)
  380.     state = ps_parameter_close;
  381.       else if (strcmp (string, ",") == 0)
  382.     state = ps_parameter_comma;
  383.       else
  384.     state = ps_bad;
  385.       break;
  386.  
  387.     case ps_parameter_close:
  388.       /* If we get here, then there was junk after the closing paren. */
  389.       state = ps_bad;
  390.       break;
  391.  
  392.     case ps_trace:
  393.       if (strcmp (string, "on") == 0)
  394.     flag_gen_trace_calls = 1;
  395.       else if (strcmp (string, "off") == 0)
  396.     flag_gen_trace_calls = 0;
  397.       else
  398.     state = ps_bad;
  399.       break;
  400.  
  401.     case ps_done:
  402.     case ps_bad:
  403.       break;
  404.  
  405.     default:
  406.       abort ();
  407.     }
  408. }
  409.  
  410. #endif /* HANDLE_MPW_PRAGMA */
  411.