summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp102
-rw-r--r--clang/lib/Format/UnwrappedLineParser.h2
-rw-r--r--clang/unittests/Format/FormatTestObjC.cpp10
3 files changed, 68 insertions, 46 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 3fac75dc6fe..e41af026dfc 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -943,49 +943,6 @@ void UnwrappedLineParser::parseStructuralElement() {
return;
}
switch (FormatTok->Tok.getKind()) {
- case tok::at:
- nextToken();
- if (FormatTok->Tok.is(tok::l_brace)) {
- nextToken();
- parseBracedList();
- break;
- }
- switch (FormatTok->Tok.getObjCKeywordID()) {
- case tok::objc_public:
- case tok::objc_protected:
- case tok::objc_package:
- case tok::objc_private:
- return parseAccessSpecifier();
- case tok::objc_interface:
- case tok::objc_implementation:
- return parseObjCInterfaceOrImplementation();
- case tok::objc_protocol:
- return parseObjCProtocol();
- case tok::objc_end:
- return; // Handled by the caller.
- case tok::objc_optional:
- case tok::objc_required:
- nextToken();
- addUnwrappedLine();
- return;
- case tok::objc_autoreleasepool:
- nextToken();
- if (FormatTok->Tok.is(tok::l_brace)) {
- if (Style.BraceWrapping.AfterObjCDeclaration)
- addUnwrappedLine();
- parseBlock(/*MustBeDeclaration=*/false);
- }
- addUnwrappedLine();
- return;
- case tok::objc_try:
- // This branch isn't strictly necessary (the kw_try case below would
- // do this too after the tok::at is parsed above). But be explicit.
- parseTryCatch();
- return;
- default:
- break;
- }
- break;
case tok::kw_asm:
nextToken();
if (FormatTok->is(tok::l_brace)) {
@@ -1132,6 +1089,44 @@ void UnwrappedLineParser::parseStructuralElement() {
if (FormatTok->Tok.is(tok::l_brace)) {
nextToken();
parseBracedList();
+ break;
+ }
+ switch (FormatTok->Tok.getObjCKeywordID()) {
+ case tok::objc_public:
+ case tok::objc_protected:
+ case tok::objc_package:
+ case tok::objc_private:
+ return parseAccessSpecifier();
+ case tok::objc_interface:
+ case tok::objc_implementation:
+ return parseObjCInterfaceOrImplementation();
+ case tok::objc_protocol:
+ if (parseObjCProtocol())
+ return;
+ break;
+ case tok::objc_end:
+ return; // Handled by the caller.
+ case tok::objc_optional:
+ case tok::objc_required:
+ nextToken();
+ addUnwrappedLine();
+ return;
+ case tok::objc_autoreleasepool:
+ nextToken();
+ if (FormatTok->Tok.is(tok::l_brace)) {
+ if (Style.BraceWrapping.AfterObjCDeclaration)
+ addUnwrappedLine();
+ parseBlock(/*MustBeDeclaration=*/false);
+ }
+ addUnwrappedLine();
+ return;
+ case tok::objc_try:
+ // This branch isn't strictly necessary (the kw_try case below would
+ // do this too after the tok::at is parsed above). But be explicit.
+ parseTryCatch();
+ return;
+ default:
+ break;
}
break;
case tok::kw_enum:
@@ -2128,6 +2123,8 @@ void UnwrappedLineParser::parseObjCUntilAtEnd() {
}
void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
+ assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_interface ||
+ FormatTok->Tok.getObjCKeywordID() == tok::objc_implementation);
nextToken();
nextToken(); // interface name
@@ -2155,8 +2152,21 @@ void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
parseObjCUntilAtEnd();
}
-void UnwrappedLineParser::parseObjCProtocol() {
+// Returns true for the declaration/definition form of @protocol,
+// false for the expression form.
+bool UnwrappedLineParser::parseObjCProtocol() {
+ assert(FormatTok->Tok.getObjCKeywordID() == tok::objc_protocol);
nextToken();
+
+ if (FormatTok->is(tok::l_paren))
+ // The expression form of @protocol, e.g. "Protocol* p = @protocol(foo);".
+ return false;
+
+ // The definition/declaration form,
+ // @protocol Foo
+ // - (int)someMethod;
+ // @end
+
nextToken(); // protocol name
if (FormatTok->Tok.is(tok::less))
@@ -2165,11 +2175,13 @@ void UnwrappedLineParser::parseObjCProtocol() {
// Check for protocol declaration.
if (FormatTok->Tok.is(tok::semi)) {
nextToken();
- return addUnwrappedLine();
+ addUnwrappedLine();
+ return true;
}
addUnwrappedLine();
parseObjCUntilAtEnd();
+ return true;
}
void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index 1d8ccabbd0f..62238aba879 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -119,7 +119,7 @@ private:
void parseObjCProtocolList();
void parseObjCUntilAtEnd();
void parseObjCInterfaceOrImplementation();
- void parseObjCProtocol();
+ bool parseObjCProtocol();
void parseJavaScriptEs6ImportExport();
bool tryToParseLambda();
bool tryToParseLambdaIntroducer();
diff --git a/clang/unittests/Format/FormatTestObjC.cpp b/clang/unittests/Format/FormatTestObjC.cpp
index 6cb5729e252..879932db0db 100644
--- a/clang/unittests/Format/FormatTestObjC.cpp
+++ b/clang/unittests/Format/FormatTestObjC.cpp
@@ -215,6 +215,12 @@ TEST_F(FormatTestObjC, FormatObjCInterface) {
"@end");
verifyFormat("@interface Foo : Bar\n"
+ "@property(assign, readwrite) NSInteger bar;\n"
+ "+ (id)init;\n"
+ "@end");
+
+ verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @interface Foo : Bar\n"
+ "@property(assign, readwrite) NSInteger bar;\n"
"+ (id)init;\n"
"@end");
@@ -394,6 +400,10 @@ TEST_F(FormatTestObjC, FormatObjCProtocol) {
"@protocol Bar\n"
"@end");
+ verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @protocol Foo\n"
+ "@property(assign, readwrite) NSInteger bar;\n"
+ "@end");
+
verifyFormat("@protocol myProtocol\n"
"- (void)mandatoryWithInt:(int)i;\n"
"@optional\n"
OpenPOWER on IntegriCloud