Index: cfe/trunk/docs/ClangFormatStyleOptions.rst =================================================================== --- cfe/trunk/docs/ClangFormatStyleOptions.rst +++ cfe/trunk/docs/ClangFormatStyleOptions.rst @@ -2288,22 +2288,38 @@ std::unique_ptr foo() {} // Won't be affected **Standard** (``LanguageStandard``) - Format compatible with this standard, e.g. use ``A >`` - instead of ``A>`` for ``LS_Cpp03``. + .. code-block:: c++ + + c++03: latest: + vector > x; vs. vector> x; + Parse and format C++ constructs compatible with this standard. Possible values: - * ``LS_Cpp03`` (in configuration: ``Cpp03``) + * ``LS_Cpp03`` (in configuration: ``c++03``) Use C++03-compatible syntax. - * ``LS_Cpp11`` (in configuration: ``Cpp11``) - Use features of C++11, C++14 and C++1z (e.g. ``A>`` instead of - ``A >``). + * ``LS_Cpp11`` (in configuration: ``c++11``) + Use C++11-compatible syntax. + + * ``LS_Cpp14`` (in configuration: ``c++14``) + Use C++14-compatible syntax. + + * ``LS_Cpp17`` (in configuration: ``c++17``) + Use C++17-compatible syntax. + + * ``LS_Cpp20`` (in configuration: ``c++20``) + Use C++20-compatible syntax. + + * ``LS_Latest`` (in configuration: ``Latest``) + Parse and format using the latest supported language version. * ``LS_Auto`` (in configuration: ``Auto``) Automatic detection based on the input. + * ``Cpp03``: deprecated alias for ``c++03`` + * ``Cpp11``: deprecated alias for ``Latest`` **StatementMacros** (``std::vector``) A vector of macros that should be interpreted as complete Index: cfe/trunk/include/clang/Format/Format.h =================================================================== --- cfe/trunk/include/clang/Format/Format.h +++ cfe/trunk/include/clang/Format/Format.h @@ -1945,15 +1945,32 @@ /// \endcode bool SpacesInSquareBrackets; - /// Supported language standards. + /// Supported language standards for parsing and formatting C++ constructs. + /// \code + /// Latest: vector> + /// c++03 vs. vector > + /// \endcode + /// + /// The correct way to spell a specific language version is e.g. ``c++11``. + /// The historical aliases ``Cpp03`` and ``Cpp11`` are deprecated. enum LanguageStandard { - /// Use C++03-compatible syntax. + /// c++03: Parse and format as C++03. LS_Cpp03, - /// Use features of C++11, C++14 and C++1z (e.g. ``A>`` instead of - /// ``A >``). + /// c++11: Parse and format as C++11. LS_Cpp11, - /// Automatic detection based on the input. - LS_Auto + /// c++14: Parse and format as C++14. + LS_Cpp14, + /// c++17: Parse and format as C++17. + LS_Cpp17, + /// c++20: Parse and format as C++20. + LS_Cpp20, + /// Latest: Parse and format using the latest supported language version. + /// 'Cpp11' is an alias for LS_Latest for historical reasons. + LS_Latest, + + /// Auto: Automatic detection based on the input. + /// Parse using the latest language version. Format based on detected input. + LS_Auto, }; /// Format compatible with this standard, e.g. use ``A >`` Index: cfe/trunk/lib/Format/Format.cpp =================================================================== --- cfe/trunk/lib/Format/Format.cpp +++ cfe/trunk/lib/Format/Format.cpp @@ -67,10 +67,19 @@ template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) { - IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); - IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); - IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11); - IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); + IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03); + IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); // Legacy alias + IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); // Legacy alias + + IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11); + IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); // Legacy alias + + IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14); + IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17); + IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20); + + IO.enumCase(Value, "Latest", FormatStyle::LS_Latest); + IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest); // Legacy alias IO.enumCase(Value, "Auto", FormatStyle::LS_Auto); } }; @@ -756,7 +765,7 @@ LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; LLVMStyle.SpacesBeforeTrailingComments = 1; - LLVMStyle.Standard = FormatStyle::LS_Cpp11; + LLVMStyle.Standard = FormatStyle::LS_Latest; LLVMStyle.UseTab = FormatStyle::UT_Never; LLVMStyle.ReflowComments = true; LLVMStyle.SpacesInParentheses = false; @@ -1399,7 +1408,7 @@ : FormatStyle::PAS_Right; if (Style.Standard == FormatStyle::LS_Auto) Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) - ? FormatStyle::LS_Cpp11 + ? FormatStyle::LS_Latest : FormatStyle::LS_Cpp03; BinPackInconclusiveFunctions = HasBinPackedFunction || !HasOnePerLineFunction; @@ -2455,14 +2464,18 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { LangOptions LangOpts; - FormatStyle::LanguageStandard LexingStd = - Style.Standard == FormatStyle::LS_Auto ? FormatStyle::LS_Cpp11 - : Style.Standard; + + FormatStyle::LanguageStandard LexingStd = Style.Standard; + if (LexingStd == FormatStyle::LS_Auto) + LexingStd = FormatStyle::LS_Latest; + if (LexingStd == FormatStyle::LS_Latest) + LexingStd = FormatStyle::LS_Cpp20; LangOpts.CPlusPlus = 1; LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; - LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp11; - LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp11; - LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp11; + LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14; + LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17; + LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp20; + LangOpts.LineComment = 1; bool AlternativeOperators = Style.isCpp(); LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; Index: cfe/trunk/unittests/Format/FormatTest.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp +++ cfe/trunk/unittests/Format/FormatTest.cpp @@ -9388,6 +9388,19 @@ format("#define x(_a) printf(\"foo\"_a);", Style)); } +TEST_F(FormatTest, CppLexVersion) { + FormatStyle Style = getLLVMStyle(); + // Formatting of x * y differs if x is a type. + verifyFormat("void foo() { MACRO(a * b); }", Style); + verifyFormat("void foo() { MACRO(int *b); }", Style); + + // LLVM style uses latest lexer. + verifyFormat("void foo() { MACRO(char8_t *b); }", Style); + Style.Standard = FormatStyle::LS_Cpp17; + // But in c++17, char8_t isn't a keyword. + verifyFormat("void foo() { MACRO(char8_t * b); }", Style); +} + TEST_F(FormatTest, UnderstandsCpp1y) { verifyFormat("int bi{1'000'000};"); } TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) { @@ -12305,11 +12318,18 @@ FormatStyle::PAS_Middle); Style.Standard = FormatStyle::LS_Auto; + CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03); + CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11); + CHECK_PARSE("Standard: c++14", Standard, FormatStyle::LS_Cpp14); + CHECK_PARSE("Standard: c++17", Standard, FormatStyle::LS_Cpp17); + CHECK_PARSE("Standard: c++20", Standard, FormatStyle::LS_Cpp20); + CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto); + CHECK_PARSE("Standard: Latest", Standard, FormatStyle::LS_Latest); + // Legacy aliases: CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03); - CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Cpp11); + CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Latest); CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03); CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11); - CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto); Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment",