]> granicus.if.org Git - yasm/commitdiff
Implement some linemap changes required for the GAS preprocessor.
authorPeter Johnson <peter@tortall.net>
Sun, 3 Jan 2010 01:58:23 +0000 (01:58 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 3 Jan 2010 01:58:23 +0000 (01:58 -0000)
Contributed by: Alexei Svitkine <alexei.svitkine@gmail.com>

- yasm_linemap_set() now takes virtual_line as a parameter, instead of
always using linemap->current. If 0 is passed for the virtual_line,
then linemap->current is used, as before.

This is because linemap->current was only incremented by the parser
(and never decremented), so the preprocessor was not able to set
mappings during the preprocessing phase (whereas with these changes,
it now does).

Additionally, setting a mapping for a line number will now delete any
existing mappings for line numbers equal or greater to that line
number. This allows the code to correctly handle the case when the
preprocessor first sets mappings from pre-pp lines to post-pp lines,
and later those mappings getting superseded by .line directives in the
original source.

This change also required making a change to yasm_linemap_lookup() to
set *file_line to 0 when line is 0 (i.e. preventing line 0 - which
means "don't display line number in output" - from getting mapped).

svn path=/trunk/yasm/; revision=2259

frontends/tasm/tasm.c
frontends/yasm/yasm.c
libyasm/linemap.c
libyasm/linemap.h
modules/parsers/gas/gas-parse.c
modules/parsers/nasm/nasm-parse.c

index a8490b238c955e1eb8a12594ae41fb075cd49eb6..70f9573a5a20fbba5968ca18d06b77ba26c8c3a4 100644 (file)
@@ -267,7 +267,7 @@ do_assemble(void)
 
     /* Initialize line map */
     linemap = yasm_linemap_create();
-    yasm_linemap_set(linemap, in_filename, 1, 1);
+    yasm_linemap_set(linemap, in_filename, 0, 1, 1);
 
     /* determine the object filename if not specified */
     if (!obj_filename) {
index b8c1ac5953d3185a40cceec7c03afcfc3703a9c4..05d0dfe7de03e446298a791dd13adccfd2b957a2 100644 (file)
@@ -255,7 +255,7 @@ do_preproc_only(void)
 
     /* Initialize line map */
     linemap = yasm_linemap_create();
-    yasm_linemap_set(linemap, in_filename, 1, 1);
+    yasm_linemap_set(linemap, in_filename, 0, 1, 1);
 
     /* Default output to stdout if not specified or generating dependency
        makefiles */
@@ -359,7 +359,7 @@ do_assemble(void)
 
     /* Initialize line map */
     linemap = yasm_linemap_create();
-    yasm_linemap_set(linemap, in_filename, 1, 1);
+    yasm_linemap_set(linemap, in_filename, 0, 1, 1);
 
     /* determine the object filename if not specified */
     if (!obj_filename) {
index 926c3102d63a5f5b4a0ca95a2fc999df6c300906..abee748239d4a7a0cc67510fc9cd43254021b3a7 100644 (file)
@@ -80,22 +80,40 @@ filename_delete_one(/*@only@*/ void *d)
 
 void
 yasm_linemap_set(yasm_linemap *linemap, const char *filename,
-                 unsigned long file_line, unsigned long line_inc)
+                 unsigned long virtual_line, unsigned long file_line,
+                 unsigned long line_inc)
 {
     char *copy;
+    unsigned long i;
     int replace = 0;
-    line_mapping *mapping;
+    line_mapping *mapping = NULL;
 
-    /* Create a new mapping in the map */
-    if (linemap->map_size >= linemap->map_allocated) {
-        /* allocate another size bins when full for 2x space */
-        linemap->map_vector =
-            yasm_xrealloc(linemap->map_vector, 2*linemap->map_allocated
-                          *sizeof(line_mapping));
-        linemap->map_allocated *= 2;
+    if (virtual_line == 0) {
+        virtual_line = linemap->current;
+    }
+
+    /* Replace all existing mappings that have line numbers >= this one. */
+    for (i = linemap->map_size; i > 0; i--) {
+        if (linemap->map_vector[i-1].line < virtual_line) {
+            if (i < linemap->map_size) {
+                mapping = &linemap->map_vector[i];
+                linemap->map_size = i + 1;
+            }
+            break;
+        }
+    }
+
+    if (mapping == NULL) {
+        /* Create a new mapping in the map */
+        if (linemap->map_size >= linemap->map_allocated) {
+            /* allocate another size bins when full for 2x space */
+            linemap->map_vector = yasm_xrealloc(linemap->map_vector,
+                2*linemap->map_allocated*sizeof(line_mapping));
+            linemap->map_allocated *= 2;
+        }
+        mapping = &linemap->map_vector[linemap->map_size];
+        linemap->map_size++;
     }
-    mapping = &linemap->map_vector[linemap->map_size];
-    linemap->map_size++;
 
     /* Fill it */
 
@@ -115,7 +133,7 @@ yasm_linemap_set(yasm_linemap *linemap, const char *filename,
         /*@=aliasunique@*/
     }
 
-    mapping->line = linemap->current;
+    mapping->line = virtual_line;
     mapping->file_line = file_line;
     mapping->line_inc = line_inc;
 }
@@ -128,14 +146,14 @@ yasm_linemap_poke(yasm_linemap *linemap, const char *filename,
     line_mapping *mapping;
 
     linemap->current++;
-    yasm_linemap_set(linemap, filename, file_line, 0);
+    yasm_linemap_set(linemap, filename, 0, file_line, 0);
 
     mapping = &linemap->map_vector[linemap->map_size-1];
 
     line = linemap->current;
 
     linemap->current++;
-    yasm_linemap_set(linemap, mapping->filename,
+    yasm_linemap_set(linemap, mapping->filename, 0,
                      mapping->file_line +
                      mapping->line_inc*(linemap->current-2-mapping->line),
                      mapping->line_inc);
@@ -249,7 +267,7 @@ yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line,
     mapping = &linemap->map_vector[vindex];
 
     *filename = mapping->filename;
-    *file_line = mapping->file_line + mapping->line_inc*(line-mapping->line);
+    *file_line = (line ? mapping->file_line + mapping->line_inc*(line-mapping->line) : 0);
 }
 
 int
index 03912551b29c739936e15b79763d83bc1095dfa2..e916c6d05995087b5bf3ab175623c6c615dbea5b 100644 (file)
@@ -91,17 +91,19 @@ void yasm_linemap_add_source(yasm_linemap *linemap,
 YASM_LIB_DECL
 unsigned long yasm_linemap_goto_next(yasm_linemap *linemap);
 
-/** Set a new file/line physical association starting point at the current
+/** Set a new file/line physical association starting point at the specified
  * virtual line.  line_inc indicates how much the "real" line is incremented
  * by for each virtual line increment (0 is perfectly legal).
  * \param linemap       line mapping repository
  * \param filename      physical file name (if NULL, not changed)
+ * \param virtual_line  virtual line number (if 0, linemap->current is used)
  * \param file_line     physical line number
  * \param line_inc      line increment
  */
 YASM_LIB_DECL
 void yasm_linemap_set(yasm_linemap *linemap, /*@null@*/ const char *filename,
-                      unsigned long file_line, unsigned long line_inc);
+                      unsigned long virtual_line, unsigned long file_line,
+                      unsigned long line_inc);
 
 /** Poke a single file/line association, restoring the original physical
  * association starting point.  Caution: increments the current virtual line
index cabf5764f13bfc804accca46146da9dc3ffe33cd..e790f9129b457996951cf6f5ad926621787094b0 100644 (file)
@@ -321,7 +321,7 @@ cpp_line_marker(yasm_parser_gas *parser_gas)
     get_next_token();
 
     /* Set linemap. */
-    yasm_linemap_set(parser_gas->linemap, filename, line, 1);
+    yasm_linemap_set(parser_gas->linemap, filename, 0, line, 1);
 
     /*
         The first line marker in the file (which should be on the first line
@@ -429,7 +429,7 @@ nasm_line_marker(yasm_parser_gas *parser_gas)
     filename = STRING_val.contents;
 
     /* Set linemap. */
-    yasm_linemap_set(parser_gas->linemap, filename, line, incr);
+    yasm_linemap_set(parser_gas->linemap, filename, 0, line, incr);
 
     /*
         The first line marker in the file (which should be on the first line
@@ -472,12 +472,12 @@ dir_line(yasm_parser_gas *parser_gas, unsigned int param)
 
     if (parser_gas->dir_fileline == 3) {
         /* Have both file and line */
-        yasm_linemap_set(parser_gas->linemap, NULL,
+        yasm_linemap_set(parser_gas->linemap, NULL, 0,
                          parser_gas->dir_line, 1);
     } else if (parser_gas->dir_fileline == 1) {
         /* Had previous file directive only */
         parser_gas->dir_fileline = 3;
-        yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file,
+        yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file, 0,
                          parser_gas->dir_line, 1);
     } else {
         /* Didn't see file yet */
@@ -877,12 +877,12 @@ dir_file(yasm_parser_gas *parser_gas, unsigned int param)
 
             yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn,
                                 &old_line);
-            yasm_linemap_set(parser_gas->linemap, filename, old_line,
+            yasm_linemap_set(parser_gas->linemap, filename, 0, old_line,
                              1);
         } else if (parser_gas->dir_fileline == 2) {
             /* Had previous line directive only */
             parser_gas->dir_fileline = 3;
-            yasm_linemap_set(parser_gas->linemap, filename,
+            yasm_linemap_set(parser_gas->linemap, filename, 0,
                              parser_gas->dir_line, 1);
         } else {
             /* Didn't see line yet, save file */
index 6ec14fd0291d745ecdb72c956ddf688b84025764..242d3f0b821f816cd2315e6a8bf60734420da229 100644 (file)
@@ -316,7 +316,7 @@ parse_line(yasm_parser_nasm *parser_nasm)
             /* %line indicates the line number of the *next* line, so subtract
              * out the increment when setting the line number.
              */
-            yasm_linemap_set(parser_nasm->linemap, filename,
+            yasm_linemap_set(parser_nasm->linemap, filename, 0,
                 yasm_intnum_get_uint(line) - yasm_intnum_get_uint(incr),
                 yasm_intnum_get_uint(incr));
             yasm_intnum_destroy(line);