示例#1
0
static const struct line_map*
first_map_in_common_1 (struct line_maps *set,
		       source_location *loc0,
		       source_location *loc1)
{
  source_location l0 = *loc0, l1 = *loc1;
  const struct line_map *map0 = linemap_lookup (set, l0),
    *map1 = linemap_lookup (set, l1);

  while (linemap_macro_expansion_map_p (map0)
	 && linemap_macro_expansion_map_p (map1)
	 && (map0 != map1))
    {
      if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
	{
	  l0 = linemap_macro_map_loc_to_exp_point (map0, l0);
	  map0 = linemap_lookup (set, l0);
	}
      else
	{
	  l1 = linemap_macro_map_loc_to_exp_point (map1, l1);
	  map1 = linemap_lookup (set, l1);
	}
    }

  if (map0 == map1)
    {
      *loc0 = l0;
      *loc1 = l1;
      return map0;
    }
  return NULL;
}
示例#2
0
/* Print the logical file location (LINE, COL) in preparation for a
   diagnostic.  Outputs the #include chain if it has changed.  A line
   of zero suppresses the include stack, and outputs the program name
   instead.  */
static void
print_location (cpp_reader *pfile, source_location line, unsigned int col)
{
  if (line == 0)
    fprintf (stderr, "%s: ", progname);
  else
    {
      const struct line_map *map;
      linenum_type lin;

      map = linemap_lookup (pfile->line_table, line);
      linemap_print_containing_files (pfile->line_table, map);

      lin = SOURCE_LINE (map, line);
      if (col == 0)
	{
	  col = SOURCE_COLUMN (map, line);
	  if (col == 0)
	    col = 1;
	}

      if (lin == 0)
	fprintf (stderr, "%s:", map->to_file);
      else if (CPP_OPTION (pfile, show_column) == 0)
	fprintf (stderr, "%s:%u:", map->to_file, lin);
      else
	fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);

      fputc (' ', stderr);
    }
}
/* Helper function for cb_line_change and scan_translation_unit.  */
static void
do_line_change (cpp_reader *pfile, const cpp_token *token,
		source_location src_loc, int parsing_args)
{
  if (define_queue || undef_queue)
    dump_queued_macros (pfile);

  if (token->type == CPP_EOF || parsing_args)
    return;

  maybe_print_line (src_loc);
  print.prev = 0;
  print.source = 0;

  /* Supply enough spaces to put this token in its original column,
     one space per column greater than 2, since scan_translation_unit
     will provide a space if PREV_WHITE.  Don't bother trying to
     reconstruct tabs; we can't get it right in general, and nothing
     ought to care.  Some things do care; the fault lies with them.  */
  if (!CPP_OPTION (pfile, traditional))
    {
      const struct line_map *map = linemap_lookup (line_table, src_loc);
      int spaces = SOURCE_COLUMN (map, src_loc) - 2;
      print.printed = 1;

      while (-- spaces >= 0)
	putc (' ', print.outf);
    }
}
示例#4
0
/* #define callback for DWARF and DWARF2 debug info.  */
static void
cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
{
  const struct line_map *map = linemap_lookup (&line_table, loc);
  (*debug_hooks->define) (SOURCE_LINE (map, loc),
			  (const char *) cpp_macro_definition (pfile, node));
}
/* If the token read on logical line LINE needs to be output on a
   different line to the current one, output the required newlines or
   a line marker, and return 1.  Otherwise return 0.  */
static void
maybe_print_line (source_location src_loc)
{
  const struct line_map *map = linemap_lookup (line_table, src_loc);
  int src_line = SOURCE_LINE (map, src_loc);
  /* End the previous line of text.  */
  if (print.printed)
    {
      putc ('\n', print.outf);
      print.src_line++;
      print.printed = 0;
    }

  if (!flag_no_line_commands
      && src_line >= print.src_line
      && src_line < print.src_line + 8
      && strcmp (map->to_file, print.src_file) == 0)
    {
      while (src_line > print.src_line)
	{
	  putc ('\n', print.outf);
	  print.src_line++;
	}
    }
  else
    print_line (src_loc, "");
}
示例#6
0
/* If LOC is the virtual location of a token coming from the expansion
   of a macro M and if its spelling location is reserved (e.g, a
   location for a built-in token), then this function unwinds (using
   linemap_unwind_toward_expansion) the location until a location that
   is not reserved and is not in a system header is reached.  In other
   words, this unwinds the reserved location until a location that is
   in real source code is reached.

   Otherwise, if the spelling location for LOC is not reserved or if
   LOC doesn't come from the expansion of a macro, the function
   returns LOC as is and *MAP is not touched.

   *MAP is set to the map of the returned location if the later is
   different from LOC.  */
source_location
linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
					  source_location loc,
					  const struct line_map **map)
{
  source_location resolved_loc;
  const struct line_map *map0 = NULL, *map1 = NULL;

  map0 = linemap_lookup (set, loc);
  if (!linemap_macro_expansion_map_p (map0))
    return loc;

  resolved_loc = linemap_resolve_location (set, loc,
					   LRK_SPELLING_LOCATION,
					   &map1);

  if (resolved_loc >= RESERVED_LOCATION_COUNT
      && !LINEMAP_SYSP (map1))
    return loc;

  while (linemap_macro_expansion_map_p (map0)
	 && (resolved_loc < RESERVED_LOCATION_COUNT
	     || LINEMAP_SYSP (map1)))
    {
      loc = linemap_unwind_toward_expansion (set, loc, &map0);
      resolved_loc = linemap_resolve_location (set, loc,
					       LRK_SPELLING_LOCATION,
					       &map1);
    }

  if (map != NULL)
    *map = map0;
  return loc;
}
示例#7
0
static void
cb_def_pragma (cpp_reader *pfile, source_location loc)
{
  /* Issue a warning message if we have been asked to do so.  Ignore
     unknown pragmas in system headers unless an explicit
     -Wunknown-pragmas has been given.  */
  if (warn_unknown_pragmas > in_system_header)
    {
      const unsigned char *space, *name;
      const cpp_token *s;
#ifndef USE_MAPPED_LOCATION
      location_t fe_loc;
      const struct line_map *map = linemap_lookup (&line_table, loc);
      fe_loc.file = map->to_file;
      fe_loc.line = SOURCE_LINE (map, loc);
#else
      location_t fe_loc = loc;
#endif

      space = name = (const unsigned char *) "";
      s = cpp_get_token (pfile);
      if (s->type != CPP_EOF)
	{
	  space = cpp_token_as_text (pfile, s);
	  s = cpp_get_token (pfile);
	  if (s->type == CPP_NAME)
	    name = cpp_token_as_text (pfile, s);
	}

      warning (OPT_Wunknown_pragmas, "%Hignoring #pragma %s %s",
	       &fe_loc, space, name);
    }
}
示例#8
0
/* Output a line marker for logical line LINE.  Special flags are "1"
   or "2" indicating entering or leaving a file.  */
static void
print_line (source_location src_loc, const char *special_flags)
{
  /* End any previous line of text.  */
  if (print.printed)
    putc ('\n', print.outf);
  print.printed = 0;

  if (!flag_no_line_commands)
    {
      const struct line_map *map = linemap_lookup (&line_table, src_loc);

      size_t to_file_len = strlen (map->to_file);
      unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
      unsigned char *p;

      print.src_line = SOURCE_LINE (map, src_loc);

      /* cpp_quote_string does not nul-terminate, so we have to do it
	 ourselves.  */
      p = cpp_quote_string (to_file_quoted,
			    (unsigned char *) map->to_file, to_file_len);
      *p = '\0';
      fprintf (print.outf, "# %u \"%s\"%s", print.src_line,
	       to_file_quoted, special_flags);

      if (map->sysp == 2)
	fputs (" 3 4", print.outf);
      else if (map->sysp == 1)
	fputs (" 3", print.outf);

      putc ('\n', print.outf);
    }
}
示例#9
0
/* #undef callback for DWARF and DWARF2 debug info.  */
static void
cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
	  cpp_hashnode *node)
{
  const struct line_map *map = linemap_lookup (&line_table, loc);
  (*debug_hooks->undef) (SOURCE_LINE (map, loc),
			 (const char *) NODE_NAME (node));
}
示例#10
0
source_location
linemap_unwind_toward_expansion (struct line_maps *set,
				 source_location loc,
				 const struct line_map **map)
{
  source_location resolved_location;
  const struct line_map *resolved_map;

  resolved_location =
    linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
  resolved_map = linemap_lookup (set, resolved_location);

  if (!linemap_macro_expansion_map_p (resolved_map))
    {
      resolved_location = linemap_macro_map_loc_to_exp_point (*map, loc);
      resolved_map = linemap_lookup (set, resolved_location);
    }

  *map = resolved_map;
  return resolved_location;
}
示例#11
0
/* Print the logical file location (LINE, COL) in preparation for a
   diagnostic.  Outputs the #include chain if it has changed.  A line
   of zero suppresses the include stack, and outputs the program name
   instead.  */
