зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
1093f4928a
Коммит
2eb362b50f
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче