benhamilton created this revision.
benhamilton added a reviewer: djasper.
Herald added subscribers: cfe-commits, klimek.

This fixes an issue brought up by djasper@ in his review of 
https://reviews.llvm.org/D44790. We
handled top-level child lines, but if those child lines themselves
had child lines, we didn't handle them.

Rather than use recursion (which could blow out the stack), I use a
DenseSet to hold the set of lines we haven't yet checked (since order
doesn't matter), and update the set to add the children of each
line as we check it.

Test Plan: New tests added. Confirmed tests failed before fix

  and passed after fix.


Repository:
  rC Clang

https://reviews.llvm.org/D44831

Files:
  lib/Format/Format.cpp
  unittests/Format/FormatTest.cpp


Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12171,10 +12171,12 @@
             guessLanguage("foo.h", "#define FOO ({ std::string s; })"));
   EXPECT_EQ(FormatStyle::LK_ObjC,
             guessLanguage("foo.h", "#define FOO ({ NSString *s; })"));
-  EXPECT_EQ(FormatStyle::LK_Cpp,
-            guessLanguage("foo.h", "#define FOO ({ ({ std::string s; }) })"));
-  EXPECT_EQ(FormatStyle::LK_ObjC,
-            guessLanguage("foo.h", "#define FOO ({ ({ NSString *s; }) })"));
+  EXPECT_EQ(
+      FormatStyle::LK_Cpp,
+      guessLanguage("foo.h", "#define FOO ({ foo(); ({ std::string s; }) })"));
+  EXPECT_EQ(
+      FormatStyle::LK_ObjC,
+      guessLanguage("foo.h", "#define FOO ({ foo(); ({ NSString *s; }) })"));
 }
 
 } // end namespace
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -31,6 +31,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/VirtualFileSystem.h"
 #include "clang/Lex/Lexer.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
@@ -1538,13 +1539,18 @@
       }
       return false;
     };
-    for (auto Line : AnnotatedLines) {
-      if (LineContainsObjCCode(*Line))
+    llvm::DenseSet<AnnotatedLine *> LinesToCheckSet;
+    LinesToCheckSet.reserve(AnnotatedLines.size());
+    LinesToCheckSet.insert(AnnotatedLines.begin(), AnnotatedLines.end());
+    while (!LinesToCheckSet.empty()) {
+      const auto NextLineIter = LinesToCheckSet.begin();
+      const auto NextLine = *NextLineIter;
+      if (LineContainsObjCCode(*NextLine))
         return true;
-      for (auto ChildLine : Line->Children) {
-        if (LineContainsObjCCode(*ChildLine))
-          return true;
-      }
+      LinesToCheckSet.erase(NextLineIter);
+      LinesToCheckSet.reserve(NextLine->Children.size());
+      LinesToCheckSet.insert(NextLine->Children.begin(),
+                             NextLine->Children.end());
     }
     return false;
   }


Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12171,10 +12171,12 @@
             guessLanguage("foo.h", "#define FOO ({ std::string s; })"));
   EXPECT_EQ(FormatStyle::LK_ObjC,
             guessLanguage("foo.h", "#define FOO ({ NSString *s; })"));
-  EXPECT_EQ(FormatStyle::LK_Cpp,
-            guessLanguage("foo.h", "#define FOO ({ ({ std::string s; }) })"));
-  EXPECT_EQ(FormatStyle::LK_ObjC,
-            guessLanguage("foo.h", "#define FOO ({ ({ NSString *s; }) })"));
+  EXPECT_EQ(
+      FormatStyle::LK_Cpp,
+      guessLanguage("foo.h", "#define FOO ({ foo(); ({ std::string s; }) })"));
+  EXPECT_EQ(
+      FormatStyle::LK_ObjC,
+      guessLanguage("foo.h", "#define FOO ({ foo(); ({ NSString *s; }) })"));
 }
 
 } // end namespace
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -31,6 +31,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/VirtualFileSystem.h"
 #include "clang/Lex/Lexer.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
@@ -1538,13 +1539,18 @@
       }
       return false;
     };
-    for (auto Line : AnnotatedLines) {
-      if (LineContainsObjCCode(*Line))
+    llvm::DenseSet<AnnotatedLine *> LinesToCheckSet;
+    LinesToCheckSet.reserve(AnnotatedLines.size());
+    LinesToCheckSet.insert(AnnotatedLines.begin(), AnnotatedLines.end());
+    while (!LinesToCheckSet.empty()) {
+      const auto NextLineIter = LinesToCheckSet.begin();
+      const auto NextLine = *NextLineIter;
+      if (LineContainsObjCCode(*NextLine))
         return true;
-      for (auto ChildLine : Line->Children) {
-        if (LineContainsObjCCode(*ChildLine))
-          return true;
-      }
+      LinesToCheckSet.erase(NextLineIter);
+      LinesToCheckSet.reserve(NextLine->Children.size());
+      LinesToCheckSet.insert(NextLine->Children.begin(),
+                             NextLine->Children.end());
     }
     return false;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to