diff --git a/sv-parser-pp/src/preprocess.rs b/sv-parser-pp/src/preprocess.rs index 9a01eff3..0234dc72 100644 --- a/sv-parser-pp/src/preprocess.rs +++ b/sv-parser-pp/src/preprocess.rs @@ -487,7 +487,7 @@ pub fn preprocess_str, U: AsRef, V: BuildHasher>( let elsifid = identifier(elsifid.into(), &s).unwrap(); if hit { skip_nodes.push(elsifbody.into()); - } else if defines.contains_key(&elsifid) || is_predefined_text_macro(&ifid) { + } else if defines.contains_key(&elsifid) || is_predefined_text_macro(&elsifid) { hit = true; } else { skip_nodes.push(elsifbody.into()); @@ -535,7 +535,7 @@ pub fn preprocess_str, U: AsRef, V: BuildHasher>( let elsifid = identifier(elsifid.into(), &s).unwrap(); if hit { skip_nodes.push(elsifbody.into()); - } else if defines.contains_key(&elsifid) || is_predefined_text_macro(&ifid) { + } else if defines.contains_key(&elsifid) || is_predefined_text_macro(&elsifid) { hit = true; } else { skip_nodes.push(elsifbody.into()); diff --git a/sv-parser-pp/testcases/expected/macro_FILE.sv b/sv-parser-pp/testcases/expected/macro_FILE.sv index 6edf5c24..cf30b156 100644 --- a/sv-parser-pp/testcases/expected/macro_FILE.sv +++ b/sv-parser-pp/testcases/expected/macro_FILE.sv @@ -3,7 +3,6 @@ // This block SHOULD be emitted from the preprocessor. -// Emitted instead. // The following define should have no effect. diff --git a/sv-parser-pp/testcases/expected/macro_LINE.sv b/sv-parser-pp/testcases/expected/macro_LINE.sv index 58ec595a..b9c97f1a 100644 --- a/sv-parser-pp/testcases/expected/macro_LINE.sv +++ b/sv-parser-pp/testcases/expected/macro_LINE.sv @@ -3,7 +3,6 @@ // This block SHOULD be emitted from the preprocessor. -// Emitted instead. // The following define should have no effect. diff --git a/sv-parser-pp/testcases/macro_FILE.sv b/sv-parser-pp/testcases/macro_FILE.sv index 2ae84048..8ab9906b 100644 --- a/sv-parser-pp/testcases/macro_FILE.sv +++ b/sv-parser-pp/testcases/macro_FILE.sv @@ -12,7 +12,7 @@ // preprocessor parsing stage without error. `define __FILE__ "(null)" `elsif UNDEFINED -// Emitted instead. +// NOT emitted: UNDEFINED is not defined. `endif // The following define should have no effect. diff --git a/sv-parser-pp/testcases/macro_LINE.sv b/sv-parser-pp/testcases/macro_LINE.sv index 76de0774..383249c8 100644 --- a/sv-parser-pp/testcases/macro_LINE.sv +++ b/sv-parser-pp/testcases/macro_LINE.sv @@ -12,7 +12,7 @@ // preprocessor parsing stage without error. `define __LINE__ -1 `elsif UNDEFINED -// Emitted instead. +// NOT emitted: UNDEFINED is not defined. `endif // The following define should have no effect. diff --git a/sv-parser/src/lib.rs b/sv-parser/src/lib.rs index e84700a7..419a5b30 100644 --- a/sv-parser/src/lib.rs +++ b/sv-parser/src/lib.rs @@ -452,6 +452,50 @@ endmodule"##; assert!(ret.is_ok()); } + #[test] + fn test_elsif_predefined_macro() { + for directive in &["ifdef UNDEFINED", "ifndef __FILE__", "ifndef __LINE__"] { + for predefined in &["__FILE__", "__LINE__"] { + let src = format!( + "`{}\nmodule first; endmodule\n`elsif {}\nmodule selected; endmodule\n\ + `else\nmodule fallback; endmodule\n`endif\n", + directive, predefined, + ); + let (tree, _) = + parse_sv_str(&src, "", &HashMap::new(), &[""], false, false).unwrap(); + let modules: Vec<_> = (&tree) + .into_iter() + .filter_map(|node| match node { + RefNode::ModuleIdentifier(id) => tree.get_str_trim(id), + _ => None, + }) + .collect(); + assert_eq!(modules, ["selected"], "{} / {}", directive, predefined); + } + } + } + + #[test] + fn test_elsif_undefined_after_predefined() { + for predefined in &["__FILE__", "__LINE__"] { + let src = format!( + "`ifndef {}\nmodule first; endmodule\n`elsif UNDEFINED\nmodule second; endmodule\n\ + `else\nmodule fallback; endmodule\n`endif\n", + predefined, + ); + let (tree, _) = + parse_sv_str(&src, "", &HashMap::new(), &[""], false, false).unwrap(); + let modules: Vec<_> = (&tree) + .into_iter() + .filter_map(|node| match node { + RefNode::ModuleIdentifier(id) => tree.get_str_trim(id), + _ => None, + }) + .collect(); + assert_eq!(modules, ["fallback"], "{}", predefined); + } + } + #[test] fn test_type_equality() { let src = r##"module top #( parameter type T = type(logic[11:0]) )