[Ada] Consistently use explicit Entity_Id type instead of alias
[gcc.git] / libcpp / macro.c
index dc4366ffefd36fd663262340249ba7aba2e77654..05755859cd68d1782d9fdb28cc8e953cf845c008 100644 (file)
@@ -268,6 +268,8 @@ class vaopt_state {
 
 /* Macro expansion.  */
 
+static cpp_macro *get_deferred_or_lazy_macro (cpp_reader *, cpp_hashnode *,
+                                             location_t);
 static int enter_macro_context (cpp_reader *, cpp_hashnode *,
                                const cpp_token *, location_t);
 static int builtin_macro (cpp_reader *, cpp_hashnode *,
@@ -338,8 +340,6 @@ static cpp_macro *create_iso_definition (cpp_reader *);
 /* #define directive parsing and handling.  */
 
 static cpp_macro *lex_expansion_token (cpp_reader *, cpp_macro *);
-static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *,
-                                 const cpp_macro *);
 static bool parse_params (cpp_reader *, unsigned *, bool *);
 static void check_trad_stringification (cpp_reader *, const cpp_macro *,
                                        const cpp_string *);
@@ -351,8 +351,6 @@ static const cpp_token* cpp_get_token_1 (cpp_reader *, location_t *);
 
 static cpp_hashnode* macro_of_context (cpp_context *context);
 
-static bool in_macro_expansion_p (cpp_reader *pfile);
-
 /* Statistical counter tracking the number of macros that got
    expanded.  */
 unsigned num_expanded_macros_counter = 0;
@@ -586,7 +584,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
         (c) we are not in strictly conforming mode, then it has the
         value 0.  (b) and (c) are already checked in cpp_init_builtins.  */
     case BT_STDC:
-      if (cpp_in_system_header (pfile))
+      if (_cpp_in_system_header (pfile))
        number = 0;
       else
        number = 1;
@@ -604,29 +602,21 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
             at init time, because time() and localtime() are very
             slow on some systems.  */
          time_t tt;
-         struct tm *tb = NULL;
-
-         /* Set a reproducible timestamp for __DATE__ and __TIME__ macro
-            if SOURCE_DATE_EPOCH is defined.  */
-         if (pfile->source_date_epoch == (time_t) -2
-             && pfile->cb.get_source_date_epoch != NULL)
-           pfile->source_date_epoch = pfile->cb.get_source_date_epoch (pfile);
+         auto kind = cpp_get_date (pfile, &tt);
 
-         if (pfile->source_date_epoch >= (time_t) 0)
-           tb = gmtime (&pfile->source_date_epoch);
-         else
+         if (kind == CPP_time_kind::UNKNOWN)
            {
-             /* (time_t) -1 is a legitimate value for "number of seconds
-                since the Epoch", so we have to do a little dance to
-                distinguish that from a genuine error.  */
-             errno = 0;
-             tt = time (NULL);
-             if (tt != (time_t)-1 || errno == 0)
-               tb = localtime (&tt);
+             cpp_errno (pfile, CPP_DL_WARNING,
+                        "could not determine date and time");
+               
+             pfile->date = UC"\"??? ?? ????\"";
+             pfile->time = UC"\"??:??:??\"";
            }
-
-         if (tb)
+         else
            {
+             struct tm *tb = (kind == CPP_time_kind::FIXED
+                              ? gmtime : localtime) (&tt);
+
              pfile->date = _cpp_unaligned_alloc (pfile,
                                                  sizeof ("\"Oct 11 1347\""));
              sprintf ((char *) pfile->date, "\"%s %2d %4d\"",
@@ -638,14 +628,6 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
              sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"",
                       tb->tm_hour, tb->tm_min, tb->tm_sec);
            }
-         else
-           {
-             cpp_errno (pfile, CPP_DL_WARNING,
-                        "could not determine date and time");
-               
-             pfile->date = UC"\"??? ?? ????\"";
-             pfile->time = UC"\"??:??:??\"";
-           }
        }
 
       if (node->value.builtin == BT_DATE)
@@ -662,7 +644,11 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
       break;
 
     case BT_HAS_ATTRIBUTE:
-      number = pfile->cb.has_attribute (pfile);
+      number = pfile->cb.has_attribute (pfile, false);
+      break;
+
+    case BT_HAS_STD_ATTRIBUTE:
+      number = pfile->cb.has_attribute (pfile, true);
       break;
 
     case BT_HAS_BUILTIN:
@@ -686,6 +672,51 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
   return result;      
 }
 
+/* Get an idempotent date.  Either the cached value, the value from
+   source epoch, or failing that, the value from time(2).  Use this
+   during compilation so that every time stamp is the same.  */
+CPP_time_kind
+cpp_get_date (cpp_reader *pfile, time_t *result)
+{
+  if (!pfile->time_stamp_kind)
+    {
+      int kind = 0;
+      if (pfile->cb.get_source_date_epoch)
+       {
+         /* Try reading the fixed epoch.  */
+         pfile->time_stamp = pfile->cb.get_source_date_epoch (pfile);
+         if (pfile->time_stamp != time_t (-1))
+           kind = int (CPP_time_kind::FIXED);
+       }
+
+      if (!kind)
+       {
+         /* Pedantically time_t (-1) is a legitimate value for
+            "number of seconds since the Epoch".  It is a silly
+            time.   */
+         errno = 0;
+         pfile->time_stamp = time (nullptr);
+         /* Annoyingly a library could legally set errno and return a
+            valid time!  Bad library!  */
+         if (pfile->time_stamp == time_t (-1) && errno)
+           kind = errno;
+         else
+           kind = int (CPP_time_kind::DYNAMIC);
+       }
+
+      pfile->time_stamp_kind = kind;
+    }
+
+  *result = pfile->time_stamp;
+  if (pfile->time_stamp_kind >= 0)
+    {
+      errno = pfile->time_stamp_kind;
+      return CPP_time_kind::UNKNOWN;
+    }
+
+  return CPP_time_kind (pfile->time_stamp_kind);
+}
+
 /* Convert builtin macros like __FILE__ to a token and push it on the
    context stack.  Also handles _Pragma, for which a new token may not
    be created.  Returns 1 if it generates a new token context, 0 to
@@ -1241,7 +1272,8 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node,
        ntokens--;
 
       arg->count = ntokens;
-      set_arg_token (arg, &pfile->eof, pfile->eof.src_loc,
+      /* Append an EOF to mark end-of-argument.  */
+      set_arg_token (arg, &pfile->endarg, token->src_loc,
                     ntokens, MACRO_ARG_TOKEN_NORMAL,
                     CPP_OPTION (pfile, track_macro_expansion));
 
@@ -1258,11 +1290,10 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node,
 
   if (token->type == CPP_EOF)
     {
-      /* We still need the CPP_EOF to end directives, and to end
-        pre-expansion of a macro argument.  Step back is not
-        unconditional, since we don't want to return a CPP_EOF to our
-        callers at the end of an -include-d file.  */
-      if (pfile->context->prev || pfile->state.in_directive)
+      /* Unless the EOF is marking the end of an argument, it's a fake
+        one from the end of a file that _cpp_clean_line will not have
+        advanced past.  */
+      if (token == &pfile->endarg)
        _cpp_backup_tokens (pfile, 1);
       cpp_error (pfile, CPP_DL_ERROR,
                 "unterminated argument list invoking macro \"%s\"",
@@ -1325,14 +1356,15 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
       pfile->state.parsing_args = 2;
       return collect_args (pfile, node, pragma_buff, num_args);
     }
-
-  /* CPP_EOF can be the end of macro arguments, or the end of the
-     file.  We mustn't back up over the latter.  Ugh.  */
-  if (token->type != CPP_EOF || token == &pfile->eof)
+  
+  /* Back up.  A CPP_EOF is either an EOF from an argument we're
+     expanding, or a fake one from lex_direct.  We want to backup the
+     former, but not the latter.  We may have skipped padding, in
+     which case backing up more than one token when expanding macros
+     is in general too difficult.  We re-insert it in its own
+     context.  */
+  if (token->type != CPP_EOF || token == &pfile->endarg)
     {
-      /* Back up.  We may have skipped padding, in which case backing
-        up more than one token when expanding macros is in general
-        too difficult.  We re-insert it in its own context.  */
       _cpp_backup_tokens (pfile, 1);
       if (padding)
        _cpp_push_token_context (pfile, NULL, padding, 1);
@@ -1432,7 +1464,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
 
       /* Laziness can only affect the expansion tokens of the macro,
         not its fun-likeness or parameters.  */
-      _cpp_maybe_notify_macro_use (pfile, node);
+      _cpp_maybe_notify_macro_use (pfile, node, location);
       if (pfile->cb.used)
        pfile->cb.used (pfile, location, node);
 
@@ -2181,7 +2213,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
              = (const cpp_token **) tokens_buff_last_token_ptr (buff);
        }
       else if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99)
