diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-10 18:10:56 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-10 18:10:56 +0000 |
commit | 2eb362b50f34296c39d5ec3e5e1bd6a2c9a5877e (patch) | |
tree | f4f0e21876c7c2c414ed874cd5b7b15f6c91a9fb | |
parent | 1093f4928a4263d08b44d96e468a42515d8a28f3 (diff) |
objective-C++: delayed parsing of member function with
function-try-block occuring in objc's implementation
block. wip.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161675 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 19 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 3 | ||||
-rw-r--r-- | test/SemaObjCXX/delay-parsing-func-tryblock.mm | 47 |
3 files changed, 64 insertions, 5 deletions
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 70254b6db6..9b7e85f211 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1927,11 +1927,19 @@ void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) { LexedMethod* LM = new LexedMethod(this, MDecl); CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM); CachedTokens &Toks = LM->Toks; - // Begin by storing the '{' token. + // Begin by storing the '{' or 'try' token. Toks.push_back(Tok); + if (Tok.is(tok::kw_try)) { + ConsumeToken(); + Toks.push_back(Tok); // also store '{' + } ConsumeBrace(); // Consume everything up to (and including) the matching right brace. ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); + while (Tok.is(tok::kw_catch)) { + ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); + ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); + } } /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' @@ -2863,7 +2871,8 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { // Consume the previously pushed token. ConsumeAnyToken(); - assert(Tok.is(tok::l_brace) && "Inline objective-c method not starting with '{'"); + assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) && + "Inline objective-c method not starting with '{' or 'try'"); // Enter a scope for the method or c-fucntion body. ParseScope BodyScope(this, parseMethod @@ -2876,8 +2885,10 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl); else Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl); - - MCDecl = ParseFunctionStatementBody(MCDecl, BodyScope); + if (Tok.is(tok::kw_try)) + MCDecl = ParseFunctionTryBlock(MCDecl, BodyScope); + else + MCDecl = ParseFunctionStatementBody(MCDecl, BodyScope); if (Tok.getLocation() != OrigLoc) { // Due to parsing error, we either went over the cached tokens or diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 3531deba4f..5f00f87af3 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -1025,7 +1025,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, } return DP; } - else if (CurParsedObjCImpl && Tok.is(tok::l_brace) && + else if (CurParsedObjCImpl && + (Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) && !TemplateInfo.TemplateParams && Actions.CurContext->isTranslationUnit()) { MultiTemplateParamsArg TemplateParameterLists(Actions, 0, 0); diff --git a/test/SemaObjCXX/delay-parsing-func-tryblock.mm b/test/SemaObjCXX/delay-parsing-func-tryblock.mm new file mode 100644 index 0000000000..d0acc3f9b1 --- /dev/null +++ b/test/SemaObjCXX/delay-parsing-func-tryblock.mm @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -x objective-c++ -fcxx-exceptions -fsyntax-only -Werror -verify -Wno-objc-root-class %s +// rdar://10387088 + +@interface MyClass +- (void)someMethod; +@end + +struct BadReturn { + BadReturn(MyClass * myObject); + int bar(MyClass * myObject); + int i; +}; + +@implementation MyClass +- (void)someMethod { + [self privateMethod]; // clang already does not warn here +} + +int BadReturn::bar(MyClass * myObject) { + [myObject privateMethod]; + return 0; +} + +BadReturn::BadReturn(MyClass * myObject) try { +} catch(...) { + try { + [myObject privateMethod]; + [myObject privateMethod1]; + getMe = bar(myObject); + } catch(int ei) { + i = ei; + } catch(...) { + { + i = 0; + } + } +} + +- (void)privateMethod { } + +- (void)privateMethod1 { + getMe = getMe+1; +} + +static int getMe; + +@end |