MyDeveloperDay updated this revision to Diff 463502. MyDeveloperDay retitled this revision from "[clang-format] Add Really Basic Carbon Support/Infrastructure" to "[clang-format] Add Basic Carbon Support/Infrastructure to clang-format". MyDeveloperDay added a comment.
Improve the handling of generics. Ensure match is formatted like switch. Move closer to Google style. Add some pointer support for return types Add additional integration CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134652/new/ https://reviews.llvm.org/D134652 Files: clang/docs/ClangFormatStyleOptions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/tools/clang-format/ClangFormat.cpp clang/tools/clang-format/clang-format-diff.py clang/tools/clang-format/git-clang-format clang/unittests/Format/CMakeLists.txt clang/unittests/Format/FormatTestCarbon.cpp clang/unittests/Format/TokenAnnotatorTest.cpp
Index: clang/unittests/Format/TokenAnnotatorTest.cpp =================================================================== --- clang/unittests/Format/TokenAnnotatorTest.cpp +++ clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1045,6 +1045,97 @@ EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon); } +TEST_F(TokenAnnotatorTest, UnderstandsCarbonReturnType) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + auto Tokens = annotate("fn Sum(var a: i32, var b: i32) -> i32 {", Style); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[13], tok::arrow, TT_TrailingReturnArrow); + EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_FunctionLBrace); + + Tokens = annotate("fn Add[me: Self](k: i32) -> Self {", Style); + ASSERT_EQ(Tokens.size(), 16u) << Tokens; + EXPECT_TOKEN(Tokens[12], tok::arrow, TT_TrailingReturnArrow); + EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_FunctionLBrace); + + Tokens = annotate("fn Add[me: Self](k: i32) -> Self;", Style); + ASSERT_EQ(Tokens.size(), 16u) << Tokens; + EXPECT_TOKEN(Tokens[12], tok::arrow, TT_TrailingReturnArrow); + EXPECT_TOKEN(Tokens[14], tok::semi, TT_Unknown); + + Tokens = annotate("fn Add[me: Self](k: i32) -> i32*;", Style); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[12], tok::arrow, TT_TrailingReturnArrow); + EXPECT_TOKEN(Tokens[15], tok::semi, TT_Unknown); +} + +TEST_F(TokenAnnotatorTest, UnderstandsCarbonTypeOnColon) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + auto Tokens = annotate("let id: i32 = 57;", Style); + ASSERT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::colon, TT_JsTypeColon); + + Tokens = annotate("var t2: {.x: i32, .y: i32} = {.x = 2, .y = 5};", Style); + ASSERT_EQ(Tokens.size(), 28u) << Tokens; + EXPECT_TOKEN(Tokens[6], tok::colon, TT_JsTypeColon); +} + +TEST_F(TokenAnnotatorTest, UnderstandsCarbonPointerTypeOnColon) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + auto Tokens = annotate("fn GetSetX[addr me: Point*](x: i32) -> i32 {", Style); + ASSERT_EQ(Tokens.size(), 18u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::colon, TT_JsTypeColon); + EXPECT_TOKEN(Tokens[7], tok::star, TT_PointerOrReference); + + Tokens = annotate( + "fn GetSetX[addr me: Point*, addr me: Point*](x: i32) -> i32 {", Style); + ASSERT_EQ(Tokens.size(), 24u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::colon, TT_JsTypeColon); + EXPECT_TOKEN(Tokens[7], tok::star, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[11], tok::colon, TT_JsTypeColon); + EXPECT_TOKEN(Tokens[13], tok::star, TT_PointerOrReference); +} + +TEST_F(TokenAnnotatorTest, UnderstandsCarbonTypeOnColonForLoop) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + auto Tokens = annotate("for (var name: String in names) {", Style); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::colon, TT_JsTypeColon); +} + +TEST_F(TokenAnnotatorTest, UnderstandsCarbonTypeExclaim) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + auto Tokens = annotate("(T:! Addable)", Style); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::colon, TT_JsTypeColon); + EXPECT_TOKEN(Tokens[3], tok::exclaim, TT_UnaryOperator); + ASSERT_EQ(Tokens[3]->SpacesRequiredBefore, false); + EXPECT_TOKEN(Tokens[4], tok::identifier, TT_Unknown); + ASSERT_EQ(Tokens[4]->SpacesRequiredBefore, true); +} + +TEST_F(TokenAnnotatorTest, UnderstandsCarbonClassTemplate) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + auto Tokens = annotate("class GenericClass(T:! Type) {", Style); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown); + ASSERT_EQ(Tokens[2]->SpacesRequiredBefore, false); + ASSERT_EQ(Tokens[2]->MustBreakBefore, false); +} + +TEST_F(TokenAnnotatorTest, UnderstandsCarbonMatch) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + auto Tokens = annotate("match (x)", Style); + ASSERT_EQ(Tokens.size(), 5u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown); + ASSERT_EQ(Tokens[1]->SpacesRequiredBefore, true); +} + } // namespace } // namespace format } // namespace clang Index: clang/unittests/Format/FormatTestCarbon.cpp =================================================================== --- /dev/null +++ clang/unittests/Format/FormatTestCarbon.cpp @@ -0,0 +1,139 @@ +//===- unittest/Format/FormatTestCarbon.cpp - Formatting tests for Carbon -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "FormatTestUtils.h" +#include "clang/Format/Format.h" +#include "llvm/Support/Debug.h" +#include "gtest/gtest.h" + +#define DEBUG_TYPE "format-test-json" + +namespace clang { +namespace format { + +class FormatTestCarbon : public ::testing::Test { +protected: + static std::string format(llvm::StringRef Code, unsigned Offset, + unsigned Length, const FormatStyle &Style) { + LLVM_DEBUG(llvm::errs() << "---\n"); + LLVM_DEBUG(llvm::errs() << Code << "\n\n"); + std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); + tooling::Replacements Replaces = reformat(Style, Code, Ranges); + auto Result = applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast<bool>(Result)); + LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); + return *Result; + } + + static std::string + format(llvm::StringRef Code, + const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_Carbon)) { + return format(Code, 0, Code.size(), Style); + } + + static FormatStyle getStyleWithColumns(unsigned ColumnLimit) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + Style.ColumnLimit = ColumnLimit; + return Style; + } + + static void verifyFormatStable(llvm::StringRef Code, + const FormatStyle &Style) { + EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable"; + } + + static void verifyFormat( + llvm::StringRef Code, + const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_Carbon)) { + verifyFormatStable(Code, Style); + EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); + } +}; + +TEST_F(FormatTestCarbon, CarbonBasicFunctions) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + verifyFormat("fn Sum(var a: i32, var b: i32) -> i32 { return a + b; }", + Style); + verifyFormat("// Empty or void return type.\n" + "fn PrintCount(var count: i32) { Print(\" The count is { 0 } " + "\", count); }", + Style); +} + +TEST_F(FormatTestCarbon, CarbonFunctionPrototype) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("fn GetSetX[addr me: Point*](x: i32) -> i32 {", Style); + verifyFormat("fn Add[me: Self](k: i32) -> Self;", Style); + verifyFormat("fn Add[me: Self](k: i32) -> Self {", Style); + verifyFormat("fn Main() -> i32 {", Style); + verifyFormat("fn Make() -> (Self, T);", Style); + verifyFormat("fn Make() -> (Self, T) {", Style); + verifyFormat("fn F(n: i32, p: i32*, q: i32***) -> i32* {", Style); +} + +TEST_F(FormatTestCarbon, CarbonVariable) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("var name: auto = \"Carbon is an open-source programming\";", + Style); + verifyFormat("let id: i32 = 57;", Style); + verifyFormat("var total_articles_published: i32 = 4500;", Style); +} + +TEST_F(FormatTestCarbon, CarbonVariableInLoop) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("for (var name: String in names) {", Style); +} + +TEST_F(FormatTestCarbon, CarbonVariableBreakAfterClass) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("class Sum {\n" + " var a: i32;\n" + "}\n" + "fn Main() -> i32 { var p1: Sum = {.a = 5}; }", + Style); +} + +TEST_F(FormatTestCarbon, CarbonClassAndInterface) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("class Class {\n" + " var a: i32;\n" + "}", + Style); + verifyFormat("class GenericClass(T:! Type) {\n" + " var a: T;\n" + "}", + Style); + verifyFormat("interface Interface {\n" + " fn Make() -> Self;\n" + "}", + Style); + verifyFormat("interface GenericInterface(T:! Type) {\n" + " fn Make() -> Self;\n" + "}", + Style); +} + +TEST_F(FormatTestCarbon, CarbonMatch) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("match (x) {", Style); +} + +TEST_F(FormatTestCarbon, CarbonTuple) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_Carbon); + + verifyFormat("var (x: auto, y: auto) = (2, 3);", Style); +} + +} // namespace format +} // end namespace clang Index: clang/unittests/Format/CMakeLists.txt =================================================================== --- clang/unittests/Format/CMakeLists.txt +++ clang/unittests/Format/CMakeLists.txt @@ -6,6 +6,7 @@ CleanupTest.cpp DefinitionBlockSeparatorTest.cpp FormatTest.cpp + FormatTestCarbon.cpp FormatTestComments.cpp FormatTestCSharp.cpp FormatTestJS.cpp Index: clang/tools/clang-format/git-clang-format =================================================================== --- clang/tools/clang-format/git-clang-format +++ clang/tools/clang-format/git-clang-format @@ -98,6 +98,7 @@ 'ts', # TypeScript 'cs', # C Sharp 'json', # Json + 'carbon', # Carbon ]) p = argparse.ArgumentParser( Index: clang/tools/clang-format/clang-format-diff.py =================================================================== --- clang/tools/clang-format/clang-format-diff.py +++ clang/tools/clang-format/clang-format-diff.py @@ -48,7 +48,7 @@ '(case sensitive, overrides -iregex)') parser.add_argument('-iregex', metavar='PATTERN', default= r'.*\.(cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp|hxx' - r'|m|mm|inc|js|ts|proto|protodevel|java|cs|json)', + r'|m|mm|inc|js|ts|proto|protodevel|java|cs|json|carbon)', help='custom pattern selecting file paths to reformat ' '(case insensitive, overridden by -regex)') parser.add_argument('-sort-includes', action='store_true', default=False, Index: clang/tools/clang-format/ClangFormat.cpp =================================================================== --- clang/tools/clang-format/ClangFormat.cpp +++ clang/tools/clang-format/ClangFormat.cpp @@ -582,7 +582,8 @@ cl::SetVersionPrinter(PrintVersion); cl::ParseCommandLineOptions( argc, argv, - "A tool to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# " + "A tool to format " + "C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C#/Carbon " "code.\n\n" "If no arguments are specified, it formats the code from standard input\n" "and writes the result to the standard output.\n" Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -1930,7 +1930,8 @@ tryToParseJSFunction(); break; } - if ((Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) && + if ((Style.isJavaScript() || Style.Language == FormatStyle::LK_Java || + Style.isCarbon()) && FormatTok->is(Keywords.kw_interface)) { if (Style.isJavaScript()) { // In JavaScript/TypeScript, "interface" can be used as a standalone @@ -3667,9 +3668,9 @@ // parseRecord falls through and does not yet add an unwrapped line as a // record declaration or definition can start a structural element. parseRecord(); - // This does not apply to Java, JavaScript and C#. + // This does not apply to Java, JavaScript and C# or Carbon if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() || - Style.isCSharp()) { + Style.isCSharp() || Style.isCarbon()) { if (FormatTok->is(tok::semi)) nextToken(); addUnwrappedLine(); @@ -3825,6 +3826,10 @@ nextToken(); } } + if (Style.isCarbon()) { + if (FormatTok && FormatTok->is(tok::l_paren)) + parseParens(); + } } // Note that parsing away template declarations here leads to incorrectly Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -617,7 +617,10 @@ Left->setType(TT_StructuredBindingLSquare); } else if (Left->is(TT_Unknown)) { if (StartsObjCMethodExpr) { - Left->setType(TT_ObjCMethodExpr); + if (Style.isCarbon()) + Left->setType(TT_JsTypeColon); + else + Left->setType(TT_ObjCMethodExpr); } else if (InsideInlineASM) { Left->setType(TT_InlineASMSymbolicNameLSquare); } else if (IsCpp11AttributeSpecifier) { @@ -765,7 +768,7 @@ // Remember that this is a [[using ns: foo]] C++ attribute, so we // don't add a space before the colon (unlike other colons). CurrentToken->setType(TT_AttributeColon); - } else if (!Style.isVerilog() && + } else if (!Style.isVerilog() && !Style.isCarbon() && Left->isOneOf(TT_ArraySubscriptLSquare, TT_DesignatedInitializerLSquare)) { Left->setType(TT_ObjCMethodExpr); @@ -775,6 +778,8 @@ // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen. Parent->setType(TT_CastRParen); } + } else if (Style.isCarbon()) { + CurrentToken->setType(TT_JsTypeColon); } ColonFound = true; } @@ -983,7 +988,10 @@ } else if (Contexts.back().ColonIsDictLiteral || Style.Language == FormatStyle::LK_Proto || Style.Language == FormatStyle::LK_TextProto) { - Tok->setType(TT_DictLiteral); + if (Style.isCarbon()) + Tok->setType(TT_JsTypeColon); + else + Tok->setType(TT_DictLiteral); if (Style.Language == FormatStyle::LK_TextProto) { if (FormatToken *Previous = Tok->getPreviousNonComment()) Previous->setType(TT_SelectorName); @@ -1018,7 +1026,10 @@ ++Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts; } } else if (Contexts.back().ColonIsForRangeExpr) { - Tok->setType(TT_RangeBasedForLoopColon); + if (Style.isCarbon()) + Tok->setType(TT_JsTypeColon); + else + Tok->setType(TT_RangeBasedForLoopColon); } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) { Tok->setType(TT_BitFieldColon); } else if (Contexts.size() == 1 && @@ -1038,7 +1049,10 @@ if (PrevPrev && PrevPrev->isOneOf(tok::r_paren, tok::kw_noexcept)) Tok->setType(TT_CtorInitializerColon); } else { - Tok->setType(TT_InheritanceColon); + if (Style.isCarbon()) + Tok->setType(TT_JsTypeColon); + else + Tok->setType(TT_InheritanceColon); } } else if (canBeObjCSelectorComponent(*Tok->Previous) && Tok->Next && (Tok->Next->isOneOf(tok::r_paren, tok::comma) || @@ -1048,7 +1062,10 @@ // the colon are passed as macro arguments. Tok->setType(TT_ObjCMethodExpr); } else if (Contexts.back().ContextKind == tok::l_paren) { - Tok->setType(TT_InlineASMColon); + if (Style.isCarbon()) + Tok->setType(TT_JsTypeColon); + else + Tok->setType(TT_InlineASMColon); } break; case tok::pipe: @@ -1842,6 +1859,22 @@ } } + if (Style.isCarbon()) { + // -> T { + // -> T ; + // -> i32*; + if (Current.is(tok::arrow) && Current.Next->Next && + Current.Next->Next->isOneOf(TT_FunctionLBrace, tok::semi, + tok::star)) { + Current.setType(TT_TrailingReturnArrow); + } + // -> (Self,T) { + if (Current.is(tok::arrow) && Current.Next && + Current.Next->is(tok::l_paren)) { + Current.setType(TT_TrailingReturnArrow); + } + } + // Line.MightBeFunctionDecl can only be true after the parentheses of a // function declaration have been found. In this case, 'Current' is a // trailing token of this declaration and thus cannot be a name. @@ -2333,6 +2366,10 @@ const FormatToken *NextToken = Tok.getNextNonComment(); + // handle [addr me: Point*] + if (Style.isCarbon() && NextToken->is(tok::r_square)) + return TT_PointerOrReference; + if (InTemplateArgument && NextToken && NextToken->is(tok::kw_noexcept)) return TT_BinaryOperator; @@ -3323,6 +3360,15 @@ Right.MatchingParen->is(TT_CastRParen)) { return true; } + // (T:! Addable) + if (Style.isCarbon()) { + if (Left.is(TT_JsTypeColon) && Right.is(tok::exclaim)) + return false; + if (Left.is(tok::exclaim) && Left.Previous && + Left.Previous->is(TT_JsTypeColon)) { + return true; + } + } if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon)) return false; if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java) @@ -3398,6 +3444,7 @@ tok::kw_true, tok::kw_false)) { return false; } + if (Left.is(tok::colon)) return !Left.is(TT_ObjCMethodExpr); if (Left.is(tok::coloncolon)) @@ -3504,6 +3551,8 @@ startsWithInitStatement(Line)))) { return false; } + if (Style.isCarbon() && Right.is(tok::r_square)) + return false; return Left.Previous && !Left.Previous->isOneOf( tok::l_paren, tok::coloncolon, tok::l_square); } @@ -3638,6 +3687,12 @@ return true; if (Left.is(tok::semi)) return true; + if (Style.isCarbon()) { + if (Left.isOneOf(Keywords.kw_match, Keywords.kw_var)) { + return Style.SpaceBeforeParensOptions.AfterControlStatements || + spaceRequiredBeforeParens(Right); + } + } if (Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while, tok::kw_switch, tok::kw_case, TT_ForEachMacro, TT_ObjCForIn) || Left.isIf(Line.Type != LT_PreprocessorDirective) || @@ -3908,6 +3963,9 @@ Right.is(tok::l_paren)) { return true; } + } else if (Style.isCarbon()) { + if (Right.is(TT_JsTypeColon)) + return false; } else if (Style.isJavaScript()) { if (Left.is(TT_FatArrow)) return true; @@ -4092,6 +4150,18 @@ return false; } + // (T:! Addable) + if (Style.isCarbon()) { + if (Left.is(tok::exclaim) && Left.Previous && + Left.Previous->is(TT_JsTypeColon)) { + return true; + } + if (Right.is(tok::l_paren) && Left.Previous && + Left.Previous->isOneOf(tok::kw_class, Keywords.kw_interface)) { + return false; + } + } + if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) || Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) { return true; Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -1143,6 +1143,11 @@ kw_with = &IdentTable.get("with"); kw_wor = &IdentTable.get("wor"); + // Carbon keywords + kw_me = &IdentTable.get("me"); + kw_fn = &IdentTable.get("fn"); + kw_match = &IdentTable.get("match"); + // Symbols that are treated as keywords. kw_verilogHash = &IdentTable.get("#"); kw_verilogHashHash = &IdentTable.get("##"); @@ -1172,6 +1177,9 @@ // Keywords from the Java section. kw_abstract, kw_extends, kw_implements, kw_instanceof, kw_interface}); + CarbonExtraKeywords = std::unordered_set<IdentifierInfo *>( + {kw_me, kw_package, kw_fn, kw_abstract}); + // Some keywords are not included here because they don't need special // treatment like `showcancelled` or they should be treated as identifiers // like `int` and `logic`. @@ -1406,6 +1414,11 @@ IdentifierInfo *kw_when; IdentifierInfo *kw_where; + // Carbon keywords + IdentifierInfo *kw_me; + IdentifierInfo *kw_fn; + IdentifierInfo *kw_match; + // Verilog keywords IdentifierInfo *kw_always; IdentifierInfo *kw_always_comb; @@ -1800,6 +1813,9 @@ /// The Verilog keywords beyond the C++ keyword set. std::unordered_set<IdentifierInfo *> VerilogExtraKeywords; + + /// The Carbon keywords beyond the C++ keyword set + std::unordered_set<IdentifierInfo *> CarbonExtraKeywords; }; } // namespace format Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -60,14 +60,15 @@ template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> { static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) { IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp); + IO.enumCase(Value, "Carbon", FormatStyle::LK_Carbon); + IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp); IO.enumCase(Value, "Java", FormatStyle::LK_Java); IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript); + IO.enumCase(Value, "Json", FormatStyle::LK_Json); IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC); IO.enumCase(Value, "Proto", FormatStyle::LK_Proto); IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen); IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto); - IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp); - IO.enumCase(Value, "Json", FormatStyle::LK_Json); } }; @@ -1501,6 +1502,9 @@ GoogleStyle.BreakStringLiterals = false; GoogleStyle.ColumnLimit = 100; GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; + } else if (Language == FormatStyle::LK_Carbon) { + GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; + GoogleStyle.ReflowComments = false; } return GoogleStyle; @@ -3487,6 +3491,8 @@ return FormatStyle::LK_TableGen; if (FileName.endswith_insensitive(".cs")) return FormatStyle::LK_CSharp; + if (FileName.endswith_insensitive(".carbon")) + return FormatStyle::LK_Carbon; if (FileName.endswith_insensitive(".json")) return FormatStyle::LK_Json; if (FileName.endswith_insensitive(".sv") || Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -2587,6 +2587,8 @@ enum LanguageKind : int8_t { /// Do not use. LK_None, + /// Should be used for Carbon + LK_Carbon, /// Should be used for C, C++. LK_Cpp, /// Should be used for C#. @@ -2614,6 +2616,7 @@ }; bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; } bool isCSharp() const { return Language == LK_CSharp; } + bool isCarbon() const { return Language == LK_Carbon; } bool isJson() const { return Language == LK_Json; } bool isJavaScript() const { return Language == LK_JavaScript; } bool isVerilog() const { return Language == LK_Verilog; } @@ -4292,6 +4295,8 @@ switch (Language) { case FormatStyle::LK_Cpp: return "C++"; + case FormatStyle::LK_Carbon: + return "Carbon"; case FormatStyle::LK_CSharp: return "CSharp"; case FormatStyle::LK_ObjC: Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -421,6 +421,7 @@ clang-format ------------ +- Basic Carbon Language Support. clang-extdef-mapping -------------------- Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -3184,6 +3184,9 @@ * ``LK_None`` (in configuration: ``None``) Do not use. + * ``LK_Carbon`` (in configuration: ``Carbon``) + Should be used for Carbon + * ``LK_Cpp`` (in configuration: ``Cpp``) Should be used for C, C++.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits