diff --git a/fortls/parsers/internal/parser.py b/fortls/parsers/internal/parser.py index bef50dd0..5095a6d4 100644 --- a/fortls/parsers/internal/parser.py +++ b/fortls/parsers/internal/parser.py @@ -2209,9 +2209,10 @@ def append_multiline_macro(def_value: str | tuple, line: str): elif exc_continue: log.debug("%s !!! Conditional EXCLUDED(%d)", line.strip(), i + 1) continue + stack_is_true = all(scope[0] < 0 for scope in pp_stack) # Handle variable/macro definitions files match = FRegex.PP_DEF.match(line) - if (match is not None) and ((len(pp_stack) == 0) or (pp_stack[-1][0] < 0)): + if (match is not None) and stack_is_true: output_file.append(line) pp_defines.append(i + 1) def_name = match.group(2) @@ -2246,7 +2247,7 @@ def append_multiline_macro(def_value: str | tuple, line: str): continue # Handle include files match = FRegex.PP_INCLUDE.match(line) - if (match is not None) and ((len(pp_stack) == 0) or (pp_stack[-1][0] < 0)): + if (match is not None) and stack_is_true: log.debug("%s !!! Include statement(%d)", line.strip(), i + 1) include_filename = match.group(1).replace('"', "") include_path = None diff --git a/test/test_preproc.py b/test/test_preproc.py index 15b26026..0a618926 100644 --- a/test/test_preproc.py +++ b/test/test_preproc.py @@ -42,6 +42,8 @@ def check_return(result_array, checks): string += hover_req(file_path, 30, 23) file_path = root_dir / "preproc_if_elif_skip.F90" string += hover_req(file_path, 30, 23) + file_path = root_dir / "preproc_if_nested.F90" + string += hover_req(file_path, 33, 23) config = str(root_dir / ".pp_conf.json") errcode, results = run_request(string, ["--config", config]) assert errcode == 0 @@ -68,6 +70,7 @@ def check_return(result_array, checks): "```fortran90\nINTEGER, PARAMETER :: res = 0+1+0+0\n```", "```fortran90\nINTEGER, PARAMETER :: res = 0+0+0+1\n```", "```fortran90\nINTEGER, PARAMETER :: res = 1+0+0+0\n```", + "```fortran90\nINTEGER, PARAMETER :: res = 0+0+1+0\n```", ) assert len(ref_results) == len(results) - 1 check_return(results[1:], ref_results) diff --git a/test/test_source/pp/preproc_if_nested.F90 b/test/test_source/pp/preproc_if_nested.F90 new file mode 100644 index 00000000..5d4795d2 --- /dev/null +++ b/test/test_source/pp/preproc_if_nested.F90 @@ -0,0 +1,36 @@ +subroutine preprocessor_if_nested() + +! This file, as used in test_preproc, tests that when there are nested +! if-else preprocessor blocks, only the branches are used where ALL +! statements leading to the definition evaluate to true. + +#if 0 +#if 1 +#define PART1 1 +#else +#define PART2 1 +#endif +#else +#if 1 +#define PART3 1 +#else +#define PART4 1 +#endif +#endif + +#ifndef PART1 +#define PART1 0 +#endif +#ifndef PART2 +#define PART2 0 +#endif +#ifndef PART3 +#define PART3 0 +#endif +#ifndef PART4 +#define PART4 0 +#endif + +integer, parameter :: res = PART1+PART2+PART3+PART4 + +endsubroutine preprocessor_if_nested