-              && ! macro->syshdr && ! cpp_in_system_header (pfile))
+              && ! macro->syshdr && ! _cpp_in_system_header (pfile))
        {
          if (CPP_OPTION (pfile, cplusplus))
            cpp_pedwarning (pfile, CPP_W_PEDANTIC,
@@ -2200,7 +2232,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
        }
       else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
               && ! CPP_OPTION (pfile, cplusplus)
-              && ! macro->syshdr && ! cpp_in_system_header (pfile))
+              && ! macro->syshdr && ! _cpp_in_system_header (pfile))
        cpp_warning (pfile, CPP_W_C90_C99_COMPAT,
                     "invoking macro %s argument %d: "
                     "empty macro arguments are undefined"
@@ -2640,8 +2672,7 @@ _cpp_pop_context (cpp_reader *pfile)
   cpp_context *context = pfile->context;
 
   /* We should not be popping the base context.  */
-  if (context == &pfile->base_context)
-    abort ();
+  gcc_assert (context != &pfile->base_context);
 
   if (context->c.macro)
     {
@@ -2843,6 +2874,12 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
       if (node->type == NT_VOID || (result->flags & NO_EXPAND))
        break;
 
+      if (!(node->flags & NODE_USED)
+         && node->type == NT_USER_MACRO
+         && !node->value.macro
+         && !cpp_get_deferred_macro (pfile, node, result->src_loc))
+       break;
+
       if (!(node->flags & NODE_DISABLED))
        {
          int ret = 0;
@@ -2870,8 +2907,7 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
                                      || (peek_tok->flags & PREV_WHITE));
                  node = pfile->cb.macro_to_expand (pfile, result);
                  if (node)
-                   ret = enter_macro_context (pfile, node, result,
-                                              virt_loc);
+                   ret = enter_macro_context (pfile, node, result, virt_loc);
                  else if (whitespace_after)
                    {
                      /* If macro_to_expand hook returned NULL and it
@@ -2888,8 +2924,7 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
                }
            }
          else
-           ret = enter_macro_context (pfile, node, result, 
-                                      virt_loc);
+           ret = enter_macro_context (pfile, node, result, virt_loc);
          if (ret)
            {
              if (pfile->state.in_directive || ret == 2)
@@ -2930,6 +2965,85 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
     }
 
   pfile->about_to_expand_macro_p = saved_about_to_expand_macro;
+
+  if (pfile->state.directive_file_token
+      && !pfile->state.parsing_args
+      && !(result->type == CPP_PADDING || result->type == CPP_COMMENT)
+      && !(15 & --pfile->state.directive_file_token))
+    {
+      /* Do header-name frobbery.  Concatenate < ... > as approprate.
+        Do header search if needed, and finally drop the outer <> or
+        "".  */
+      pfile->state.angled_headers = false;
+
+      /* Do angle-header reconstitution.  Then do include searching.
+        We'll always end up with a ""-quoted header-name in that
+        case.  If searching finds nothing, we emit a diagnostic and
+        an empty string.  */
+      size_t len = 0;
+      char *fname = NULL;
+
+      cpp_token *tmp = _cpp_temp_token (pfile);
+      *tmp = *result;
+
+      tmp->type = CPP_HEADER_NAME;
+      bool need_search = !pfile->state.directive_file_token;
+      pfile->state.directive_file_token = 0;
+
+      bool angle = result->type != CPP_STRING;
+      if (result->type == CPP_HEADER_NAME
+         || (result->type == CPP_STRING && result->val.str.text[0] != 'R'))
+       {
+         len = result->val.str.len - 2;
+         fname = XNEWVEC (char, len + 1);
+         memcpy (fname, result->val.str.text + 1, len);
+         fname[len] = 0;
+       }
+      else if (result->type == CPP_LESS)
+       fname = _cpp_bracket_include (pfile);
+
+      if (fname)
+       {
+         /* We have a header-name.  Look it up.  This will emit an
+            unfound diagnostic.  Canonicalize the found name.  */
+         const char *found = fname;
+
+         if (need_search)
+           {
+             found = cpp_find_header_unit (pfile, fname, angle, tmp->src_loc);
+             if (!found)
+               found = "";
+             len = strlen (found);
+           }
+         /* Force a leading './' if it's not absolute.  */
+         bool dotme = (found[0] == '.' ? !IS_DIR_SEPARATOR (found[1])
+                       : found[0] && !IS_ABSOLUTE_PATH (found));
+
+         if (BUFF_ROOM (pfile->u_buff) < len + 1 + dotme * 2)
+           _cpp_extend_buff (pfile, &pfile->u_buff, len + 1 + dotme * 2);
+         unsigned char *buf = BUFF_FRONT (pfile->u_buff);
+         size_t pos = 0;
+             
+         if (dotme)
+           {
+             buf[pos++] = '.';
+             /* Apparently '/' is unconditional.  */
+             buf[pos++] = '/';
+           }
+         memcpy (&buf[pos], found, len);
+         pos += len;
+         buf[pos] = 0;
+
+         tmp->val.str.len = pos;
+         tmp->val.str.text = buf;
+
+         tmp->type = CPP_HEADER_NAME;
+         XDELETEVEC (fname);
+         
+         result = tmp;
+       }
+    }
+
   return result;
 }
 
@@ -3104,15 +3218,16 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
   if (node->flags & NODE_CONDITIONAL)
     return false;
 
-  cpp_macro *macro1 = node->value.macro;
-  if (macro1->lazy)
-    {
-      /* We don't want to mark MACRO as used, but do need to finalize
-        its laziness.  */
-      pfile->cb.user_lazy_macro (pfile, macro1, macro1->lazy - 1);
-      macro1->lazy = 0;
-    }
+  if (cpp_macro *macro1 = get_deferred_or_lazy_macro (pfile, node, macro2->line))
+    return cpp_compare_macros (macro1, macro2);
+  return false;
+}
+
+/* Return TRUE if MACRO1 and MACRO2 differ.  */
 
+bool
+cpp_compare_macros (const cpp_macro *macro1, const cpp_macro *macro2)
+{
   /* Redefinition of a macro is allowed if and only if the old and new
      definitions are the same.  (6.10.3 paragraph 2).  */
 
@@ -3581,6 +3696,10 @@ _cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement)
 {
   cpp_macro *macro = (cpp_macro *) placement;
 
+  /* Zero init all the fields.  This'll tell the compiler know all the
+     following inits are writing a virgin object.  */
+  memset (macro, 0, offsetof (cpp_macro, exp));
+
   macro->line = pfile->directive_line;
   macro->parm.params = 0;
   macro->lazy = 0;
@@ -3666,39 +3785,72 @@ cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
   macro->lazy = num + 1;
 }
 
+/* NODE is a deferred macro, resolve it, returning the definition
+   (which may be NULL).  */
+cpp_macro *
+cpp_get_deferred_macro (cpp_reader *pfile, cpp_hashnode *node,
+                       location_t loc)
+{
+  node->value.macro = pfile->cb.user_deferred_macro (pfile, loc, node);
+
+  if (!node->value.macro)
+    node->type = NT_VOID;
+
+  return node->value.macro;
+}
+
+static cpp_macro *
+get_deferred_or_lazy_macro (cpp_reader *pfile, cpp_hashnode *node,
+                           location_t loc)
+{
+  cpp_macro *macro = node->value.macro;
+  if (!macro)
+    {
+      macro = cpp_get_deferred_macro (pfile, node, loc);
+      if (!macro)
+       return NULL;
+    }
+
+  if (macro->lazy)
+    {
+      pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1);
+      macro->lazy = 0;
+    }
+
+  return macro;
+}
+
 /* Notify the use of NODE in a macro-aware context (i.e. expanding it,
-   or testing its existance).  Also applies any lazy definition.  */
+   or testing its existance).  Also applies any lazy definition.
+   Return FALSE if the macro isn't really there.  */
 
-extern void
-_cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node)
+extern bool
+_cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
+                      location_t loc)
 {
   node->flags |= NODE_USED;
   switch (node->type)
     {
     case NT_USER_MACRO:
-      {
-       cpp_macro *macro = node->value.macro;
-       if (macro->lazy)
-         {
-           pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1);
-           macro->lazy = 0;
-         }
-      }
+      if (!get_deferred_or_lazy_macro (pfile, node, loc))
+       return false;
       /* FALLTHROUGH.  */
 
     case NT_BUILTIN_MACRO:
       if (pfile->cb.used_define)
-       pfile->cb.used_define (pfile, pfile->directive_line, node);
+       pfile->cb.used_define (pfile, loc, node);
       break;
 
     case NT_VOID:
       if (pfile->cb.used_undef)
-       pfile->cb.used_undef (pfile, pfile->directive_line, node);
+       pfile->cb.used_undef (pfile, loc, node);
       break;
 
     default:
       abort ();
     }
+
+  return true;
 }
 
 /* Warn if a token in STRING matches one of a function-like MACRO's
@@ -3751,12 +3903,19 @@ check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro,
 const unsigned char *
 cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
 {
-  unsigned int i, len;
-  unsigned char *buffer;
-
   gcc_checking_assert (cpp_user_macro_p (node));
 
-  const cpp_macro *macro = node->value.macro;
+  if (const cpp_macro *macro = get_deferred_or_lazy_macro (pfile, node, 0))
+    return cpp_macro_definition (pfile, node, macro);
+  return NULL;
+}
+
+const unsigned char *
+cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node,
+                     const cpp_macro *macro)
+{
+  unsigned int i, len;
+  unsigned char *buffer;
 
   /* Calculate length.  */
   len = NODE_LEN (node) * 10 + 2;              /* ' ' and NUL.  */