Skip to content

Keep original line information in AST ranges, add separate mechanism for #line directives #18553

Open
@Martin521

Description

@Martin521

#line directives are very useful when debugging generated source code. Unfortunately, they are implemented in a way that creates problems in many other cases (like #18489, #17519, #18049, #18433, #18402). I therefore propose to implement them differently.

Currently, the lexer (tokenizer) handles the #line directives by attaching the target ranges (as defined by the #line directive arguments) to the tokens. So, all subsequent stages (parsing, type checking etc) have access only to the target ranges and no longer to the original ranges. The target ranges, however, are really needed only when formatting diagnostic messages and when writing the pdb file.

In #18049, where we needed the original ranges, we have created a work-around with "linemaps". These linemaps are created during lexing and can be used to map the target ranges back to the original ranges. This mapping is not necessarily unique, but we decided we have a good enough implementation for the typical cases like fslex/fsyacc. It is also currently coupled to the specific "nowarn" application.

I propose now to (try to) turn this around. Keep the original ranges through all stages. During lexing, create a forward map (which is unique) from the original to the target ranges. And use this map when formatting diagnostic messages and when writing the pdb. In these cases necessarily the range.FileName or range.FileIndex members are used. So we need to check all calls to these member (a few dozens in the compiler) and decide if a mapping is necessary. From a quick check I believe that we can make the map available to these places through TcConfig and TcGlobals.

I expect this to not create any changes to the fsc output. I also assume there are no consumers of the compiler service that rely on having the target ranges in the AST. For them, this would be a breaking change. They would need to apply the map when dealing with these ranges.

Feasibility can finally only be assessed by implementing this.
But if anybody sees roadblocks, please provide feedback.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions