From a5342db6fcc6ee3fae084f584ecb019726de9cca Mon Sep 17 00:00:00 2001
From: Manuel Klimek <klimek@google.com>
Date: Sun, 6 Jan 2013 20:07:31 +0000
Subject: [PATCH] Fixes handling of unbalances braces.

If we find an unexpected closing brace, we must not stop parsing, as
we'd otherwise not layout anything beyond that point.

If we find a structural error on the highest level we'll not re-indent
anyway, but we'll still want to format within unwrapped lines.

Needed to introduce a differentiation between an expected and unexpected
closing brace.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171666 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Format/UnwrappedLineParser.cpp | 17 ++++++++++++-----
 lib/Format/UnwrappedLineParser.h   |  2 +-
 unittests/Format/FormatTest.cpp    |  8 ++++++--
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 72b47503ee8..00710827c2a 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -84,13 +84,13 @@ bool UnwrappedLineParser::parse() {
 }
 
 bool UnwrappedLineParser::parseFile() {
-  bool Error = parseLevel();
+  bool Error = parseLevel(/*HasOpeningBrace=*/false);
   // Make sure to format the remaining tokens.
   addUnwrappedLine();
   return Error;
 }
 
-bool UnwrappedLineParser::parseLevel() {
+bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
   bool Error = false;
   do {
     switch (FormatTok.Tok.getKind()) {
@@ -103,8 +103,15 @@ bool UnwrappedLineParser::parseLevel() {
       addUnwrappedLine();
       break;
     case tok::r_brace:
-      // Stray '}' is an error.
-      return true;
+      if (HasOpeningBrace) {
+        return false;
+      } else {
+        // Stray '}' is an error.
+        Error = true;
+        nextToken();
+        addUnwrappedLine();
+      }
+      break;
     default:
       parseStatement();
       break;
@@ -120,7 +127,7 @@ bool UnwrappedLineParser::parseBlock(unsigned AddLevels) {
   addUnwrappedLine();
 
   Line.Level += AddLevels;
-  parseLevel();
+  parseLevel(/*HasOpeningBrace=*/true);
   Line.Level -= AddLevels;
 
   // FIXME: Add error handling.
diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h
index 287143dae29..2308c92fa1f 100644
--- a/lib/Format/UnwrappedLineParser.h
+++ b/lib/Format/UnwrappedLineParser.h
@@ -106,7 +106,7 @@ public:
 
 private:
   bool parseFile();
-  bool parseLevel();
+  bool parseLevel(bool HasOpeningBrace);
   bool parseBlock(unsigned AddLevels = 1);
   void parsePPDirective();
   void parsePPDefine();
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 8d95538b16b..28f63aa0551 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -474,8 +474,12 @@ TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) {
   verifyFormat("{\n  {\n    a #c;\n  }\n}");
 }
 
-// FIXME: write test for unbalanced braces in macros...
-// FIXME: test # inside a normal statement (like {#define A b})
+TEST_F(FormatTest, FormatUnbalancedStructuralElements) {
+  EXPECT_EQ("#define A \\\n  {       \\\n    {\nint i;",
+            format("#define A { {\nint i;", getLLVMStyleWithColumns(11)));
+  EXPECT_EQ("#define A \\\n  }       \\\n  }\nint i;",
+            format("#define A } }\nint i;", getLLVMStyleWithColumns(11)));
+}
 
 TEST_F(FormatTest, MixingPreprocessorDirectivesAndNormalCode) {
   EXPECT_EQ(
-- 
GitLab