krasimir created this revision.
Herald added subscribers: cfe-commits, klimek.

Repository:
  rC Clang

https://reviews.llvm.org/D40909

Files:
  include/clang/Format/Format.h
  lib/Format/ContinuationIndenter.cpp
  lib/Format/ContinuationIndenter.h
  lib/Format/Format.cpp
  unittests/Format/FormatTest.cpp
  unittests/Format/FormatTestRawStrings.cpp

Index: unittests/Format/FormatTestRawStrings.cpp
===================================================================
--- unittests/Format/FormatTestRawStrings.cpp
+++ unittests/Format/FormatTestRawStrings.cpp
@@ -9,6 +9,8 @@
 
 #include "clang/Format/Format.h"
 
+#include <memory>
+
 #include "../Tooling/ReplacementTest.h"
 #include "FormatTestUtils.h"
 
@@ -19,6 +21,12 @@
 
 #define DEBUG_TYPE "format-test"
 
+#define DBG(A)                                                                 \
+  DEBUG({                                                                      \
+    llvm::dbgs() << __LINE__ << ":" << __func__ << ":" << #A << " = " << A     \
+                 << "\n";                                                      \
+  });
+
 using clang::tooling::ReplacementTest;
 using clang::tooling::toReplacements;
 
@@ -65,23 +73,40 @@
   FormatStyle getRawStringPbStyleWithColumns(unsigned ColumnLimit) {
     FormatStyle Style = getLLVMStyle();
     Style.ColumnLimit = ColumnLimit;
-    Style.RawStringFormats = {{/*Delimiter=*/"pb",
-                               /*Kind=*/FormatStyle::LK_TextProto,
-                               /*BasedOnStyle=*/"google"}};
+    Style.AdditionalLanguageStyles[FormatStyle::LK_TextProto] =
+        std::make_shared<FormatStyle>(
+            getGoogleStyle(FormatStyle::LK_TextProto));
+    Style.RawStringFormats = {{/*Language=*/FormatStyle::LK_TextProto,
+                               /*Delimiters=*/{"pb"},
+                               /*EnclosingFunctionNames=*/{},
+                               /*CanonicalDelimiter=*/""}};
     return Style;
   }
 
-  FormatStyle getRawStringLLVMCppStyleBasedOn(std::string BasedOnStyle) {
+  FormatStyle getRawStringLLVMCppStyleBasedOn(std::string Name) {
     FormatStyle Style = getLLVMStyle();
-    Style.RawStringFormats = {{/*Delimiter=*/"cpp",
-                               /*Kind=*/FormatStyle::LK_Cpp, BasedOnStyle}};
+    FormatStyle BasedOnStyle = getLLVMStyle();
+    getPredefinedStyle(Name, FormatStyle::LK_Cpp, &BasedOnStyle);
+    Style.AdditionalLanguageStyles[FormatStyle::LK_Cpp] =
+        std::make_shared<FormatStyle>(BasedOnStyle);
+    Style.RawStringFormats = {{/*Language=*/FormatStyle::LK_Cpp,
+                               /*Delimiters=*/{"cpp"},
+                               /*EnclosingFunctionNames=*/{},
+                               /*CanonicalDelimiter=*/""}};
+    DBG(BasedOnStyle.PointerAlignment);
     return Style;
   }
 
-  FormatStyle getRawStringGoogleCppStyleBasedOn(std::string BasedOnStyle) {
+  FormatStyle getRawStringGoogleCppStyleBasedOn(std::string Name) {
     FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp);
-    Style.RawStringFormats = {{/*Delimiter=*/"cpp",
-                               /*Kind=*/FormatStyle::LK_Cpp, BasedOnStyle}};
+    FormatStyle BasedOnStyle = getLLVMStyle();
+    getPredefinedStyle(Name, FormatStyle::LK_Cpp, &BasedOnStyle);
+    Style.AdditionalLanguageStyles[FormatStyle::LK_Cpp] =
+        std::make_shared<FormatStyle>(BasedOnStyle);
+    Style.RawStringFormats = {{/*Language=*/FormatStyle::LK_Cpp,
+                               /*Delimiters=*/{"cpp"},
+                               /*EnclosingFunctionNames=*/{},
+                               /*CanonicalDelimiter=*/""}};
     return Style;
   }
 
@@ -96,17 +121,19 @@
   // llvm style puts '*' on the right.
   // google style puts '*' on the left.
 
-  // Use the llvm style if the raw string style has no BasedOnStyle.
-  expect_eq(R"test(int *i = R"cpp(int *p = nullptr;)cpp")test",
-            format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
-                   getRawStringLLVMCppStyleBasedOn("")));
-
-  // Use the google style if the raw string style has BasedOnStyle=google.
+  // Use llvm style outside and the google style inside if the raw string style
+  // is based on google.
   expect_eq(R"test(int *i = R"cpp(int* p = nullptr;)cpp")test",
             format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
                    getRawStringLLVMCppStyleBasedOn("google")));
 
-  // Use the llvm style if the raw string style has no BasedOnStyle=llvm.
+  // Use llvm style if the raw string style has no BasedOnStyle.
+  expect_eq(R"test(int *i = R"cpp(int *p = nullptr;)cpp")test",
+            format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
+                   getRawStringLLVMCppStyleBasedOn("")));
+
+  // Use google style outside and the llvm style inside if the raw string style
+  // is based on llvm.
   expect_eq(R"test(int* i = R"cpp(int *p = nullptr;)cpp")test",
             format(R"test(int * i = R"cpp(int * p = nullptr;)cpp")test",
                    getRawStringGoogleCppStyleBasedOn("llvm")));
@@ -121,29 +148,6 @@
 s = R"PB(item:1)PB";
 t = R"pb(item:1)pb";)test",
                    getRawStringPbStyleWithColumns(40)));
-
-  FormatStyle MixedStyle = getLLVMStyle();
-  MixedStyle.RawStringFormats = {
-      {/*Delimiter=*/"cpp", /*Kind=*/FormatStyle::LK_Cpp,
-       /*BasedOnStyle=*/"llvm"},
-      {/*Delimiter=*/"CPP", /*Kind=*/FormatStyle::LK_Cpp,
-       /*BasedOnStyle=*/"google"}};
-
-  // Format the 'cpp' raw string with '*' on the right.
-  // Format the 'CPP' raw string with '*' on the left.
-  // Do not format the 'Cpp' raw string.
-  // Do not format non-raw strings.
-  expect_eq(R"test(
-a = R"cpp(int *i = 0;)cpp";
-b = R"CPP(int* j = 0;)CPP";
-c = R"Cpp(int * k = 0;)Cpp";
-d = R"cpp(int * k = 0;)Cpp";)test",
-            format(R"test(
-a = R"cpp(int * i = 0;)cpp";
-b = R"CPP(int * j = 0;)CPP";
-c = R"Cpp(int * k = 0;)Cpp";
-d = R"cpp(int * k = 0;)Cpp";)test",
-                   MixedStyle));
 }
 
 TEST_F(FormatTestRawStrings, ReformatsShortRawStringsOnSingleLine) {
@@ -210,9 +214,9 @@
 P p = TP(R"pb(item_1 <1>
               item_2: <2>
               item_3 {})pb");)test",
-      format(R"test(
+            format(R"test(
 P p = TP(R"pb(item_1<1> item_2:<2> item_3{ })pb");)test",
-          getRawStringPbStyleWithColumns(40)));
+                   getRawStringPbStyleWithColumns(40)));
 
   expect_eq(
       R"test(
@@ -515,7 +519,6 @@
             format(R"test(
 ASSERT_TRUE(ParseFromString(R"pb(item_1: 1 item_2: 2)pb"), ptr);)test",
                    getRawStringPbStyleWithColumns(40)));
-
 }
 
 TEST_F(FormatTestRawStrings, RawStringsInOperands) {
@@ -642,7 +645,6 @@
 auto S=(count<3)?R"pb(item_1:1)pb":R"pb(item_2:2,item_3:3)pb";
 )test",
                    getRawStringPbStyleWithColumns(40)));
-
 }
 
 TEST_F(FormatTestRawStrings, PrefixAndSuffixAlignment) {
@@ -728,6 +730,13 @@
                    getRawStringPbStyleWithColumns(20)));
 }
 
+TEST_F(FormatTestRawStrings, UpdatesToCanonicalDelimiters) {
+  FormatStyle Style = getRawStringPbStyleWithColumns(25);
+  Style.RawStringFormats[0].CanonicalDelimiter = "proto";
+  expect_eq(R"test(a = R"proto(key: value)proto";)test",
+            format(R"test(a = R"pb(key:value)pb";)test", Style));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -10402,16 +10402,27 @@
 
   Style.RawStringFormats.clear();
   std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
-      {"pb", FormatStyle::LK_TextProto, "llvm"},
-      {"cpp", FormatStyle::LK_Cpp, "google"}};
+      {FormatStyle::LK_TextProto,
+       {"pb", "proto"},
+       {"PARSE_TEXT_PROTO"},
+       "textproto"},
+      {FormatStyle::LK_Cpp, {"cc", "cpp"}, {"C_CODEBLOCK", "CPPEVAL"}, ""}};
 
   CHECK_PARSE("RawStringFormats:\n"
-              "  - Delimiter: 'pb'\n"
-              "    Language: TextProto\n"
-              "    BasedOnStyle: llvm\n"
-              "  - Delimiter: 'cpp'\n"
-              "    Language: Cpp\n"
-              "    BasedOnStyle: google",
+              "  - Language: TextProto\n"
+              "    Delimiters:\n"
+              "      - 'pb'\n"
+              "      - 'proto'\n"
+              "    EnclosingFunctionNames:\n"
+              "      - 'PARSE_TEXT_PROTO'\n"
+              "    CanonicalDelimiter: 'textproto'\n"
+              "  - Language: Cpp\n"
+              "    Delimiters:\n"
+              "      - 'cc'\n"
+              "      - 'cpp'\n"
+              "    EnclosingFunctionNames:\n"
+              "      - 'C_CODEBLOCK'\n"
+              "      - 'CPPEVAL'",
               RawStringFormats, ExpectedRawStringFormats);
 }
 
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -455,9 +455,10 @@
 
 template <> struct MappingTraits<FormatStyle::RawStringFormat> {
   static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
-    IO.mapOptional("Delimiter", Format.Delimiter);
     IO.mapOptional("Language", Format.Language);
-    IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);
+    IO.mapOptional("Delimiters", Format.Delimiters);
+    IO.mapOptional("EnclosingFunctionNames", Format.EnclosingFunctionNames);
+    IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);
   }
 };
 
@@ -641,7 +642,10 @@
   LLVMStyle.SpacesBeforeTrailingComments = 1;
   LLVMStyle.Standard = FormatStyle::LS_Cpp11;
   LLVMStyle.UseTab = FormatStyle::UT_Never;
-  LLVMStyle.RawStringFormats = {{"pb", FormatStyle::LK_TextProto, "google"}};
+  LLVMStyle.RawStringFormats = {
+      {FormatStyle::LK_TextProto, /*Delimiters=*/{"pb", "PB"},
+       /*EnclosingFunctionNames=*/{}, /*CanonicalDelimiter=*/""},
+  };
   LLVMStyle.ReflowComments = true;
   LLVMStyle.SpacesInParentheses = false;
   LLVMStyle.SpacesInSquareBrackets = false;
@@ -829,6 +833,8 @@
   return NoStyle;
 }
 
+/// \brief Gets a predefined style for the specified language by name.
+
 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
                         FormatStyle *Style) {
   if (Name.equals_lower("llvm")) {
@@ -888,14 +894,31 @@
   // Look for a suitable configuration starting from the end, so we can
   // find the configuration for the specific language first, and the default
   // configuration (which can only be at slot 0) after it.
+  bool LanguageFound = false;
   for (int i = Styles.size() - 1; i >= 0; --i) {
-    if (Styles[i].Language == Language ||
-        Styles[i].Language == FormatStyle::LK_None) {
+    if (!LanguageFound && (Styles[i].Language == Language ||
+                           Styles[i].Language == FormatStyle::LK_None)) {
       *Style = Styles[i];
       Style->Language = Language;
-      return make_error_code(ParseError::Success);
+      LanguageFound = true;
+    }
+    if (Styles[i].Language == FormatStyle::LK_None) {
+      for (unsigned AdditionalLanguage = 0;
+           AdditionalLanguage < FormatStyle::LK_End; ++AdditionalLanguage) {
+        FormatStyle AdditionalLanguageStyle = Styles[i];
+        AdditionalLanguageStyle.Language =
+            static_cast<FormatStyle::LanguageKind>(AdditionalLanguage);
+        if (!Style->AdditionalLanguageStyles[AdditionalLanguage])
+          Style->AdditionalLanguageStyles[AdditionalLanguage].reset(
+              new FormatStyle(AdditionalLanguageStyle));
+      }
+      continue;
     }
+    Style->AdditionalLanguageStyles[Styles[i].Language].reset(
+        new FormatStyle(Styles[i]));
   }
+  if (LanguageFound)
+    return make_error_code(ParseError::Success);
   return make_error_code(ParseError::Unsuitable);
 }
 
Index: lib/Format/ContinuationIndenter.h
===================================================================
--- lib/Format/ContinuationIndenter.h
+++ lib/Format/ContinuationIndenter.h
@@ -37,11 +37,11 @@
 class WhitespaceManager;
 
 struct RawStringFormatStyleManager {
-  llvm::StringMap<FormatStyle> DelimiterStyle;
+  llvm::StringMap<const FormatStyle*> DelimiterStyle;
 
   RawStringFormatStyleManager(const FormatStyle &CodeStyle);
 
-  llvm::Optional<FormatStyle> get(StringRef Delimiter) const;
+  const FormatStyle *getDelimiterStyle(StringRef Delimiter) const;
 };
 
 class ContinuationIndenter {
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -23,6 +23,11 @@
 
 #define DEBUG_TYPE "format-indenter"
 
+#define DBG(A) DEBUG({ \
+  llvm::dbgs() << __LINE__ << ":" << __func__ << ":" \
+               << #A << " = " << A << "\n"; \
+});
+
 namespace clang {
 namespace format {
 
@@ -102,25 +107,32 @@
   return Delimiter;
 }
 
+static StringRef
+getCanonicalRawStringDelimiter(const FormatStyle &Style,
+                               FormatStyle::LanguageKind Language) {
+  for (const auto &Format : llvm::reverse(Style.RawStringFormats)) {
+    if (Format.Language == Language)
+      return StringRef(Format.CanonicalDelimiter);
+  }
+  return "";
+}
+
 RawStringFormatStyleManager::RawStringFormatStyleManager(
     const FormatStyle &CodeStyle) {
   for (const auto &RawStringFormat : CodeStyle.RawStringFormats) {
-    FormatStyle Style;
-    if (!getPredefinedStyle(RawStringFormat.BasedOnStyle,
-                            RawStringFormat.Language, &Style)) {
-      Style = getLLVMStyle();
-      Style.Language = RawStringFormat.Language;
+    for (StringRef Delimiter : RawStringFormat.Delimiters) {
+      DelimiterStyle.insert(
+          {Delimiter,
+           CodeStyle.AdditionalLanguageStyles[RawStringFormat.Language].get()});
     }
-    Style.ColumnLimit = CodeStyle.ColumnLimit;
-    DelimiterStyle.insert({RawStringFormat.Delimiter, Style});
   }
 }
 
-llvm::Optional<FormatStyle>
-RawStringFormatStyleManager::get(StringRef Delimiter) const {
+const FormatStyle *
+RawStringFormatStyleManager::getDelimiterStyle(StringRef Delimiter) const {
   auto It = DelimiterStyle.find(Delimiter);
   if (It == DelimiterStyle.end())
-    return None;
+    return nullptr;
   return It->second;
 }
 
@@ -1291,14 +1303,22 @@
     const FormatToken &Current, LineState &State,
     const FormatStyle &RawStringStyle, bool DryRun) {
   unsigned StartColumn = State.Column - Current.ColumnWidth;
-  auto Delimiter = *getRawStringDelimiter(Current.TokenText);
+  StringRef OldDelimiter = *getRawStringDelimiter(Current.TokenText);
+  StringRef NewDelimiter =
+      getCanonicalRawStringDelimiter(Style, RawStringStyle.Language);
+  if (NewDelimiter.empty() || OldDelimiter.empty())
+    NewDelimiter = OldDelimiter;
+  bool UpdateDelimiter = (NewDelimiter != OldDelimiter);
+
   // The text of a raw string is between the leading 'R"delimiter(' and the
   // trailing 'delimiter)"'.
-  unsigned PrefixSize = 3 + Delimiter.size();
-  unsigned SuffixSize = 2 + Delimiter.size();
+  unsigned OldPrefixSize = 3 + OldDelimiter.size();
+  unsigned NewPrefixSize = 3 + NewDelimiter.size();
+  unsigned OldSuffixSize = 2 + OldDelimiter.size();
+  unsigned NewSuffixSize = 2 + NewDelimiter.size();
 
   // The first start column is the column the raw text starts.
-  unsigned FirstStartColumn = StartColumn + PrefixSize;
+  unsigned FirstStartColumn = StartColumn + NewPrefixSize;
 
   // The next start column is the intended indentation a line break inside
   // the raw string at level 0. It is determined by the following rules:
@@ -1309,7 +1329,7 @@
   // These rules have the advantage that the formatted content both does not
   // violate the rectangle rule and visually flows within the surrounding
   // source.
-  bool ContentStartsOnNewline = Current.TokenText[PrefixSize] == '\n';
+  bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n';
   unsigned NextStartColumn = ContentStartsOnNewline
                                  ? State.Stack.back().Indent + Style.IndentWidth
                                  : FirstStartColumn;
@@ -1323,11 +1343,11 @@
   //   - if the raw string prefix does not start on a newline, it is the current
   //     indent.
   unsigned LastStartColumn = Current.NewlinesBefore
-                                 ? FirstStartColumn - PrefixSize
+                                 ? FirstStartColumn - NewPrefixSize
                                  : State.Stack.back().Indent;
 
   std::string RawText =
-      Current.TokenText.substr(PrefixSize).drop_back(SuffixSize);
+      Current.TokenText.substr(OldPrefixSize).drop_back(OldSuffixSize);
 
   std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat(
       RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
@@ -1341,8 +1361,33 @@
     return 0;
   }
   if (!DryRun) {
+    if (UpdateDelimiter) {
+      // In 'R"delimiter(...', the delimiter starts 2 characters after the start
+      // of the token.
+      SourceLocation PrefixDelimiterStart =
+          Current.Tok.getLocation().getLocWithOffset(2);
+      auto PrefixErr = Whitespaces.addReplacement(tooling::Replacement(
+          SourceMgr, PrefixDelimiterStart, OldDelimiter.size(), NewDelimiter));
+      if (PrefixErr) {
+        llvm::errs()
+            << "Failed to update the prefix delimiter of a raw string: "
+            << llvm::toString(std::move(PrefixErr)) << "\n";
+      }
+      // In 'R"delimiter(...)delimiter"', the suffix delimiter starts at
+      // position length - 1 - |delimiter|.
+      SourceLocation SuffixDelimiterStart =
+          Current.Tok.getLocation().getLocWithOffset(Current.TokenText.size() -
+                                                     1 - OldDelimiter.size());
+      auto SuffixErr = Whitespaces.addReplacement(tooling::Replacement(
+          SourceMgr, SuffixDelimiterStart, OldDelimiter.size(), NewDelimiter));
+      if (SuffixErr) {
+        llvm::errs()
+            << "Failed to update the suffix delimiter of a raw string: "
+            << llvm::toString(std::move(SuffixErr)) << "\n";
+      }
+    }
     SourceLocation OriginLoc =
-        Current.Tok.getLocation().getLocWithOffset(PrefixSize);
+        Current.Tok.getLocation().getLocWithOffset(OldPrefixSize);
     for (const tooling::Replacement &Fix : Fixes.first) {
       auto Err = Whitespaces.addReplacement(tooling::Replacement(
           SourceMgr, OriginLoc.getLocWithOffset(Fix.getOffset()),
@@ -1355,7 +1400,7 @@
   }
   unsigned RawLastLineEndColumn = getLastLineEndColumn(
       *NewCode, FirstStartColumn, Style.TabWidth, Encoding);
-  State.Column = RawLastLineEndColumn + SuffixSize;
+  State.Column = RawLastLineEndColumn + NewSuffixSize;
   return Fixes.second;
 }
 
@@ -1383,6 +1428,7 @@
   // that can be reformatted.
   auto RawStringStyle = getRawStringStyle(Current, State);
   if (RawStringStyle) {
+    DBG(RawStringStyle->PointerAlignment);
     Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun);
   } else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
     // Don't break multi-line tokens other than block comments and raw string
@@ -1436,10 +1482,13 @@
   auto Delimiter = getRawStringDelimiter(Current.TokenText);
   if (!Delimiter)
     return None;
-  auto RawStringStyle = RawStringFormats.get(*Delimiter);
-  if (!RawStringStyle)
+  DBG(*Delimiter);
+  auto DelimiterStyle = RawStringFormats.getDelimiterStyle(*Delimiter);
+  if (!DelimiterStyle)
     return None;
-  RawStringStyle->ColumnLimit = getColumnLimit(State);
+  DBG(DelimiterStyle->PointerAlignment);
+  FormatStyle RawStringStyle = *DelimiterStyle;
+  RawStringStyle.ColumnLimit = getColumnLimit(State);
   return RawStringStyle;
 }
 
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -18,6 +18,8 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include <array>
 #include <system_error>
 
 namespace clang {
@@ -1211,7 +1213,9 @@
     LK_TableGen,
     /// Should be used for Protocol Buffer messages in text format
     /// (https://developers.google.com/protocol-buffers/).
-    LK_TextProto
+    LK_TextProto,
+    /// Do not use. Keep at last position.
+    LK_End,
   };
   bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
 
@@ -1363,17 +1367,16 @@
 
   /// See documentation of ``RawStringFormats``.
   struct RawStringFormat {
-    /// \brief The delimiter that this raw string format matches.
-    std::string Delimiter;
     /// \brief The language of this raw string.
     LanguageKind Language;
-    /// \brief The style name on which this raw string format is based on.
-    /// If not specified, the raw string format is based on the style that this
-    /// format is based on.
-    std::string BasedOnStyle;
+    std::vector<std::string> Delimiters;
+    std::vector<std::string> EnclosingFunctionNames;
+    std::string CanonicalDelimiter;
+
     bool operator==(const RawStringFormat &Other) const {
-      return Delimiter == Other.Delimiter && Language == Other.Language &&
-             BasedOnStyle == Other.BasedOnStyle;
+      return Language == Other.Language && Delimiters == Other.Delimiters &&
+             EnclosingFunctionNames == Other.EnclosingFunctionNames &&
+             CanonicalDelimiter == Other.CanonicalDelimiter;
     }
   };
 
@@ -1685,8 +1688,10 @@
            Standard == R.Standard && TabWidth == R.TabWidth &&
            UseTab == R.UseTab;
   }
-};
 
+  std::array<std::shared_ptr<FormatStyle>, FormatStyle::LK_End>
+      AdditionalLanguageStyles;
+};
 /// \brief Returns a format style complying with the LLVM coding standards:
 /// http://llvm.org/docs/CodingStandards.html.
 FormatStyle getLLVMStyle();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to