[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-27 Thread Ben Hamilton via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC328628: [clang-format] Refine ObjC guesser to handle child 
lines of child lines (authored by benhamilton, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D44831?vs=139929&id=139932#toc

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
@@ -12159,6 +12159,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 ({ 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
@@ -1514,8 +1514,8 @@
 "UIView",
 };
 
-auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-  for (const FormatToken *FormatTok = Line.First; FormatTok;
+for (auto Line : AnnotatedLines) {
+  for (const FormatToken *FormatTok = Line->First; FormatTok;
FormatTok = FormatTok->Next) {
 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
  (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
@@ -1535,14 +1535,7 @@
TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
   return true;
 }
-  }
-  return false;
-};
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
-return true;
-  for (auto ChildLine : Line->Children) {
-if (LineContainsObjCCode(*ChildLine))
+if (guessIsObjC(Line->Children, Keywords))
   return true;
   }
 }


Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12159,6 +12159,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 ({ 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
@@ -1514,8 +1514,8 @@
 "UIView",
 };
 
-auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-  for (const FormatToken *FormatTok = Line.First; FormatTok;
+for (auto Line : AnnotatedLines) {
+  for (const FormatToken *FormatTok = Line->First; FormatTok;
FormatTok = FormatTok->Next) {
 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
  (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
@@ -1535,14 +1535,7 @@
TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
   return true;
 }
-  }
-  return false;
-};
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
-return true;
-  for (auto ChildLine : Line->Children) {
-if (LineContainsObjCCode(*ChildLine))
+if (guessIsObjC(Line->Children, Keywords))
   return true;
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-27 Thread Daniel Jasper via Phabricator via cfe-commits
djasper accepted this revision.
djasper added a comment.
This revision is now accepted and ready to land.

Looks good.


Repository:
  rC Clang

https://reviews.llvm.org/D44831



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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-27 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton added inline comments.



Comment at: lib/Format/Format.cpp:1449
   const AdditionalKeywords &Keywords) {
+for (auto Line : AnnotatedLines)
+  if (LineContainsObjCCode(*Line, Keywords))

djasper wrote:
> I would not create a second function here. Just iterate over the tokens here 
> and call guessIsObjC recursively with Line->Children. That means we need one 
> less for loop overall, I think (I might be missing something).
Good call, done.

I don't know why I didn't do that first! For some reason, my brain thought 
`Line.Children` was an incompatible type..



Comment at: lib/Format/Format.cpp:1455
+
+  static bool LineContainsObjCCode(const AnnotatedLine &Line,
+   const AdditionalKeywords &Keywords) {

djasper wrote:
> Convention would be lineContainsObjCCode.
Removed.


Repository:
  rC Clang

https://reviews.llvm.org/D44831



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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-27 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton updated this revision to Diff 139929.
benhamilton marked 2 inline comments as done.
benhamilton added a comment.

- Simplify recursion. Remove static method LineContainsObjCCode().


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,6 +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 ({ 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
@@ -1514,8 +1514,8 @@
 "UIView",
 };
 
-auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-  for (const FormatToken *FormatTok = Line.First; FormatTok;
+for (auto Line : AnnotatedLines) {
+  for (const FormatToken *FormatTok = Line->First; FormatTok;
FormatTok = FormatTok->Next) {
 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
  (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
@@ -1535,14 +1535,7 @@
TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
   return true;
 }
-  }
-  return false;
-};
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
-return true;
-  for (auto ChildLine : Line->Children) {
-if (LineContainsObjCCode(*ChildLine))
+if (guessIsObjC(Line->Children, Keywords))
   return true;
   }
 }


Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12171,6 +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 ({ 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
@@ -1514,8 +1514,8 @@
 "UIView",
 };
 
-auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-  for (const FormatToken *FormatTok = Line.First; FormatTok;
+for (auto Line : AnnotatedLines) {
+  for (const FormatToken *FormatTok = Line->First; FormatTok;
FormatTok = FormatTok->Next) {
 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
  (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
@@ -1535,14 +1535,7 @@
TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
   return true;
 }
-  }
-  return false;
-};
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
-return true;
-  for (auto ChildLine : Line->Children) {
-if (LineContainsObjCCode(*ChildLine))
+if (guessIsObjC(Line->Children, Keywords))
   return true;
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-27 Thread Daniel Jasper via Phabricator via cfe-commits
djasper added inline comments.



Comment at: lib/Format/Format.cpp:1449
   const AdditionalKeywords &Keywords) {
+for (auto Line : AnnotatedLines)
+  if (LineContainsObjCCode(*Line, Keywords))

I would not create a second function here. Just iterate over the tokens here 
and call guessIsObjC recursively with Line->Children. That means we need one 
less for loop overall, I think (I might be missing something).



Comment at: lib/Format/Format.cpp:1455
+
+  static bool LineContainsObjCCode(const AnnotatedLine &Line,
+   const AdditionalKeywords &Keywords) {

Convention would be lineContainsObjCCode.


Repository:
  rC Clang

https://reviews.llvm.org/D44831



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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-26 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton updated this revision to Diff 139804.
benhamilton added a comment.

- Remove stray semicolon.


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,6 +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 ({ 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
@@ -1446,6 +1446,14 @@
 private:
   static bool guessIsObjC(const SmallVectorImpl 
&AnnotatedLines,
   const AdditionalKeywords &Keywords) {
+for (auto Line : AnnotatedLines)
+  if (LineContainsObjCCode(*Line, Keywords))
+return true;
+return false;
+  }
+
+  static bool LineContainsObjCCode(const AnnotatedLine &Line,
+   const AdditionalKeywords &Keywords) {
 // Keep this array sorted, since we are binary searching over it.
 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
 "CGFloat",
@@ -1514,37 +1522,29 @@
 "UIView",
 };
 
-auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-  for (const FormatToken *FormatTok = Line.First; FormatTok;
-   FormatTok = FormatTok->Next) {
-if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
- (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
-  FormatTok->isObjCAtKeyword(tok::objc_implementation) ||
-  FormatTok->isObjCAtKeyword(tok::objc_protocol) ||
-  FormatTok->isObjCAtKeyword(tok::objc_end) ||
-  FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
- tok::l_brace))) ||
-(FormatTok->Tok.isAnyIdentifier() &&
- std::binary_search(std::begin(FoundationIdentifiers),
-std::end(FoundationIdentifiers),
-FormatTok->TokenText)) ||
-FormatTok->is(TT_ObjCStringLiteral) ||
-FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
-   TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
-   TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
-   TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
-  return true;
-}
-  }
-  return false;
-};
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
+for (const FormatToken *FormatTok = Line.First; FormatTok;
+ FormatTok = FormatTok->Next) {
+  if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
+   (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
+FormatTok->isObjCAtKeyword(tok::objc_implementation) ||
+FormatTok->isObjCAtKeyword(tok::objc_protocol) ||
+FormatTok->isObjCAtKeyword(tok::objc_end) ||
+FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
+   tok::l_brace))) ||
+  (FormatTok->Tok.isAnyIdentifier() &&
+   std::binary_search(std::begin(FoundationIdentifiers),
+  std::end(FoundationIdentifiers),
+  FormatTok->TokenText)) ||
+  FormatTok->is(TT_ObjCStringLiteral) ||
+  FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
+ TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
+ TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
+ TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
 return true;
-  for (auto ChildLine : Line->Children) {
-if (LineContainsObjCCode(*ChildLine))
-  return true;
   }
+  for (auto ChildLine : Line.Children)
+if (LineContainsObjCCode(*ChildLine, Keywords))
+  return true;
 }
 return false;
   }


Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12171,6 +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 ({ foo();

[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-26 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton updated this revision to Diff 139802.
benhamilton added a comment.

- Use recursion. Split lambda out into its own static method since recursion on 
lambdas is quite ugly until C++14


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,6 +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 ({ 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
@@ -1446,6 +1446,14 @@
 private:
   static bool guessIsObjC(const SmallVectorImpl 
&AnnotatedLines,
   const AdditionalKeywords &Keywords) {
+for (auto Line : AnnotatedLines)
+  if (LineContainsObjCCode(*Line, Keywords))
+return true;
+return false;
+  }
+
+  static bool LineContainsObjCCode(const AnnotatedLine &Line,
+   const AdditionalKeywords &Keywords) {
 // Keep this array sorted, since we are binary searching over it.
 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
 "CGFloat",
@@ -1514,40 +1522,32 @@
 "UIView",
 };
 
-auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-  for (const FormatToken *FormatTok = Line.First; FormatTok;
-   FormatTok = FormatTok->Next) {
-if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
- (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
-  FormatTok->isObjCAtKeyword(tok::objc_implementation) ||
-  FormatTok->isObjCAtKeyword(tok::objc_protocol) ||
-  FormatTok->isObjCAtKeyword(tok::objc_end) ||
-  FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
- tok::l_brace))) ||
-(FormatTok->Tok.isAnyIdentifier() &&
- std::binary_search(std::begin(FoundationIdentifiers),
-std::end(FoundationIdentifiers),
-FormatTok->TokenText)) ||
-FormatTok->is(TT_ObjCStringLiteral) ||
-FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
-   TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
-   TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
-   TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
-  return true;
-}
-  }
-  return false;
-};
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
+for (const FormatToken *FormatTok = Line.First; FormatTok;
+ FormatTok = FormatTok->Next) {
+  if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
+   (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
+FormatTok->isObjCAtKeyword(tok::objc_implementation) ||
+FormatTok->isObjCAtKeyword(tok::objc_protocol) ||
+FormatTok->isObjCAtKeyword(tok::objc_end) ||
+FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
+   tok::l_brace))) ||
+  (FormatTok->Tok.isAnyIdentifier() &&
+   std::binary_search(std::begin(FoundationIdentifiers),
+  std::end(FoundationIdentifiers),
+  FormatTok->TokenText)) ||
+  FormatTok->is(TT_ObjCStringLiteral) ||
+  FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
+ TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
+ TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
+ TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
 return true;
-  for (auto ChildLine : Line->Children) {
-if (LineContainsObjCCode(*ChildLine))
-  return true;
   }
+  for (auto ChildLine : Line.Children)
+if (LineContainsObjCCode(*ChildLine, Keywords))
+  return true;
 }
 return false;
-  }
+  };
 
   bool IsObjC;
 };


Index: unittests/Format/FormatTest.cpp
===
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12171,6 +12171,12 @@
 guessLanguage("foo.h", "#define FOO ({ std::string s; })"));
   EXPECT_EQ(FormatStyle::LK_ObjC,
 guessLanguage("foo.h", "#define FOO 

[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-26 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton added inline comments.



Comment at: lib/Format/Format.cpp:1542
 };
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
+llvm::DenseSet LinesToCheckSet;
+LinesToCheckSet.reserve(AnnotatedLines.size());

benhamilton wrote:
> djasper wrote:
> > Wouldn't it be much easier to call this function recursively for Children 
> > instead of using the lambda as well as this additional set? Lines and their 
> > children should form a tree, I think, so you should never see the same line 
> > again during recursion.
> I'm less worried about cycles and more worried about a maliciously deeply 
> nested set of children blowing out the stack and causing a crash.
> 
> It seemed safer to use the heap here to avoid that scenario (I don't know of 
> any other way to avoid it, since we don't know the stack size and we don't 
> control it.)
djasper@ informed me that `clang-format` is already full of places which rely 
on the stack for recursion on user input, so that window has already been 
broken. :)

I'll happily go ahead and change this.


Repository:
  rC Clang

https://reviews.llvm.org/D44831



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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-26 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton added inline comments.



Comment at: lib/Format/Format.cpp:1542
 };
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
+llvm::DenseSet LinesToCheckSet;
+LinesToCheckSet.reserve(AnnotatedLines.size());

djasper wrote:
> Wouldn't it be much easier to call this function recursively for Children 
> instead of using the lambda as well as this additional set? Lines and their 
> children should form a tree, I think, so you should never see the same line 
> again during recursion.
I'm less worried about cycles and more worried about a maliciously deeply 
nested set of children blowing out the stack and causing a crash.

It seemed safer to use the heap here to avoid that scenario (I don't know of 
any other way to avoid it, since we don't know the stack size and we don't 
control it.)


Repository:
  rC Clang

https://reviews.llvm.org/D44831



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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-26 Thread Daniel Jasper via Phabricator via cfe-commits
djasper added inline comments.



Comment at: lib/Format/Format.cpp:1542
 };
-for (auto Line : AnnotatedLines) {
-  if (LineContainsObjCCode(*Line))
+llvm::DenseSet LinesToCheckSet;
+LinesToCheckSet.reserve(AnnotatedLines.size());

Wouldn't it be much easier to call this function recursively for Children 
instead of using the lambda as well as this additional set? Lines and their 
children should form a tree, I think, so you should never see the same line 
again during recursion.


Repository:
  rC Clang

https://reviews.llvm.org/D44831



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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-23 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton updated this revision to Diff 139601.
benhamilton added a comment.

Update from correct base revision


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,6 +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 ({ 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 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,6 +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 ({ 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 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


[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

2018-03-23 Thread Ben Hamilton via Phabricator via cfe-commits
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 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 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());