Merge pull request #833 from larsclausen/ivlpp-multiline-comment
ivlpp: Improve handling of comments in macros
This commit is contained in:
commit
7c866b2590
|
|
@ -1130,12 +1130,14 @@ void free_macros(void)
|
|||
* variables. When the define is over, the def_finish() function
|
||||
* executes the define and clears this text. The define_continue_flag
|
||||
* is set if do_define detects that the definition is to be continued
|
||||
* on the next line.
|
||||
* on the next line. The define_comment_flag is set when a multi-line comment is
|
||||
* active in a define.
|
||||
*/
|
||||
static char* define_text = 0;
|
||||
static size_t define_cnt = 0;
|
||||
|
||||
static int define_continue_flag = 0;
|
||||
static int define_comment_flag = 0;
|
||||
|
||||
/*
|
||||
* The do_magic function puts the expansions of magic macros into
|
||||
|
|
@ -1189,6 +1191,33 @@ static char *find_arg(char*ptr, char*head, char*arg)
|
|||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if the comment continues on the next line
|
||||
*/
|
||||
static int do_define_multiline_comment(char *replace_start,
|
||||
const char *search_start)
|
||||
{
|
||||
char *tail = strstr(search_start, "*/");
|
||||
|
||||
if (!tail) {
|
||||
if (search_start[strlen(search_start) - 1] == '\\') {
|
||||
define_continue_flag = 1;
|
||||
define_comment_flag = 1;
|
||||
*replace_start++ = '\\';
|
||||
} else {
|
||||
define_comment_flag = 0;
|
||||
fprintf(stderr, "%s:%u: Unterminated comment in define\n",
|
||||
istack->path, istack->lineno+1);
|
||||
}
|
||||
*replace_start = '\0';
|
||||
return 1;
|
||||
}
|
||||
define_comment_flag = 0;
|
||||
tail += 2;
|
||||
memmove(replace_start, tail, strlen(tail) + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect the definition. Normally, this returns 0. If there is a
|
||||
* continuation, then return 1 and this function may be called again
|
||||
|
|
@ -1204,6 +1233,12 @@ static void do_define(void)
|
|||
|
||||
define_continue_flag = 0;
|
||||
|
||||
/* Are we in an multi-line comment? Look for the end */
|
||||
if (define_comment_flag) {
|
||||
if (do_define_multiline_comment(yytext, yytext))
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look for comments in the definition, and remove them. */
|
||||
cp = strchr(yytext, '/');
|
||||
|
||||
|
|
@ -1215,24 +1250,14 @@ static void do_define(void)
|
|||
}
|
||||
*cp = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cp[1] == '*') {
|
||||
tail = strstr(cp+2, "*/");
|
||||
|
||||
if (tail == 0) {
|
||||
*cp = 0;
|
||||
fprintf(stderr, "%s:%u: Unterminated comment in define\n",
|
||||
istack->path, istack->lineno+1
|
||||
);
|
||||
} else if (cp[1] == '*') {
|
||||
if (do_define_multiline_comment(cp, cp + 2))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cp++;
|
||||
}
|
||||
|
||||
memmove(cp, tail+2, strlen(tail+2)+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
cp = strchr(cp+1, '/');
|
||||
cp = strchr(cp, '/');
|
||||
}
|
||||
|
||||
/* Trim trailing white space. */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// Check that a '*' or '/' following a C-style comment is supported in a macro
|
||||
|
||||
`define x(a, b) a /* comment */ * b
|
||||
`define y(a, b) a /* comment */ / b
|
||||
|
||||
module test;
|
||||
|
||||
initial begin
|
||||
if (`x(2, 3) === 6 && `y(8, 2) === 4) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Check that another comment directly following a C-style comment is
|
||||
// supported in a macro.
|
||||
|
||||
`define x(a, b) a /* comment */// * b
|
||||
`define y(a, b) a /* comment *//*/ b*/
|
||||
|
||||
module test;
|
||||
|
||||
initial begin
|
||||
if (`x(2, 3) === 2 && `y(8, 2) === 8) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Check that a '/' directly after opening a C-style comment gets handled
|
||||
// correctly in a macro.
|
||||
|
||||
`define x(a, b) a /*/ b */ + b
|
||||
|
||||
module test;
|
||||
|
||||
initial begin
|
||||
if (`x(2, 3) === 5) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Check that multi-line comments in macros are supported. Including some corner
|
||||
// cases like another comment start in the comment.
|
||||
|
||||
`define test(a, b, c) \
|
||||
(a + /* these is some \
|
||||
multi line */ b /* comment \
|
||||
that goes on \
|
||||
and on */ ) /* and some more \
|
||||
\
|
||||
// and even has a comments \
|
||||
/* in the comment */ * c
|
||||
|
||||
module test;
|
||||
|
||||
initial begin
|
||||
if (`test(1, 2, 3) === 9) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -635,6 +635,10 @@ localparam_type normal ivltests gold=parameter_type.gold
|
|||
long_div normal ivltests gold=long_div.gold
|
||||
macro2 normal ivltests
|
||||
macro_args CO,-yivltests ivltests
|
||||
macro_comment1 normal ivltests
|
||||
macro_comment2 normal ivltests
|
||||
macro_comment3 normal ivltests
|
||||
macro_comment_multiline normal ivltests
|
||||
macro_redefinition normal,-Wmacro-redefinition ivltests gold=macro_redefinition.gold
|
||||
macro_replacement normal,-Wmacro-replacement ivltests gold=macro_replacement.gold
|
||||
macsub normal ivltests
|
||||
|
|
|
|||
Loading…
Reference in New Issue