static void
print_location (cpp_reader *pfile, source_location line, unsigned int col)
{
  /* APPLE LOCAL begin error-colon */
  const char *estr;
  {
    static int done = 0;
    if ( ! done)
      {
        done = 1;       /* Do this only once.  */
        /* Pretend we saw "-w" on commandline.  */
        if (getenv ("GCC_DASH_W"))
          CPP_OPTION (pfile, inhibit_warnings) = 1; /* referenced by diagnostic.h:diagnostic_report_warnings() */
        if (getenv ("GCC_ERROR_COLON"))
          gcc_error_colon = 1;
      }
  }
  estr = (gcc_error_colon) ? "error:" : "" ;
  /* APPLE LOCAL end error-colon */

  if (line == 0)
    fprintf (stderr, "%s: ", progname);
  else
    {
      const struct line_map *map;
      unsigned int lin;

      map = linemap_lookup (pfile->line_table, line);
      linemap_print_containing_files (pfile->line_table, map);

      lin = SOURCE_LINE (map, line);
      if (col == 0)
	{
	  col = SOURCE_COLUMN (map, line);
	  if (col == 0)
	    col = 1;
	}

      /* APPLE LOCAL begin error-colon */
      if (lin == 0)
        fprintf (stderr, "%s:%s", map->to_file, estr);
      else if (CPP_OPTION (pfile, show_column) == 0)
        fprintf (stderr, "%s:%u:%s", map->to_file, lin, estr);
      else
        fprintf (stderr, "%s:%u:%u:%s", map->to_file, lin, col, estr);
      /* APPLE LOCAL end error-colon */

      fputc (' ', stderr);
    }
}
示例#12
0
/* Called at the start of every non-empty line.  TOKEN is the first
   lexed token on the line.  Used for diagnostic line numbers.  */
static void
cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token,
		int parsing_args)
{
  if (token->type != CPP_EOF && !parsing_args)
#ifdef USE_MAPPED_LOCATION
    input_location = token->src_loc;
#else
    {
      source_location loc = token->src_loc;
      const struct line_map *map = linemap_lookup (&line_table, loc);
      input_line = SOURCE_LINE (map, loc);
    }
#endif
}
static source_location
get_loc (unsigned int line_num, unsigned int col_num)
{
  /* Use input_location to get the relevant line_map */
  const struct line_map_ordinary *line_map
    = (const line_map_ordinary *)(linemap_lookup (line_table,
						  input_location));

  /* Convert from 0-based column numbers to 1-based column numbers.  */
  source_location loc
    = linemap_position_for_line_and_column (line_map,
					    line_num, col_num + 1);

  return loc;
}
示例#14
0
void
diagnostic_report_current_module (diagnostic_context *context)
{
  const struct line_map *map;

  if (pp_needs_newline (context->printer))
    {
      pp_newline (context->printer);
      pp_needs_newline (context->printer) = false;
    }

  if (input_location <= BUILTINS_LOCATION)
    return;

  map = linemap_lookup (line_table, input_location);
  if (map && diagnostic_last_module_changed (context, map))
    {
      diagnostic_set_last_module (context, map);
      if (! MAIN_FILE_P (map))
	{
	  map = INCLUDED_FROM (line_table, map);
	  if (flag_show_column)
	    pp_verbatim (context->printer,
			 "In file included from %s:%d:%d",
			 map->to_file,
			 LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map));
	  else
	    pp_verbatim (context->printer,
			 "In file included from %s:%d",
			 map->to_file, LAST_SOURCE_LINE (map));
	  while (! MAIN_FILE_P (map))
	    {
	      map = INCLUDED_FROM (line_table, map);
	      pp_verbatim (context->printer,
			   ",\n                 from %s:%d",
			   map->to_file, LAST_SOURCE_LINE (map));
	    }
	  pp_verbatim (context->printer, ":");
	  pp_newline (context->printer);
	}
    }
}
示例#15
0
static source_location
linemap_macro_loc_to_exp_point (struct line_maps *set,
				source_location location,
				const struct line_map **original_map)
{
  struct line_map *map;

  linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

  while (true)
    {
      map = (struct line_map*) linemap_lookup (set, location);
      if (!linemap_macro_expansion_map_p (map))
	break;
      location = linemap_macro_map_loc_to_exp_point (map, location);
    }

  if (original_map)
    *original_map = map;
  return location;
}
示例#16
0
int
linemap_location_in_system_header_p (struct line_maps *set,
				     source_location location)
{
  const struct line_map *map = NULL;

  if (location < RESERVED_LOCATION_COUNT)
    return false;

  /* Let's look at where the token for LOCATION comes from.  */
  while (true)
    {
      map = linemap_lookup (set, location);
      if (map != NULL)
	{
	  if (!linemap_macro_expansion_map_p (map))
	    /* It's a normal token.  */
	    return LINEMAP_SYSP (map);
	  else
	    {
	      /* It's a token resulting from a macro expansion.  */
	      source_location loc =
		linemap_macro_map_loc_unwind_toward_spelling (map, location);
	      if (loc < RESERVED_LOCATION_COUNT)
		/* This token might come from a built-in macro.  Let's
		   look at where that macro got expanded.  */
		location = linemap_macro_map_loc_to_exp_point (map, location);
	      else
		location = loc;
	    }
	}
      else
	break;
    }
  return false;
}
/* Writes out the preprocessed file, handling spacing and paste
   avoidance issues.  */
static void
scan_translation_unit (cpp_reader *pfile)
{
  bool avoid_paste = false;
  bool do_line_adjustments
    = cpp_get_options (parse_in)->lang != CLK_ASM
      && !flag_no_line_commands;
  bool in_pragma = false;

  print.source = NULL;
  for (;;)
    {
      source_location loc;
      const cpp_token *token = cpp_get_token_with_location (pfile, &loc);

      if (token->type == CPP_PADDING)
	{
	  avoid_paste = true;
	  if (print.source == NULL
	      || (!(print.source->flags & PREV_WHITE)
		  && token->val.source == NULL))
	    print.source = token->val.source;
	  continue;
	}

      if (token->type == CPP_EOF)
	break;

      /* Subtle logic to output a space if and only if necessary.  */
      if (avoid_paste)
	{
	  const struct line_map *map
	    = linemap_lookup (line_table, loc);
	  int src_line = SOURCE_LINE (map, loc);

	  if (print.source == NULL)
	    print.source = token;

	  if (src_line != print.src_line
	      && do_line_adjustments
	      && !in_pragma)
	    {
	      do_line_change (pfile, token, loc, false);
	      putc (' ', print.outf);
	    }
	  else if (print.source->flags & PREV_WHITE
		   || (print.prev
		       && cpp_avoid_paste (pfile, print.prev, token))
		   || (print.prev == NULL && token->type == CPP_HASH))
	    putc (' ', print.outf);
	}
      else if (token->flags & PREV_WHITE)
	{
	  const struct line_map *map
	    = linemap_lookup (line_table, loc);
	  int src_line = SOURCE_LINE (map, loc);

	  if (src_line != print.src_line
	      && do_line_adjustments
	      && !in_pragma)
	    do_line_change (pfile, token, loc, false);
	  putc (' ', print.outf);
	}

      avoid_paste = false;
      print.source = NULL;
      print.prev = token;
      if (token->type == CPP_PRAGMA)
	{
	  const char *space;
	  const char *name;

	  maybe_print_line (token->src_loc);
	  fputs ("#pragma ", print.outf);
	  c_pp_lookup_pragma (token->val.pragma, &space, &name);
	  if (space)
	    fprintf (print.outf, "%s %s", space, name);
	  else
	    fprintf (print.outf, "%s", name);
	  print.printed = 1;
	  in_pragma = true;
	}
      else if (token->type == CPP_PRAGMA_EOL)
	{
	  maybe_print_line (token->src_loc);
	  in_pragma = false;
	}
      else
	cpp_output_token (token, print.outf);

      if (token->type == CPP_COMMENT)
	account_for_newlines (token->val.str.text, token->val.str.len);
    }
}