[PATCH] D65043: [Format] Add C++20 standard to style options

Sam McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 24 02:28:50 PDT 2019


sammccall added a comment.

So there's precedent for this in rL185149 <https://reviews.llvm.org/rL185149> (D1028 <https://reviews.llvm.org/D1028>). @klimek may have historical context. Overall, this makes sense.
Since the coroutines flag flip landed on the 9.x release branch, we may want this merged into the branch too.

The configuration (and particularly defaults) is difficult though. I think due to some excessive cleverness in the past, we're dug into a bit of a hole.

- the default behavior needs to work well for projects using c++20. Given ambiguous input (e.g. use of `co_yield`, with `LS_Auto`), we should resolve in favor of this being C++20 rather than a funny-named identifier. 5 years from now, the former is going to be **much** more common than the latter, and there's no better time than now to switch the default. The most obvious implementation of this is having `LS_Auto` run the lexer in C++20 mode, and requiring users who don't want that to specify C++1x.
- By bucketing C++11/14/17 together, the LS option has effectively evolved into a tristate: "old/new/detect". The result is we're not capturing user intent well: lots of `.clang-format` files specify `Cpp11` to mean "new". If we're going to add a `Cpp20` option, our only sane alternative is to disable C++20 features for such people. It's not actually a backwards-incompatible change at this point (assuming we get this on the 9.x branch), but it's an unfortunate situation and it's our fault. We need to improve the system so users have better options, because next time (when C++23 rolls around) things will be more complicated. Or if we need to change the behavior for C++17 vs 11...

I think the user intents we should capture here are:

1. pinning to **any** specific version, that's what the codebase uses and we have a process for bumping it
2. (maybe) floating with the latest language version, the codebase continuously adopts new constructs and fixes conflicts in old code
3. I don't know/haven't bothered to configure

The reason I'm unsure about 2 is I don't know whether the people setting `Cpp11` today (in projects using post-C++11 features) have a specific standard in mind. Maybe we should be conservative and leave it out for now.

This would lead to something like:

  enum LanguageStandard {
    // Default: attempt to guess based on the file.
    // Lexer always runs in the latest standard.
    // Preserves backwards-compatible formatting (e.g. vector<vector<int> >) if the
    // input uses it consistently.
    LS_Auto,
  
    LS_Cpp03, // Parse and format in C++03-compatible mode
    LS_Cpp11, // No longer enables C++14 in the lexer
    LS_Cpp14,
    LS_Cpp17, // Equivalent to today's Cpp11!
    LS_Cpp2a, // Later to be renamed to Cpp23, but we'll keep accepting `Cpp2a` in the config parser forever
  };

The obvious problem here is that this may well break existing projects that use `Cpp11` and C++14/17 features.
I think we can punt on this by making Cpp11/14 still enable 14/17 in LangOpts for now (so we don't change behavior, just give people a better way to specify their intent) and change it later if needed.

What do you think?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65043/new/

https://reviews.llvm.org/D65043





More information about the cfe-commits mailing list