clang::LangOption policy

So I’ve been working with clang as a library on Windows for a little while now, and I’m noticed a few things that I’d like to change, but in order to do so I need to know the “clang policy” for such things first.

There is a flag, MSVCCompat, which as you probably know already, tweaks some things so that clang works better on Windows.

However, other flags are required, such as DelayedTemplateParsing, in order for things to work. Now I understand that these need to be separate flags so that users on other platforms can enable things like DelayedTemplateParsing for other reasons, but as it stands enabling MSVCCompat doesn’t make clang compatible with Windows.

As a result, I’d like to fix this problem by making things like DelayedTemplateParsing take effect when MSVCCompat is turned on. However, this would make it so that the “implied” flags would essentially have no effect, and turning off DelayedTemplateParsing would not have any effect if MSVCCompat was turned off.

Furthermore, I can’t see the point in having both a MSCompatibility flag and a MSVCCompat flag; surely we should have one or the other?

How do you folks feel about this? I’d really like to make this my first contribution to clang.

So I’ve been working with clang as a library on Windows for a little while now, and I’m noticed a few things that I’d like to change, but in order to do so I need to know the “clang policy” for such things first.

There is a flag, MSVCCompat, which as you probably know already, tweaks some things so that clang works better on Windows.

However, other flags are required, such as DelayedTemplateParsing, in order for things to work. Now I understand that these need to be separate flags so that users on other platforms can enable things like DelayedTemplateParsing for other reasons, but as it stands enabling MSVCCompat doesn’t make clang compatible with Windows.

As a result, I’d like to fix this problem by making things like DelayedTemplateParsing take effect when MSVCCompat is turned on. However, this would make it so that the “implied” flags would essentially have no effect, and turning off DelayedTemplateParsing would not have any effect if MSVCCompat was turned off.

Furthermore, I can’t see the point in having both a MSCompatibility flag and a MSVCCompat flag; surely we should have one or the other?

+reid - I had the impression the right way to get clang to work on windows is by calling it in CL mode (clang-cl.exe).

Thanks for the quick reply Manuel! :slight_smile:

I am using clang as a library, so AFAIK the clang-cl is not relevant (it’s just a frontend that does the things I’m describing at a different level - which is what I’m proposing to change). The changes I am proposing would simplify the implementation of it, however!

If I’m wrong and clang-cl is not just a frontend, then that could make my life considerably easier.

So I've been working with clang as a library on Windows for a little while
now, and I'm noticed a few things that I'd like to change, but in order to
do so I need to know the "clang policy" for such things first.

There is a flag, MSVCCompat, which as you probably know already, tweaks
some things so that clang works better on Windows.

However, other flags are required, such as DelayedTemplateParsing, in
order for things to work. Now I understand that these need to be separate
flags so that users on other platforms can enable things like
DelayedTemplateParsing for other reasons, but as it stands enabling
MSVCCompat doesn't make clang compatible with Windows.

As a result, I'd like to fix this problem by making things like
DelayedTemplateParsing take effect when MSVCCompat is turned on. However,
this would make it so that the "implied" flags would essentially have no
effect, and turning off DelayedTemplateParsing would not have any effect if
MSVCCompat was turned off.

I see our MSVC compatibility story a little differently. We offer a
multitude of flags which control different aspects of compatibility with
MSVC:
-fms-extensions
-fms-compatibility
-fdelayed-template-parsing
-fms-compatibility-version/-fmsc-version
-fthreadsafe-statics
-relaxed-aliasing
/vd0, /vd1, /vd2
/vmg, /vmb, /vms, /vmv, /vmm
...

While many (all?) of these flags have some effect on language conformance,
there are perhaps two which have no discernible ABI impact (outside of,
say, SFINAE): -fms-compatibility and -fdelayed-template-parsing.

These two flags engage orthogonal pieces of our compatibility machinery and
the intent is to ask users of clang to enable the bare minimum they need in
the hopes that we would encourage authorship of code which is portable and
free of reliance on compiler quirks. -fms-compatibility is less bad than
-fdelayed-template-parsing in my eyes in that -fdelayed-template-parsing
will result in ASTs which have way worse fidelity.

I think it is reasonable for tools like clang-cl to enable both flags by
default due to it's fundamental nature but I don't think that's a decision
we'd want to make for tools at large.

At a rather fundamental level the tool really needs to know whether or not
it should run the frontend with /vd2 or /vmv, some information must be
supplied to us. I would rather see tools actively make the decision to use
-fdelayed-template-parsing instead of get opted into it.

Furthermore, I can't see the point in having both a MSCompatibility flag
and a MSVCCompat flag; surely we should have one or the other?

I can't seem to find MSCompatibility as an identifier in clang's sources.
However, I can find the similarly named MSCompatibilityVersion.
MSCompatibilityVersion is intended to be useful outside of MSVCCompat:
clang emitting MSVC-style diagnostics when targeting non-MSVC platforms is
a not-uncommon thing; some versions of VisualStudio do the wrong thing and
MSCompatibilityVersion lets us know if we should work around them (see
Frontend/TextDiagnostic.cpp).

Yes, I meant MSCompatibilityVersion (sorry about that).

I see your point about having the granularity available to the user; users not want some tweaks whilst still wanting others.
However, it feels like a misnomer having a flag MSVCCompat that doesn’t enable everything needed to compile the Windows headers. Perhaps this is a naming issue.

Does clang-cl have a function I can call into to get the appropriate flags set (LangOptions and anything else that needs to be set)? If not, how would you feel about me adding one? I feel this would make developing an application that uses libclang for Windows easier, as you could simply point them to that function.

Thanks for your input!

Yes, I meant MSCompatibilityVersion (sorry about that).

I see your point about having the granularity available to the user; users
not want some tweaks whilst still wanting others.
However, it feels like a misnomer having a flag MSVCCompat that doesn't
enable everything needed to compile the Windows headers. Perhaps this is a
naming issue.

I think you've hit the nail on the head, MSVCCompat is poorly named in our
big sea of compatibility options.

Does clang-cl have a function I can call into to get the appropriate flags
set (LangOptions and anything else that needs to be set)? If not, how would
you feel about me adding one? I feel this would make developing an
application that uses libclang for Windows easier, as you could simply
point them to that function.

What might be useful is adding a dump method to LangOptions which would let
you examine how particular invocations of clang/clang-cl have it configured
under different flags.

Thanks for your input!

Happy to help :slight_smile:

I think you’ve hit the nail on the head, MSVCCompat is poorly named in our big sea of compatibility options.

Glad you agree! I need to spend some time working out what it actually does in order to think of a better name now.

What might be useful is adding a dump method to LangOptions which would let you examine how particular invocations of clang/clang-cl have it configured under different flags.

It’ll certainly be a start, yes. It’ll also be a good way for me to get started contributing some source!

I’ll start poking around these two issues now.

Looking into things a bit more, it seems that MSVCCompat does a multitude of things, so I don’t think renaming it is the solution.
The best path I can see through this is for it to be separated out into many more specific options, but this will break a lot of user code.

Given the sheer number of places it’s used, this is probably best made in an incremental manner. I can’t justify the time for it at work, but I can in my own, so I’ll have to make a start on that tonight (assuming that path of action is taken).

The LangOptions dump however, is useful for my work, so I can get the time to do that.

I think the answer to your high-level question is that LangOptions isn’t really designed to be high-level and user-facing. Users use command lines, and LangOptions attempts to be a more logical, denormalized representation of their settings useful for the internals of the compiler.

I think you have two ways forward:

  • Use libTooling the way clang-tidy does, and let it translate from normal high-level driver command lines to -cc1 lines for you. This is probably a lot of work.

  • Dump LangOptions as David suggested and try to build a LangOptions close to what clang would do for a normal Windows compilation. This is probably easier to do now, if harder to maintain over time.

Not particularly awesome, unfortunately. =/

Thanks to you all, I’ll go with your recommendation and implement the dump function for LangOptions.

Whilst on the topic, I’ve always had trouble getting any debug information out of LLVM and Clang; is there a nice way to get things like that printed to a file / STDOUT consistently?

The best I’ve found so far involves going into the VS solution settings, adding something like > log.txt to the command line arguments, and hoping it works (it doesn’t always).

Thanks to you all, I’ll go with your recommendation and implement the dump
function for LangOptions.

Whilst on the topic, I’ve always had trouble getting any debug information
out of LLVM and Clang; is there a nice way to get things like that printed
to a file / STDOUT consistently?

You mean dumps, like -ast-dump, -fdump-record-layout, -emit-llvm, -mllvm
-print-after-all, -mllvm -debug, and this kind of thing? We don't have any
kind of generic logging infrastructure, if that's what you're thinking.

The best I’ve found so far involves going into the VS solution settings,

adding something like > log.txt to the command line arguments, and hoping
it works (it doesn’t always).

Oftentimes we dump to stderr because it's easy to invoke tools with '-o -',
so the output appears on stdout. If you can trick VS into logging stderr,
that might help.