[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-18 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor updated this revision to Diff 292781.
fodinabor marked an inline comment as done.
fodinabor added a comment.

Fix the nit :)
Anyone with access may commit this now (ideally ofc someone with a final 
opinion on the clang-format part).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

Files:
  clang/docs/ClangFormat.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/FormatTest.cpp
  llvm/include/llvm/Support/YAMLParser.h
  llvm/include/llvm/Support/YAMLTraits.h
  llvm/lib/Support/YAMLParser.cpp
  llvm/lib/Support/YAMLTraits.cpp
  llvm/unittests/ObjectYAML/YAMLTest.cpp

Index: llvm/unittests/ObjectYAML/YAMLTest.cpp
===
--- llvm/unittests/ObjectYAML/YAMLTest.cpp
+++ llvm/unittests/ObjectYAML/YAMLTest.cpp
@@ -35,3 +35,21 @@
   YOut << BH;
   EXPECT_NE(OS.str().find("''"), StringRef::npos);
 }
+
+TEST(ObjectYAML, UnknownOption) {
+  StringRef InputYAML = "InvalidKey: InvalidValue\n"
+"Binary: \n";
+  BinaryHolder BH;
+  yaml::Input Input(InputYAML);
+  // test 1: default in trying to parse invalid key is an error case.
+  Input >> BH;
+  EXPECT_EQ(Input.error().value(), 22);
+
+  // test 2: only warn about invalid key if actively set.
+  yaml::Input Input2(InputYAML);
+  BinaryHolder BH2;
+  Input2.setAllowUnknownKeys(true);
+  Input2 >> BH2;
+  EXPECT_EQ(BH2.Binary, yaml::BinaryRef(""));
+  EXPECT_EQ(Input2.error().value(), 0);
+}
Index: llvm/lib/Support/YAMLTraits.cpp
===
--- llvm/lib/Support/YAMLTraits.cpp
+++ llvm/lib/Support/YAMLTraits.cpp
@@ -48,6 +48,10 @@
   Ctxt = Context;
 }
 
+void IO::setAllowUnknownKeys(bool Allow) {
+  llvm_unreachable("Only supported for Input");
+}
+
 //===--===//
 //  Input
 //===--===//
@@ -197,8 +201,12 @@
 return;
   for (const auto  : MN->Mapping) {
 if (!is_contained(MN->ValidKeys, NN.first())) {
-  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
-  break;
+  HNode *ReportNode = NN.second.get();
+  if (!AllowUnknownKeys) {
+setError(ReportNode, Twine("unknown key '") + NN.first() + "'");
+break;
+  } else
+reportWarning(ReportNode, Twine("unknown key '") + NN.first() + "'");
 }
   }
 }
@@ -370,6 +378,11 @@
   EC = make_error_code(errc::invalid_argument);
 }
 
+void Input::reportWarning(HNode *hnode, const Twine ) {
+  assert(hnode && "HNode must not be NULL");
+  Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
+}
+
 std::unique_ptr Input::createHNodes(Node *N) {
   SmallString<128> StringStorage;
   if (ScalarNode *SN = dyn_cast(N)) {
@@ -428,6 +441,8 @@
   setError(CurrentNode, Message);
 }
 
+void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
+
 bool Input::canElideEmptySequence() {
   return false;
 }
Index: llvm/lib/Support/YAMLParser.cpp
===
--- llvm/lib/Support/YAMLParser.cpp
+++ llvm/lib/Support/YAMLParser.cpp
@@ -1775,12 +1775,9 @@
 
 bool Stream::failed() { return scanner->failed(); }
 
-void Stream::printError(Node *N, const Twine ) {
+void Stream::printError(Node *N, const Twine , SourceMgr::DiagKind Kind) {
   SMRange Range = N ? N->getSourceRange() : SMRange();
-  scanner->printError( Range.Start
- , SourceMgr::DK_Error
- , Msg
- , Range);
+  scanner->printError(Range.Start, Kind, Msg, Range);
 }
 
 document_iterator Stream::begin() {
Index: llvm/include/llvm/Support/YAMLTraits.h
===
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -789,6 +789,7 @@
   virtual NodeKind getNodeKind() = 0;
 
   virtual void setError(const Twine &) = 0;
+  virtual void setAllowUnknownKeys(bool Allow);
 
   template 
   void enumCase(T , const char* Str, const T ConstVal) {
@@ -1495,6 +1496,9 @@
   void setError(HNode *hnode, const Twine );
   void setError(Node *node, const Twine );
 
+  void reportWarning(HNode *hnode, const Twine );
+  void reportWarning(Node *hnode, const Twine );
+
 public:
   // These are only used by operator>>. They could be private
   // if those templated things could be made friends.
@@ -1504,6 +1508,8 @@
   /// Returns the current node that's being parsed by the YAML Parser.
   const Node *getCurrentNode() const;
 
+  void setAllowUnknownKeys(bool Allow) override;
+
 private:
   SourceMgr   SrcMgr; // must be before Strm
   std::unique_ptr Strm;
@@ -1514,6 +1520,7 @@
   std::vector   BitValuesUsed;
  

[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-16 Thread George Rimar via Phabricator via cfe-commits
grimar accepted this revision.
grimar added a comment.
This revision is now accepted and ready to land.

LGTM. It worth wainting for a second approvement and/or other comments to 
verify that people are happy with doing this for `clang-format`.




Comment at: clang/unittests/Format/FormatTest.cpp:16062
   FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int 
i;")));
   auto Style7 = getStyle("file", "/d/.clang-format", "LLVM", "", );
   ASSERT_FALSE((bool)Style7);

nit: since you have `Style7b`, this perhaps should be `Style7a`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-15 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor updated this revision to Diff 291826.
fodinabor marked 9 inline comments as done.
fodinabor added a comment.

Unit test cleanups.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

Files:
  clang/docs/ClangFormat.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/FormatTest.cpp
  llvm/include/llvm/Support/YAMLParser.h
  llvm/include/llvm/Support/YAMLTraits.h
  llvm/lib/Support/YAMLParser.cpp
  llvm/lib/Support/YAMLTraits.cpp
  llvm/unittests/ObjectYAML/YAMLTest.cpp

Index: llvm/unittests/ObjectYAML/YAMLTest.cpp
===
--- llvm/unittests/ObjectYAML/YAMLTest.cpp
+++ llvm/unittests/ObjectYAML/YAMLTest.cpp
@@ -35,3 +35,21 @@
   YOut << BH;
   EXPECT_NE(OS.str().find("''"), StringRef::npos);
 }
+
+TEST(ObjectYAML, UnknownOption) {
+  StringRef InputYAML = "InvalidKey: InvalidValue\n"
+"Binary: \n";
+  BinaryHolder BH;
+  yaml::Input Input(InputYAML);
+  // test 1: default in trying to parse invalid key is an error case.
+  Input >> BH;
+  EXPECT_EQ(Input.error().value(), 22);
+
+  // test 2: only warn about invalid key if actively set.
+  yaml::Input Input2(InputYAML);
+  BinaryHolder BH2;
+  Input2.setAllowUnknownKeys(true);
+  Input2 >> BH2;
+  EXPECT_EQ(BH2.Binary, yaml::BinaryRef(""));
+  EXPECT_EQ(Input2.error().value(), 0);
+}
Index: llvm/lib/Support/YAMLTraits.cpp
===
--- llvm/lib/Support/YAMLTraits.cpp
+++ llvm/lib/Support/YAMLTraits.cpp
@@ -48,6 +48,10 @@
   Ctxt = Context;
 }
 
+void IO::setAllowUnknownKeys(bool Allow) {
+  llvm_unreachable("Only supported for Input");
+}
+
 //===--===//
 //  Input
 //===--===//
@@ -197,8 +201,12 @@
 return;
   for (const auto  : MN->Mapping) {
 if (!is_contained(MN->ValidKeys, NN.first())) {
-  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
-  break;
+  HNode *ReportNode = NN.second.get();
+  if (!AllowUnknownKeys) {
+setError(ReportNode, Twine("unknown key '") + NN.first() + "'");
+break;
+  } else
+reportWarning(ReportNode, Twine("unknown key '") + NN.first() + "'");
 }
   }
 }
@@ -370,6 +378,11 @@
   EC = make_error_code(errc::invalid_argument);
 }
 
+void Input::reportWarning(HNode *hnode, const Twine ) {
+  assert(hnode && "HNode must not be NULL");
+  Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
+}
+
 std::unique_ptr Input::createHNodes(Node *N) {
   SmallString<128> StringStorage;
   if (ScalarNode *SN = dyn_cast(N)) {
@@ -428,6 +441,8 @@
   setError(CurrentNode, Message);
 }
 
+void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
+
 bool Input::canElideEmptySequence() {
   return false;
 }
Index: llvm/lib/Support/YAMLParser.cpp
===
--- llvm/lib/Support/YAMLParser.cpp
+++ llvm/lib/Support/YAMLParser.cpp
@@ -1775,12 +1775,9 @@
 
 bool Stream::failed() { return scanner->failed(); }
 
-void Stream::printError(Node *N, const Twine ) {
+void Stream::printError(Node *N, const Twine , SourceMgr::DiagKind Kind) {
   SMRange Range = N ? N->getSourceRange() : SMRange();
-  scanner->printError( Range.Start
- , SourceMgr::DK_Error
- , Msg
- , Range);
+  scanner->printError(Range.Start, Kind, Msg, Range);
 }
 
 document_iterator Stream::begin() {
Index: llvm/include/llvm/Support/YAMLTraits.h
===
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -789,6 +789,7 @@
   virtual NodeKind getNodeKind() = 0;
 
   virtual void setError(const Twine &) = 0;
+  virtual void setAllowUnknownKeys(bool Allow);
 
   template 
   void enumCase(T , const char* Str, const T ConstVal) {
@@ -1495,6 +1496,9 @@
   void setError(HNode *hnode, const Twine );
   void setError(Node *node, const Twine );
 
+  void reportWarning(HNode *hnode, const Twine );
+  void reportWarning(Node *hnode, const Twine );
+
 public:
   // These are only used by operator>>. They could be private
   // if those templated things could be made friends.
@@ -1504,6 +1508,8 @@
   /// Returns the current node that's being parsed by the YAML Parser.
   const Node *getCurrentNode() const;
 
+  void setAllowUnknownKeys(bool Allow) override;
+
 private:
   SourceMgr   SrcMgr; // must be before Strm
   std::unique_ptr Strm;
@@ -1514,6 +1520,7 @@
   std::vector   BitValuesUsed;
   HNode *CurrentNode = nullptr;
   boolScalarMatchFound = false;
+  bool 

[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-15 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor added a comment.

All comments should be adressed now.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-14 Thread George Rimar via Phabricator via cfe-commits
grimar added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:16079
+  auto Style9 = getStyle("file", "/d/.clang-format", "LLVM", "", , true);
+  ASSERT_TRUE((bool)Style9);
 }

It looks like it is very similar to "Test 7:" and can be a part of it?
E.g:


```
...
llvm::consumeError(Style7a.takeError());

// 
auto Style7b = getStyle("file", "/d/.clang-format", "LLVM", "", , true);
ASSERT_TRUE((bool)Style8);
```



Comment at: llvm/unittests/ObjectYAML/YAMLTest.cpp:39
+
+TEST(ObjectYAML, UnkownOption) {
+  std::string InputYAML = "Binary: \n"

Unk**n**ownOption



Comment at: llvm/unittests/ObjectYAML/YAMLTest.cpp:40
+TEST(ObjectYAML, UnkownOption) {
+  std::string InputYAML = "Binary: \n"
+  "InvalidKey: InvalidValue";

`std::string`->`StringRef`?



Comment at: llvm/unittests/ObjectYAML/YAMLTest.cpp:41
+  std::string InputYAML = "Binary: \n"
+  "InvalidKey: InvalidValue";
+  BinaryHolder BH;

Will this work if we switch the order of `InvalidKey` and `Binary`?

```
  std::string InputYAML = "InvalidKey: InvalidValue\n"
  "Binary: ";
```

I expect that yes and I think it is reasonable to do it to show that we don't 
stop parsing an YAML
when there is an unknown key.



Comment at: llvm/unittests/ObjectYAML/YAMLTest.cpp:44
+  llvm::yaml::Input Input(InputYAML);
+  // test 1: default in trying to parse invalid key is an error case
+  Input >> BH;

No full stop at the end.



Comment at: llvm/unittests/ObjectYAML/YAMLTest.cpp:57
+  EXPECT_EQ(BH2.Binary, BH_GT.Binary);
+  EXPECT_EQ(Input2.error().value(), 0);
+}

Do you need `BH_GT`? Can it be just:

```
  // test 2: only warn about invalid key if actively set.
  llvm::yaml::Input Input2(InputYAML);
  BinaryHolder BH2;
  Input2.setAllowUnknownKeys(true);
  Input2 >> BH2;
  EXPECT_EQ(Input2.error().value(), 0);
  EXPECT_EQ(BH2.Binary, yaml::BinaryRef(""));
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-12 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor updated this revision to Diff 291405.
fodinabor added a comment.

Address review comments, copy the help text into docs and add some basic unit 
tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

Files:
  clang/docs/ClangFormat.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/FormatTest.cpp
  llvm/include/llvm/Support/YAMLParser.h
  llvm/include/llvm/Support/YAMLTraits.h
  llvm/lib/Support/YAMLParser.cpp
  llvm/lib/Support/YAMLTraits.cpp
  llvm/unittests/ObjectYAML/YAMLTest.cpp

Index: llvm/unittests/ObjectYAML/YAMLTest.cpp
===
--- llvm/unittests/ObjectYAML/YAMLTest.cpp
+++ llvm/unittests/ObjectYAML/YAMLTest.cpp
@@ -35,3 +35,24 @@
   YOut << BH;
   EXPECT_NE(OS.str().find("''"), StringRef::npos);
 }
+
+TEST(ObjectYAML, UnkownOption) {
+  std::string InputYAML = "Binary: \n"
+  "InvalidKey: InvalidValue";
+  BinaryHolder BH;
+  llvm::yaml::Input Input(InputYAML);
+  // test 1: default in trying to parse invalid key is an error case
+  Input >> BH;
+  EXPECT_EQ(Input.error().value(), 22);
+
+  // test 2: only warn about invalid key if actively set.
+  llvm::yaml::Input Input2(InputYAML);
+  BinaryHolder BH2;
+  Input2.setAllowUnknownKeys(true);
+  Input2 >> BH2;
+
+  BinaryHolder BH_GT;
+  BH_GT.Binary = yaml::BinaryRef("");
+  EXPECT_EQ(BH2.Binary, BH_GT.Binary);
+  EXPECT_EQ(Input2.error().value(), 0);
+}
Index: llvm/lib/Support/YAMLTraits.cpp
===
--- llvm/lib/Support/YAMLTraits.cpp
+++ llvm/lib/Support/YAMLTraits.cpp
@@ -48,6 +48,10 @@
   Ctxt = Context;
 }
 
+void IO::setAllowUnknownKeys(bool Allow) {
+  llvm_unreachable("Only supported for Input");
+}
+
 //===--===//
 //  Input
 //===--===//
@@ -197,8 +201,12 @@
 return;
   for (const auto  : MN->Mapping) {
 if (!is_contained(MN->ValidKeys, NN.first())) {
-  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
-  break;
+  HNode *ReportNode = NN.second.get();
+  if (!AllowUnknownKeys) {
+setError(ReportNode, Twine("unknown key '") + NN.first() + "'");
+break;
+  } else
+reportWarning(ReportNode, Twine("unknown key '") + NN.first() + "'");
 }
   }
 }
@@ -370,6 +378,11 @@
   EC = make_error_code(errc::invalid_argument);
 }
 
+void Input::reportWarning(HNode *hnode, const Twine ) {
+  assert(hnode && "HNode must not be NULL");
+  Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
+}
+
 std::unique_ptr Input::createHNodes(Node *N) {
   SmallString<128> StringStorage;
   if (ScalarNode *SN = dyn_cast(N)) {
@@ -428,6 +441,8 @@
   setError(CurrentNode, Message);
 }
 
+void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
+
 bool Input::canElideEmptySequence() {
   return false;
 }
Index: llvm/lib/Support/YAMLParser.cpp
===
--- llvm/lib/Support/YAMLParser.cpp
+++ llvm/lib/Support/YAMLParser.cpp
@@ -1775,12 +1775,9 @@
 
 bool Stream::failed() { return scanner->failed(); }
 
-void Stream::printError(Node *N, const Twine ) {
+void Stream::printError(Node *N, const Twine , SourceMgr::DiagKind Kind) {
   SMRange Range = N ? N->getSourceRange() : SMRange();
-  scanner->printError( Range.Start
- , SourceMgr::DK_Error
- , Msg
- , Range);
+  scanner->printError(Range.Start, Kind, Msg, Range);
 }
 
 document_iterator Stream::begin() {
Index: llvm/include/llvm/Support/YAMLTraits.h
===
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -789,6 +789,7 @@
   virtual NodeKind getNodeKind() = 0;
 
   virtual void setError(const Twine &) = 0;
+  virtual void setAllowUnknownKeys(bool Allow);
 
   template 
   void enumCase(T , const char* Str, const T ConstVal) {
@@ -1495,6 +1496,9 @@
   void setError(HNode *hnode, const Twine );
   void setError(Node *node, const Twine );
 
+  void reportWarning(HNode *hnode, const Twine );
+  void reportWarning(Node *hnode, const Twine );
+
 public:
   // These are only used by operator>>. They could be private
   // if those templated things could be made friends.
@@ -1504,6 +1508,8 @@
   /// Returns the current node that's being parsed by the YAML Parser.
   const Node *getCurrentNode() const;
 
+  void setAllowUnknownKeys(bool Allow) override;
+
 private:
   SourceMgr   SrcMgr; // must be before Strm
   std::unique_ptr Strm;
@@ -1514,6 +1520,7 @@
   std::vector   BitValuesUsed;
   HNode 

[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-09 Thread George Rimar via Phabricator via cfe-commits
grimar added inline comments.



Comment at: llvm/lib/Support/YAMLTraits.cpp:204
 if (!is_contained(MN->ValidKeys, NN.first())) {
-  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
-  break;
+  auto ReportNode = NN.second.get();
+  auto ReportMessage = Twine("unknown key '") + NN.first() + "'";

Please don't use `auto` when the variable type is not obvious.
Use the real type name instead.



Comment at: llvm/lib/Support/YAMLTraits.cpp:205
+  auto ReportNode = NN.second.get();
+  auto ReportMessage = Twine("unknown key '") + NN.first() + "'";
+  if (!AllowUnknownKeys) {

The same here, but also the result type here is `Twine`, and you shouldn't use 
it like this. Documentation says:
"A Twine is not intended for use directly and should not be stored, its 
implementation relies on the ability to store pointers to temporary stack 
objects which may be deallocated at the end of a statement. Twines should only 
be used accepted as const references in arguments, when an API wishes to accept 
possibly-concatenated strings."
(https://llvm.org/doxygen/classllvm_1_1Twine.html#details)

You can probably inline it or use `std::string`, since this is a error path 
only code.



Comment at: llvm/lib/Support/YAMLTraits.cpp:387
+
+void Input::reportWarning(Node *node, const Twine ) {
+  Strm->printError(node, message, SourceMgr::DK_Warning);

Why do you need both `reportWarning` methods? I think you can have only one for 
now.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-08 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor updated this revision to Diff 290461.
fodinabor added a comment.

Remove test entry form .clang-format :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

Files:
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  llvm/include/llvm/Support/YAMLParser.h
  llvm/include/llvm/Support/YAMLTraits.h
  llvm/lib/Support/YAMLParser.cpp
  llvm/lib/Support/YAMLTraits.cpp

Index: llvm/lib/Support/YAMLTraits.cpp
===
--- llvm/lib/Support/YAMLTraits.cpp
+++ llvm/lib/Support/YAMLTraits.cpp
@@ -48,6 +48,10 @@
   Ctxt = Context;
 }
 
+void IO::setAllowUnknownKeys(bool Allow) {
+  llvm_unreachable("Only supported for Input");
+}
+
 //===--===//
 //  Input
 //===--===//
@@ -197,8 +201,13 @@
 return;
   for (const auto  : MN->Mapping) {
 if (!is_contained(MN->ValidKeys, NN.first())) {
-  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
-  break;
+  auto ReportNode = NN.second.get();
+  auto ReportMessage = Twine("unknown key '") + NN.first() + "'";
+  if (!AllowUnknownKeys) {
+setError(ReportNode, ReportMessage);
+break;
+  } else
+reportWarning(ReportNode, ReportMessage);
 }
   }
 }
@@ -370,6 +379,15 @@
   EC = make_error_code(errc::invalid_argument);
 }
 
+void Input::reportWarning(HNode *hnode, const Twine ) {
+  assert(hnode && "HNode must not be NULL");
+  reportWarning(hnode->_node, message);
+}
+
+void Input::reportWarning(Node *node, const Twine ) {
+  Strm->printError(node, message, SourceMgr::DK_Warning);
+}
+
 std::unique_ptr Input::createHNodes(Node *N) {
   SmallString<128> StringStorage;
   if (ScalarNode *SN = dyn_cast(N)) {
@@ -428,6 +446,8 @@
   setError(CurrentNode, Message);
 }
 
+void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
+
 bool Input::canElideEmptySequence() {
   return false;
 }
Index: llvm/lib/Support/YAMLParser.cpp
===
--- llvm/lib/Support/YAMLParser.cpp
+++ llvm/lib/Support/YAMLParser.cpp
@@ -1775,12 +1775,9 @@
 
 bool Stream::failed() { return scanner->failed(); }
 
-void Stream::printError(Node *N, const Twine ) {
+void Stream::printError(Node *N, const Twine , SourceMgr::DiagKind Kind) {
   SMRange Range = N ? N->getSourceRange() : SMRange();
-  scanner->printError( Range.Start
- , SourceMgr::DK_Error
- , Msg
- , Range);
+  scanner->printError(Range.Start, Kind, Msg, Range);
 }
 
 document_iterator Stream::begin() {
Index: llvm/include/llvm/Support/YAMLTraits.h
===
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -789,6 +789,7 @@
   virtual NodeKind getNodeKind() = 0;
 
   virtual void setError(const Twine &) = 0;
+  virtual void setAllowUnknownKeys(bool Allow);
 
   template 
   void enumCase(T , const char* Str, const T ConstVal) {
@@ -1495,6 +1496,9 @@
   void setError(HNode *hnode, const Twine );
   void setError(Node *node, const Twine );
 
+  void reportWarning(HNode *hnode, const Twine );
+  void reportWarning(Node *hnode, const Twine );
+
 public:
   // These are only used by operator>>. They could be private
   // if those templated things could be made friends.
@@ -1504,6 +1508,8 @@
   /// Returns the current node that's being parsed by the YAML Parser.
   const Node *getCurrentNode() const;
 
+  void setAllowUnknownKeys(bool Allow) override;
+
 private:
   SourceMgr   SrcMgr; // must be before Strm
   std::unique_ptr Strm;
@@ -1514,6 +1520,7 @@
   std::vector   BitValuesUsed;
   HNode *CurrentNode = nullptr;
   boolScalarMatchFound = false;
+  bool AllowUnknownKeys = false;
 };
 
 ///
Index: llvm/include/llvm/Support/YAMLParser.h
===
--- llvm/include/llvm/Support/YAMLParser.h
+++ llvm/include/llvm/Support/YAMLParser.h
@@ -40,6 +40,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SourceMgr.h"
 #include 
 #include 
 #include 
@@ -51,7 +52,6 @@
 namespace llvm {
 
 class MemoryBufferRef;
-class SourceMgr;
 class raw_ostream;
 class Twine;
 
@@ -100,7 +100,8 @@
 return !failed();
   }
 
-  void printError(Node *N, const Twine );
+  void printError(Node *N, const Twine ,
+  SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
 
 private:
   friend class Document;
Index: clang/tools/clang-format/ClangFormat.cpp

[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-08 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor updated this revision to Diff 290460.
fodinabor marked 9 inline comments as done.
fodinabor added a comment.

Incorporating review comments:

- renaming option to -Wno-error=unknown and adding warning in description
- emit warnings instead of fully ignoring the issues

Documentation and unit tests will follow


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

Files:
  .clang-format
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  llvm/include/llvm/Support/YAMLParser.h
  llvm/include/llvm/Support/YAMLTraits.h
  llvm/lib/Support/YAMLParser.cpp
  llvm/lib/Support/YAMLTraits.cpp

Index: llvm/lib/Support/YAMLTraits.cpp
===
--- llvm/lib/Support/YAMLTraits.cpp
+++ llvm/lib/Support/YAMLTraits.cpp
@@ -48,6 +48,10 @@
   Ctxt = Context;
 }
 
+void IO::setAllowUnknownKeys(bool Allow) {
+  llvm_unreachable("Only supported for Input");
+}
+
 //===--===//
 //  Input
 //===--===//
@@ -197,8 +201,13 @@
 return;
   for (const auto  : MN->Mapping) {
 if (!is_contained(MN->ValidKeys, NN.first())) {
-  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
-  break;
+  auto ReportNode = NN.second.get();
+  auto ReportMessage = Twine("unknown key '") + NN.first() + "'";
+  if (!AllowUnknownKeys) {
+setError(ReportNode, ReportMessage);
+break;
+  } else
+reportWarning(ReportNode, ReportMessage);
 }
   }
 }
@@ -370,6 +379,15 @@
   EC = make_error_code(errc::invalid_argument);
 }
 
+void Input::reportWarning(HNode *hnode, const Twine ) {
+  assert(hnode && "HNode must not be NULL");
+  reportWarning(hnode->_node, message);
+}
+
+void Input::reportWarning(Node *node, const Twine ) {
+  Strm->printError(node, message, SourceMgr::DK_Warning);
+}
+
 std::unique_ptr Input::createHNodes(Node *N) {
   SmallString<128> StringStorage;
   if (ScalarNode *SN = dyn_cast(N)) {
@@ -428,6 +446,8 @@
   setError(CurrentNode, Message);
 }
 
+void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
+
 bool Input::canElideEmptySequence() {
   return false;
 }
Index: llvm/lib/Support/YAMLParser.cpp
===
--- llvm/lib/Support/YAMLParser.cpp
+++ llvm/lib/Support/YAMLParser.cpp
@@ -1775,12 +1775,9 @@
 
 bool Stream::failed() { return scanner->failed(); }
 
-void Stream::printError(Node *N, const Twine ) {
+void Stream::printError(Node *N, const Twine , SourceMgr::DiagKind Kind) {
   SMRange Range = N ? N->getSourceRange() : SMRange();
-  scanner->printError( Range.Start
- , SourceMgr::DK_Error
- , Msg
- , Range);
+  scanner->printError(Range.Start, Kind, Msg, Range);
 }
 
 document_iterator Stream::begin() {
Index: llvm/include/llvm/Support/YAMLTraits.h
===
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -789,6 +789,7 @@
   virtual NodeKind getNodeKind() = 0;
 
   virtual void setError(const Twine &) = 0;
+  virtual void setAllowUnknownKeys(bool Allow);
 
   template 
   void enumCase(T , const char* Str, const T ConstVal) {
@@ -1495,6 +1496,9 @@
   void setError(HNode *hnode, const Twine );
   void setError(Node *node, const Twine );
 
+  void reportWarning(HNode *hnode, const Twine );
+  void reportWarning(Node *hnode, const Twine );
+
 public:
   // These are only used by operator>>. They could be private
   // if those templated things could be made friends.
@@ -1504,6 +1508,8 @@
   /// Returns the current node that's being parsed by the YAML Parser.
   const Node *getCurrentNode() const;
 
+  void setAllowUnknownKeys(bool Allow) override;
+
 private:
   SourceMgr   SrcMgr; // must be before Strm
   std::unique_ptr Strm;
@@ -1514,6 +1520,7 @@
   std::vector   BitValuesUsed;
   HNode *CurrentNode = nullptr;
   boolScalarMatchFound = false;
+  bool AllowUnknownKeys = false;
 };
 
 ///
Index: llvm/include/llvm/Support/YAMLParser.h
===
--- llvm/include/llvm/Support/YAMLParser.h
+++ llvm/include/llvm/Support/YAMLParser.h
@@ -40,6 +40,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SourceMgr.h"
 #include 
 #include 
 #include 
@@ -51,7 +52,6 @@
 namespace llvm {
 
 class MemoryBufferRef;
-class SourceMgr;
 class raw_ostream;
 class Twine;
 
@@ -100,7 +100,8 @@
 return !failed();
   }
 
-  void printError(Node *N, const Twine );
+  void printError(Node *N, const Twine 

[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-07 Thread Jake Merdich via Phabricator via cfe-commits
JakeMerdichAMD added a comment.

I can see the use of this, but I am also wary that ignoring style options will 
lead to people producing different results on different versions of 
clang-format. This is both because having set-or-unset an option will naturally 
lead to different code and also that newer options are a de-facto check that 
clang-format is at least a certain version (we have minor differences between 
major versions as bugs are fixed). In any case, I see this being *very* easy to 
misuse and the documentation should have a warning reflecting that.

As far as docs go, the bulk are in clang/docs/ClangFormat.rst and require no 
additional 'publish' step but definitely should be updated. The command line 
options are implicitly generated for the cli tool's --help flag, but the docs 
for them are all in that rst file and manually maintained.




Comment at: clang/tools/clang-format/ClangFormat.cpp:108
+static cl::opt
+IgnoreUnkownOptions("ignore-unknown-options",
+cl::desc("If set, unknown format options are 
ignored."),

fodinabor wrote:
> MyDeveloperDay wrote:
> > feels like a mouthful is there nothing shorter we could use?  -Wignore (or 
> > something)
> hmm... `-Wunknown`
> but the `-W` does not really make it clear that the default "errors" should 
> now be treated as warnings instead. From compiler conventions, I'd expect the 
> `-W` to enable a warning ... 
> 
> and something like `-Wno-error=unknown` is not really shorter...
I personally like -Wno-error=unknown if the behavior is to emit warnings and 
-Wno-unknown if the behavior is to be silent, for consistency with clang/gcc.

I would also put a note in the description saying that ignoring options can 
lead to dramatically different output between versions that do and don't 
support a given option, so it should be used with care.



Comment at: llvm/lib/Support/YAMLTraits.cpp:199
+  if (IgnoreUnkown)
+return;
   for (const auto  : MN->Mapping) {

grimar wrote:
> fodinabor wrote:
> > MyDeveloperDay wrote:
> > > do we want to flat out ignore or just report but not fatally. (just a 
> > > thought) silent failures are hard to diagnose
> > true.. don't know what's the best option?
> > 
> > keep it as a printed out error and just don't return an error code on exit? 
> > This option would make it a clang-format only change, but feels really 
> > dirty.
> > 
> > Otherwise I'd have to dig my way through to 
> > `llvm::yaml::Stream::printError` (or maybe rather add a `printWarning`) to 
> > conditionally change the message type for the ignore case.
> Yes, I think we might want to introduce a method, like `Input::reportWarning`
> which will call ` Strm->printError(node, message);`, but will not set a `EC`.
> Also, it should print "warning: ..." instead of "error: ..." prefix somehow.
> 
Something like how clang/gcc only report unknown -Wno-foo options if there's 
another error is an idea, but clang-format almost never fails unless there's a 
bad config or input file so that's not too useful.

I'm fine with either warning or being silent. If the user has opted-into 
ignoring missing options, we can assume they're willing to accept the 
consequences of such.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-07 Thread George Rimar via Phabricator via cfe-commits
grimar added a comment.

I am not familar with `clang-format`, but have a few comments inlined about the 
rest.
I think the new `setIgnoreUnknown` YAMLlib API is probably OK generally.
I'd perhaps call it differently, e.g. `setAllowUnknownKeys` though.

Also, I think you need to add a unit testing for the new functionality.
It seems appropriate places are: `clang\unittests\Format\FormatTest.cpp` (to 
test clang-format)
and `llvm\unittests\ObjectYAML\YAMLTest.cpp` (to test new YAML 
`Input::setIgnoreUnknown` API)

I'll add people who might have something useful to say too.




Comment at: llvm/include/llvm/Support/YAMLTraits.h:1508
 
+  void setIgnoreUnknown(bool) override;
+

I'd add a parameter name here. Seems the style is mixed in this file,
but it is a public member, and having no names for arguments actually
reads bad I think. Not sure why it was done initially.

Probably the same applies for `setIgnoreUnknown` in the base class.



Comment at: llvm/lib/Support/YAMLTraits.cpp:199
+  if (IgnoreUnkown)
+return;
   for (const auto  : MN->Mapping) {

fodinabor wrote:
> MyDeveloperDay wrote:
> > do we want to flat out ignore or just report but not fatally. (just a 
> > thought) silent failures are hard to diagnose
> true.. don't know what's the best option?
> 
> keep it as a printed out error and just don't return an error code on exit? 
> This option would make it a clang-format only change, but feels really dirty.
> 
> Otherwise I'd have to dig my way through to `llvm::yaml::Stream::printError` 
> (or maybe rather add a `printWarning`) to conditionally change the message 
> type for the ignore case.
Yes, I think we might want to introduce a method, like `Input::reportWarning`
which will call ` Strm->printError(node, message);`, but will not set a `EC`.
Also, it should print "warning: ..." instead of "error: ..." prefix somehow.




Comment at: llvm/lib/Support/YAMLTraits.cpp:742
 
+void Output::setIgnoreUnknown(bool Value) {}
+

You don't actually need it for `Output`, right?
I think instead you can have a default implementation in the base class, which 
should call `llvm_unreachable`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-07 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor added a subscriber: grimar.
fodinabor added a comment.

Thank you so far for the feedback!
maybe you can give further guidance on the comments on the comments :)

As of the git history it seems that @grimar did some work on YAML error 
handling..




Comment at: clang/tools/clang-format/ClangFormat.cpp:108
+static cl::opt
+IgnoreUnkownOptions("ignore-unknown-options",
+cl::desc("If set, unknown format options are 
ignored."),

MyDeveloperDay wrote:
> feels like a mouthful is there nothing shorter we could use?  -Wignore (or 
> something)
hmm... `-Wunknown`
but the `-W` does not really make it clear that the default "errors" should now 
be treated as warnings instead. From compiler conventions, I'd expect the `-W` 
to enable a warning ... 

and something like `-Wno-error=unknown` is not really shorter...



Comment at: llvm/include/llvm/Support/YAMLTraits.h:1520
   boolScalarMatchFound = false;
+  bool IgnoreUnkown = false;
 };

MyDeveloperDay wrote:
> is this clang-formatted?
the patch is... the original alignment of the members is not. (also see the 
`CurrentNode`'s formatting).
not sure what to do in this case, as the whole file seems rather unformatted?



Comment at: llvm/lib/Support/YAMLTraits.cpp:199
+  if (IgnoreUnkown)
+return;
   for (const auto  : MN->Mapping) {

MyDeveloperDay wrote:
> do we want to flat out ignore or just report but not fatally. (just a 
> thought) silent failures are hard to diagnose
true.. don't know what's the best option?

keep it as a printed out error and just don't return an error code on exit? 
This option would make it a clang-format only change, but feels really dirty.

Otherwise I'd have to dig my way through to `llvm::yaml::Stream::printError` 
(or maybe rather add a `printWarning`) to conditionally change the message type 
for the ignore case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-07 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added subscribers: sammccall, JDevlieghere, aaron.ballman.
MyDeveloperDay added a comment.

> Regarding not touching the LLVM support library: I'd love to find a way, but 
> as clang-format uses the >> operator

We need to find some reviewers who look after a wider area of LLVM, if you want 
to make a change out there in LLVM/support, but it above my pay grade to 
approve ;-) maybe one of the more experienced devs could help identify the 
correct person @aaron.ballman @sammccall or alternatively take a look via git 
log as to who has been maintaining that file @JDevlieghere, they may have an 
opinion about how this should be done.




Comment at: clang/tools/clang-format/ClangFormat.cpp:108
+static cl::opt
+IgnoreUnkownOptions("ignore-unknown-options",
+cl::desc("If set, unknown format options are 
ignored."),

feels like a mouthful is there nothing shorter we could use?  -Wignore (or 
something)



Comment at: llvm/include/llvm/Support/YAMLTraits.h:792
   virtual void setError(const Twine &) = 0;
+  virtual void setIgnoreUnknown(bool) = 0;
 

I'm not a massive fan of functions with out parameter names, but I see your 
following the local style.



Comment at: llvm/include/llvm/Support/YAMLTraits.h:1520
   boolScalarMatchFound = false;
+  bool IgnoreUnkown = false;
 };

is this clang-formatted?



Comment at: llvm/lib/Support/YAMLTraits.cpp:199
+  if (IgnoreUnkown)
+return;
   for (const auto  : MN->Mapping) {

do we want to flat out ignore or just report but not fatally. (just a thought) 
silent failures are hard to diagnose


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-05 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor added a comment.

I see the possible issue with the possible version mismatches and that is why 
I'd make people opt-in for this option, to still being able to format their 
files (e.g. if using out-dated built-in versions like in Visual Studio - I know 
you can specify your own binary) but the real formatting can be done with a 
pre-commit script or similar, where the new options are actually supported.

Regarding not touching the LLVM support library: I'd love to find a way, but as 
clang-format uses the `>>` operator to read the YAML and this operator 
automatically emits the errors, I don't see any other obvious way.. (maybe 
there's a LLVM trick to suppress those errors that I haven't seen, yet :))


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-05 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added a comment.

This has caught me out from time to time, but the presence of such an option 
can lead to users mixing clang-format versions which could lead to 
flip/flopping of changes, so I'm not 100% sure it won't drive bad behaviour.

However breaking based on the option can be a pain if the code you are 
formatting isn't even using the new option

I wonder is it possible to do this without impacting the LLVM support libraries?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-09-05 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86137

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D86137: Add ignore-unknown-options flag to clang-format.

2020-08-18 Thread Joachim Meyer via Phabricator via cfe-commits
fodinabor created this revision.
fodinabor added reviewers: bkramer, djasper, klimek.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.
fodinabor requested review of this revision.

Currently newer clang-format options cannot be included in .clang-format files, 
if not all users can be forced to use an updated version.
This patch tries to solve this by adding an option to clang-format, enabling to 
ignore unknown (newer) options.

As this is my first LLVM patch, I'm expecting to get some things wrong and are 
happy to receive any feedback!
E.g.: I haven't found how to update the clang-format help page yet. Is it auto 
generated?
Also if you have any suggestions on whom to ask wrt review, please add them.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86137

Files:
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/tools/clang-format/ClangFormat.cpp
  llvm/include/llvm/Support/YAMLTraits.h
  llvm/lib/Support/YAMLTraits.cpp

Index: llvm/lib/Support/YAMLTraits.cpp
===
--- llvm/lib/Support/YAMLTraits.cpp
+++ llvm/lib/Support/YAMLTraits.cpp
@@ -195,6 +195,8 @@
   MapHNode *MN = dyn_cast_or_null(CurrentNode);
   if (!MN)
 return;
+  if (IgnoreUnkown)
+return;
   for (const auto  : MN->Mapping) {
 if (!is_contained(MN->ValidKeys, NN.first())) {
   setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
@@ -428,6 +430,8 @@
   setError(CurrentNode, Message);
 }
 
+void Input::setIgnoreUnknown(bool Value) { IgnoreUnkown = Value; }
+
 bool Input::canElideEmptySequence() {
   return false;
 }
@@ -735,6 +739,8 @@
 void Output::setError(const Twine ) {
 }
 
+void Output::setIgnoreUnknown(bool Value) {}
+
 bool Output::canElideEmptySequence() {
   // Normally, with an optional key/value where the value is an empty sequence,
   // the whole key/value can be not written.  But, that produces wrong yaml
Index: llvm/include/llvm/Support/YAMLTraits.h
===
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -789,6 +789,7 @@
   virtual NodeKind getNodeKind() = 0;
 
   virtual void setError(const Twine &) = 0;
+  virtual void setIgnoreUnknown(bool) = 0;
 
   template 
   void enumCase(T , const char* Str, const T ConstVal) {
@@ -1504,6 +1505,8 @@
   /// Returns the current node that's being parsed by the YAML Parser.
   const Node *getCurrentNode() const;
 
+  void setIgnoreUnknown(bool) override;
+
 private:
   SourceMgr   SrcMgr; // must be before Strm
   std::unique_ptr Strm;
@@ -1514,6 +1517,7 @@
   std::vector   BitValuesUsed;
   HNode *CurrentNode = nullptr;
   boolScalarMatchFound = false;
+  bool IgnoreUnkown = false;
 };
 
 ///
@@ -1561,6 +1565,7 @@
   void scalarTag(std::string &) override;
   NodeKind getNodeKind() override;
   void setError(const Twine ) override;
+  void setIgnoreUnknown(bool) override;
   bool canElideEmptySequence() override;
 
   // These are only used by operator<<. They could be private
Index: clang/tools/clang-format/ClangFormat.cpp
===
--- clang/tools/clang-format/ClangFormat.cpp
+++ clang/tools/clang-format/ClangFormat.cpp
@@ -104,6 +104,11 @@
  "SortIncludes style flag"),
 cl::cat(ClangFormatCategory));
 
+static cl::opt
+IgnoreUnkownOptions("ignore-unknown-options",
+cl::desc("If set, unknown format options are ignored."),
+cl::init(false), cl::cat(ClangFormatCategory));
+
 static cl::opt
 Verbose("verbose", cl::desc("If set, shows the list of processed files"),
 cl::cat(ClangFormatCategory));
@@ -378,7 +383,8 @@
   }
 
   llvm::Expected FormatStyle =
-  getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer());
+  getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer(),
+   nullptr, IgnoreUnkownOptions.getValue());
   if (!FormatStyle) {
 llvm::errs() << llvm::toString(FormatStyle.takeError()) << "\n";
 return true;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -1288,7 +1288,8 @@
   return true;
 }
 
-std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
+std::error_code parseConfiguration(StringRef Text, FormatStyle *Style,
+   bool IgnoreUnknownOptions) {
   assert(Style);
   FormatStyle::LanguageKind Language = Style->Language;
   assert(Language != FormatStyle::LK_None);
@@ -1302,6 +1303,7 @@
   // Mapping also uses the context to get the language to find the correct
   // base style.
   Input.setContext(Style);
+  Input.setIgnoreUnknown(IgnoreUnknownOptions);