summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBen Hamilton <benhamilton@google.com>2018-02-08 16:07:25 +0000
committerBen Hamilton <benhamilton@google.com>2018-02-08 16:07:25 +0000
commit09051f2925ae059ac724ebd2b6de01aa239f26c6 (patch)
tree759b2d94c9b9274cd0515411387f973c1081bad0 /clang
parent976f317f0c89cab5d5e849b66993472486869ffd (diff)
downloadbcm5719-llvm-09051f2925ae059ac724ebd2b6de01aa239f26c6.tar.gz
bcm5719-llvm-09051f2925ae059ac724ebd2b6de01aa239f26c6.zip
[clang-format] Do not break Objective-C string literals inside array literals
Summary: Concatenating Objective-C string literals inside an array literal raises the warning -Wobjc-string-concatenation (which is enabled by default). clang-format currently splits and concatenates string literals like the following: NSArray *myArray = @[ @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ]; into: NSArray *myArray = @[ @"aaaaaaaaaaaaaaaaaaaaaaaaaaaa" @"aaaaaaaaa" ]; which raises the warning. This is https://bugs.llvm.org/show_bug.cgi?id=36153 . The options I can think of to fix this are: 1) Have clang-format disable Wobjc-string-concatenation by emitting pragmas around the formatted code 2) Have clang-format wrap the string literals in a macro (which disables the warning) 3) Disable string splitting for Objective-C string literals inside array literals I think 1) has no precedent, and I couldn't find a good identity() macro for 2). So, this diff implements 3). Test Plan: make -j12 FormatTests && ./tools/clang/unittests/Format/FormatTests Reviewers: jolesiak, stephanemoore, djasper Reviewed By: jolesiak Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D42704 llvm-svn: 324618
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp8
-rw-r--r--clang/lib/Format/ContinuationIndenter.h7
-rw-r--r--clang/unittests/Format/FormatTestObjC.cpp6
3 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 6ee299566e4..14f8f05645d 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -1285,6 +1285,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
+ State.Stack.back().IsInsideObjCArrayLiteral =
+ Current.is(TT_ArrayInitializerLSquare) && Current.Previous &&
+ Current.Previous->is(tok::at);
}
void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
@@ -1578,6 +1581,11 @@ std::unique_ptr<BreakableToken> ContinuationIndenter::createBreakableToken(
// likely want to terminate the string before any line breaking is done.
if (Current.IsUnterminatedLiteral)
return nullptr;
+ // Don't break string literals inside Objective-C array literals (doing so
+ // raises the warning -Wobjc-string-concatenation).
+ if (State.Stack.back().IsInsideObjCArrayLiteral) {
+ return nullptr;
+ }
StringRef Text = Current.TokenText;
StringRef Prefix;
diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h
index bb2b7320fd4..64b3a3eba9f 100644
--- a/clang/lib/Format/ContinuationIndenter.h
+++ b/clang/lib/Format/ContinuationIndenter.h
@@ -208,7 +208,8 @@ struct ParenState {
NoLineBreakInOperand(false), LastOperatorWrapped(true),
ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
AlignColons(true), ObjCSelectorNameFound(false),
- HasMultipleNestedBlocks(false), NestedBlockInlined(false) {}
+ HasMultipleNestedBlocks(false), NestedBlockInlined(false),
+ IsInsideObjCArrayLiteral(false) {}
/// \brief The position to which a specific parenthesis level needs to be
/// indented.
@@ -318,6 +319,10 @@ struct ParenState {
/// "function" in JavaScript) is not wrapped to a new line.
bool NestedBlockInlined : 1;
+ /// \brief \c true if the current \c ParenState represents an Objective-C
+ /// array literal.
+ bool IsInsideObjCArrayLiteral : 1;
+
bool operator<(const ParenState &Other) const {
if (Indent != Other.Indent)
return Indent < Other.Indent;
diff --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp
index d270aabea5b..df2e067a302 100644
--- a/clang/unittests/Format/FormatTestObjC.cpp
+++ b/clang/unittests/Format/FormatTestObjC.cpp
@@ -975,6 +975,12 @@ TEST_F(FormatTestObjC, ObjCArrayLiterals) {
verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
" NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
"]];");
+ Style.ColumnLimit = 20;
+ // We can't break string literals inside NSArray literals
+ // (that raises -Wobjc-string-concatenation).
+ verifyFormat("NSArray *foo = @[\n"
+ " @\"aaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
+ "];\n");
}
} // end namespace
} // end namespace format
OpenPOWER on IntegriCloud