fortran-lang / fortls

fortls - Fortran Language Server
https://fortls.fortran-lang.org/
MIT License
257 stars 41 forks source link

Special syntax for preprocessor conditional directive #309

Open Mazrog opened 1 year ago

Mazrog commented 1 year ago

Hello,

In our fortran codebase, we have some preprocessor directives that do not seem to be recognized as such, leading to "variable declared twice in this scope" kind of error (we use this typically for unicode handling with a preproc symbol, or DEBUG additional info/check)

Here is the syntax

!DEC$ IF DEFINED ( _UNICODE )
   INTEGER, PARAMETER, PUBLIC :: UTF16 = #FEFF
!DEC$ ELSE
   INTEGER, PARAMETER, PUBLIC :: UTF16 = #00
!DEC$ ENDIF

From what I understood, this is not the classic syntax, do not know if this is linked but we are using the Intel Fortran Compiler (ifort).

Is there a way to make it work? I have not found such settings in the config file. In the vscode extension that is said using fortls as a backend, there appear to have settings for specifying a compiler and path for the linting, would not know if that setting would help though.

Would you have any insight on this subject? Thanks

gnikit commented 1 year ago

Currently there is no way to accomplish what you want in fortls. As you rightly mentioned, !DEC$ is very old, non-standard syntax, that's why fortls does not support it.

I am not sure how hard it would be to edit the pre-processor to accept the DEC preprocessor directives, probably it's a non-trivial task. Also, it's worth mentioning that codes that use the DEC compiler extension usually include a lot more abuses to the Fortran Standard, like UNION, MAP and . member separator, which again fortls does not support.

I am not going to mark this as a wontfix yet, it's worth having a look and assessing the amount of work needed, but if what I recall is correct, this will be a large work-package.

Mazrog commented 1 year ago

Oh I see... Unfortunately, I think our codebase has all the red flags you mentioned ^^ A lot of code was written before C even existed from what I have been told, using some vendor extensions or compiler explicitly.

Default member access operator is ., and we used UNION and MAP keywords to make C binding with C union...

From what I gather from your message, all this is "old" and "non-standard"? Maybe we could throw a bunch of search/replace/refacto on our side in the objective of being more standard-compliant.

I can see direct mapping for the !DEC$ conditional preproc directive, % is the new ., but for UNION and MAP, as they were documented by gfortran, oracle or intel I thought they were standard :( Is there a new datatype covering it?

I understand your position, adding support for old and non standard does seem a lot of work for something legacy.