TIC4X testcase commit
[deliverable/binutils-gdb.git] / gas / cond.c
index 943c9f6bf8295b30a61465edcd6a1d91a8717518..b7a4082c52846a17036354081e834b383d593f7b 100644 (file)
@@ -1,5 +1,5 @@
 /* cond.c - conditional assembly pseudo-ops, and .include
 /* cond.c - conditional assembly pseudo-ops, and .include
-   Copyright (C) 1990, 91, 92, 93, 95, 96, 97, 98, 1999
+   Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 #include "obstack.h"
 
 
 #include "obstack.h"
 
-/* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */
+/* This is allocated to grow and shrink as .ifdef/.endif pairs are
+   scanned.  */
 struct obstack cond_obstack;
 
 struct obstack cond_obstack;
 
-struct file_line
-{
+struct file_line {
   char *file;
   unsigned int line;
 };
   char *file;
   unsigned int line;
 };
@@ -36,8 +36,7 @@ struct file_line
 /* We push one of these structures for each .if, and pop it at the
    .endif.  */
 
 /* We push one of these structures for each .if, and pop it at the
    .endif.  */
 
-struct conditional_frame
-{
+struct conditional_frame {
   /* The source file & line number of the "if".  */
   struct file_line if_file_line;
   /* The source file & line of the "else".  */
   /* The source file & line number of the "if".  */
   struct file_line if_file_line;
   /* The source file & line of the "else".  */
@@ -48,7 +47,9 @@ struct conditional_frame
   int else_seen;
   /* Whether we are currently ignoring input.  */
   int ignoring;
   int else_seen;
   /* Whether we are currently ignoring input.  */
   int ignoring;
-  /* Whether a conditional at a higher level is ignoring input.  */
+  /* Whether a conditional at a higher level is ignoring input.
+     Set also when a branch of an "if .. elseif .." tree has matched
+     to prevent further matches.  */
   int dead_tree;
   /* Macro nesting level at which this conditional was created.  */
   int macro_nest;
   int dead_tree;
   /* Macro nesting level at which this conditional was created.  */
   int macro_nest;
@@ -59,15 +60,22 @@ static char *get_mri_string PARAMS ((int, int *));
 
 static struct conditional_frame *current_cframe = NULL;
 
 
 static struct conditional_frame *current_cframe = NULL;
 
-void 
-s_ifdef (arg)
-     int arg;
+/* Performs the .ifdef (test_defined == 1) and
+   the .ifndef (test_defined == 0) pseudo op.  */
+
+void
+s_ifdef (test_defined)
+     int test_defined;
 {
 {
-  register char *name;         /* points to name of symbol */
-  register symbolS *symbolP;   /* Points to symbol */
+  /* Points to name of symbol.  */
+  char *name;
+  /* Points to symbol.  */
+  symbolS *symbolP;
   struct conditional_frame cframe;
   struct conditional_frame cframe;
+  char c;
 
 
-  SKIP_WHITESPACE ();          /* Leading whitespace is part of operand. */
+  /* Leading whitespace is part of operand.  */
+  SKIP_WHITESPACE ();
   name = input_line_pointer;
 
   if (!is_name_beginner (*name))
   name = input_line_pointer;
 
   if (!is_name_beginner (*name))
@@ -75,32 +83,46 @@ s_ifdef (arg)
       as_bad (_("invalid identifier for \".ifdef\""));
       obstack_1grow (&cond_obstack, 0);
       ignore_rest_of_line ();
       as_bad (_("invalid identifier for \".ifdef\""));
       obstack_1grow (&cond_obstack, 0);
       ignore_rest_of_line ();
+      return;
     }
     }
+
+  c = get_symbol_end ();
+  symbolP = symbol_find (name);
+  *input_line_pointer = c;
+
+  initialize_cframe (&cframe);
+  
+  if (cframe.dead_tree)
+    cframe.ignoring = 1;
   else
     {
   else
     {
-      char c;
+      int is_defined;
 
 
-      c = get_symbol_end ();
-      symbolP = symbol_find (name);
-      *input_line_pointer = c;
+      /* Use the same definition of 'defined' as .equiv so that a symbol
+        which has been referenced but not yet given a value/address is
+        considered to be undefined.  */
+      is_defined =
+       symbolP != NULL
+       && S_IS_DEFINED (symbolP)
+       && S_GET_SEGMENT (symbolP) != reg_section;
 
 
-      initialize_cframe (&cframe);
-      cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
-      current_cframe = ((struct conditional_frame *)
-                       obstack_copy (&cond_obstack, &cframe,
-                                     sizeof (cframe)));
+      cframe.ignoring = ! (test_defined ^ is_defined);
+    }
 
 
-      if (LISTING_SKIP_COND ()
-         && cframe.ignoring
-         && (cframe.previous_cframe == NULL
-             || ! cframe.previous_cframe->ignoring))
-       listing_list (2);
+  current_cframe = ((struct conditional_frame *)
+                   obstack_copy (&cond_obstack, &cframe,
+                                 sizeof (cframe)));
 
 
-      demand_empty_rest_of_line ();
-    }                          /* if a valid identifyer name */
-}                              /* s_ifdef() */
+  if (LISTING_SKIP_COND ()
+      && cframe.ignoring
+      && (cframe.previous_cframe == NULL
+         || ! cframe.previous_cframe->ignoring))
+    listing_list (2);
 
 
-void 
+  demand_empty_rest_of_line ();
+}
+
+void
 s_if (arg)
      int arg;
 {
 s_if (arg)
      int arg;
 {
@@ -113,7 +135,8 @@ s_if (arg)
   if (flag_mri)
     stop = mri_comment_field (&stopc);
 
   if (flag_mri)
     stop = mri_comment_field (&stopc);
 
-  SKIP_WHITESPACE ();          /* Leading whitespace is part of operand. */
+  /* Leading whitespace is part of operand.  */
+  SKIP_WHITESPACE ();
 
   if (current_cframe != NULL && current_cframe->ignoring)
     {
 
   if (current_cframe != NULL && current_cframe->ignoring)
     {
@@ -158,7 +181,7 @@ s_if (arg)
     mri_comment_end (stop, stopc);
 
   demand_empty_rest_of_line ();
     mri_comment_end (stop, stopc);
 
   demand_empty_rest_of_line ();
-}                              /* s_if() */
+}
 
 /* Get a string for the MRI IFC or IFNC pseudo-ops.  */
 
 
 /* Get a string for the MRI IFC or IFNC pseudo-ops.  */
 
@@ -246,7 +269,83 @@ s_ifc (arg)
   demand_empty_rest_of_line ();
 }
 
   demand_empty_rest_of_line ();
 }
 
-void 
+void
+s_elseif (arg)
+     int arg;
+{
+  if (current_cframe == NULL)
+    {
+      as_bad (_("\".elseif\" without matching \".if\""));
+    }
+  else if (current_cframe->else_seen)
+    {
+      as_bad (_("\".elseif\" after \".else\""));
+      as_bad_where (current_cframe->else_file_line.file,
+                   current_cframe->else_file_line.line,
+                   _("here is the previous \"else\""));
+      as_bad_where (current_cframe->if_file_line.file,
+                   current_cframe->if_file_line.line,
+                   _("here is the previous \"if\""));
+    }
+  else
+    {
+      as_where (&current_cframe->else_file_line.file,
+               &current_cframe->else_file_line.line);
+
+      current_cframe->dead_tree |= !current_cframe->ignoring;
+      current_cframe->ignoring = current_cframe->dead_tree;
+    }
+
+  if (current_cframe == NULL || current_cframe->ignoring)
+    {
+      while (! is_end_of_line[(unsigned char) *input_line_pointer])
+       ++input_line_pointer;
+
+      if (current_cframe == NULL)
+       return;
+    }
+  else
+    {
+      expressionS operand;
+      int t;
+
+      /* Leading whitespace is part of operand.  */
+      SKIP_WHITESPACE ();
+
+      expression (&operand);
+      if (operand.X_op != O_constant)
+       as_bad (_("non-constant expression in \".elseif\" statement"));
+
+      switch ((operatorT) arg)
+       {
+       case O_eq: t = operand.X_add_number == 0; break;
+       case O_ne: t = operand.X_add_number != 0; break;
+       case O_lt: t = operand.X_add_number < 0; break;
+       case O_le: t = operand.X_add_number <= 0; break;
+       case O_ge: t = operand.X_add_number >= 0; break;
+       case O_gt: t = operand.X_add_number > 0; break;
+       default:
+         abort ();
+         return;
+       }
+
+      current_cframe->ignoring = current_cframe->dead_tree || ! t;
+    }
+
+  if (LISTING_SKIP_COND ()
+      && (current_cframe->previous_cframe == NULL
+         || ! current_cframe->previous_cframe->ignoring))
+    {
+      if (! current_cframe->ignoring)
+       listing_list (1);
+      else
+       listing_list (2);
+    }
+
+  demand_empty_rest_of_line ();
+}
+
+void
 s_endif (arg)
      int arg ATTRIBUTE_UNUSED;
 {
 s_endif (arg)
      int arg ATTRIBUTE_UNUSED;
 {
@@ -276,20 +375,19 @@ s_endif (arg)
     }
 
   demand_empty_rest_of_line ();
     }
 
   demand_empty_rest_of_line ();
-}                              /* s_endif() */
+}
 
 
-void 
+void
 s_else (arg)
      int arg ATTRIBUTE_UNUSED;
 {
   if (current_cframe == NULL)
     {
 s_else (arg)
      int arg ATTRIBUTE_UNUSED;
 {
   if (current_cframe == NULL)
     {
-      as_bad (_(".else without matching .if - ignored"));
-
+      as_bad (_("\".else\" without matching \".if\""));
     }
   else if (current_cframe->else_seen)
     {
     }
   else if (current_cframe->else_seen)
     {
-      as_bad (_("duplicate \"else\" - ignored"));
+      as_bad (_("duplicate \"else\""));
       as_bad_where (current_cframe->else_file_line.file,
                    current_cframe->else_file_line.line,
                    _("here is the previous \"else\""));
       as_bad_where (current_cframe->else_file_line.file,
                    current_cframe->else_file_line.line,
                    _("here is the previous \"else\""));
@@ -302,20 +400,21 @@ s_else (arg)
       as_where (&current_cframe->else_file_line.file,
                &current_cframe->else_file_line.line);
 
       as_where (&current_cframe->else_file_line.file,
                &current_cframe->else_file_line.line);
 
-      if (!current_cframe->dead_tree)
+      current_cframe->ignoring =
+       current_cframe->dead_tree | !current_cframe->ignoring;
+
+      if (LISTING_SKIP_COND ()
+         && (current_cframe->previous_cframe == NULL
+             || ! current_cframe->previous_cframe->ignoring))
        {
        {
-         current_cframe->ignoring = !current_cframe->ignoring;
-         if (LISTING_SKIP_COND ())
-           {
-             if (! current_cframe->ignoring)
-               listing_list (1);
-             else
-               listing_list (2);
-           }
-       }                       /* if not a dead tree */
+         if (! current_cframe->ignoring)
+           listing_list (1);
+         else
+           listing_list (2);
+       }
 
       current_cframe->else_seen = 1;
 
       current_cframe->else_seen = 1;
-    }                          /* if error else do it */
+    }
 
   if (flag_mri)
     {
 
   if (flag_mri)
     {
@@ -324,9 +423,9 @@ s_else (arg)
     }
 
   demand_empty_rest_of_line ();
     }
 
   demand_empty_rest_of_line ();
-}                              /* s_else() */
+}
 
 
-void 
+void
 s_ifeqs (arg)
      int arg;
 {
 s_ifeqs (arg)
      int arg;
 {
@@ -363,20 +462,16 @@ s_ifeqs (arg)
     listing_list (2);
 
   demand_empty_rest_of_line ();
     listing_list (2);
 
   demand_empty_rest_of_line ();
-}                              /* s_ifeqs() */
+}
 
 
-int 
+int
 ignore_input ()
 {
   char *s;
 
   s = input_line_pointer;
 
 ignore_input ()
 {
   char *s;
 
   s = input_line_pointer;
 
-  if (flag_m68k_mri
-#ifdef NO_PSEUDO_DOT
-      || 1
-#endif
-      )
+  if (NO_PSEUDO_DOT || flag_m68k_mri)
     {
       if (s[-1] != '.')
        --s;
     {
       if (s[-1] != '.')
        --s;
@@ -401,9 +496,9 @@ ignore_input ()
     return 0;
 
   return (current_cframe != NULL) && (current_cframe->ignoring);
     return 0;
 
   return (current_cframe != NULL) && (current_cframe->ignoring);
-}                              /* ignore_input() */
+}
 
 
-static void 
+static void
 initialize_cframe (cframe)
      struct conditional_frame *cframe;
 {
 initialize_cframe (cframe)
      struct conditional_frame *cframe;
 {
@@ -457,5 +552,3 @@ cond_exit_macro (nest)
       obstack_free (&cond_obstack, hold);
     }
 }
       obstack_free (&cond_obstack, hold);
     }
 }
-
-/* end of cond.c */
This page took 0.031455 seconds and 4 git commands to generate.