diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-07-02 23:37:09 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-07-02 23:37:09 +0000 |
commit | 6c89eafc90f5c51a0bf185a993961170aee530c2 (patch) | |
tree | 1c52effa180188efec187d7271e24009d3c1d36a /lib/Parse/ParseObjc.cpp | |
parent | a9e8b9e3e90fcfe10a04624a89c39b63c32614d1 (diff) |
objective-c: just as we have done for method definitions,
c-functions declared in implementation should have their
parsing delayed until the end so, they can access forward
declared private methods. // rdar://10387088
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseObjc.cpp')
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 2540ad940d..35e4222c52 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1575,10 +1575,16 @@ void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) { assert(!Finished); P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl); for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) - P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i]); + P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], + true/*Methods*/); P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd); + if (HasCFunction) + for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) + P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], + false/*c-functions*/); + /// \brief Clear and free the cached objc methods. for (LateParsedObjCMethodContainer::iterator I = LateParsedObjCMethods.begin(), @@ -1915,6 +1921,19 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { AutoreleasePoolBody.take()); } +/// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them +/// for later parsing. +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. + Toks.push_back(Tok); + ConsumeBrace(); + // Consume everything up to (and including) the matching right brace. + ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); +} + /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' /// Decl *Parser::ParseObjCMethodDefinition() { @@ -1955,15 +1974,7 @@ Decl *Parser::ParseObjCMethodDefinition() { if (CurParsedObjCImpl) { // Consume the tokens and store them for later parsing. - LexedMethod* LM = new LexedMethod(this, MDecl); - CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM); - CachedTokens &Toks = LM->Toks; - // Begin by storing the '{' token. - Toks.push_back(Tok); - ConsumeBrace(); - // Consume everything up to (and including) the matching right brace. - ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); - + StashAwayMethodOrFunctionBodyTokens(MDecl); } else { ConsumeBrace(); SkipUntil(tok::r_brace, /*StopAtSemi=*/false); @@ -2821,8 +2832,15 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { T.getCloseLocation())); } -Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) { - +void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { + // MCDecl might be null due to error in method or c-function prototype, etc. + Decl *MCDecl = LM.D; + bool skip = MCDecl && + ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) || + (!parseMethod && Actions.isObjCMethodDecl(MCDecl))); + if (skip) + return; + // Save the current token position. SourceLocation OrigLoc = Tok.getLocation(); @@ -2832,24 +2850,25 @@ Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) { LM.Toks.push_back(Tok); PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); - // MDecl might be null due to error in method prototype, etc. - Decl *MDecl = LM.D; // Consume the previously pushed token. ConsumeAnyToken(); assert(Tok.is(tok::l_brace) && "Inline objective-c method not starting with '{'"); SourceLocation BraceLoc = Tok.getLocation(); - // Enter a scope for the method body. + // Enter a scope for the method or c-fucntion body. ParseScope BodyScope(this, - Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope); + parseMethod + ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope + : Scope::FnScope|Scope::DeclScope); - // Tell the actions module that we have entered a method definition with the - // specified Declarator for the method. - Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl); + // Tell the actions module that we have entered a method or c-function definition + // with the specified Declarator for the method/function. + Actions.ActOnStartOfObjCMethodOrCFunctionDef(getCurScope(), MCDecl, parseMethod); if (SkipFunctionBodies && trySkippingFunctionBody()) { BodyScope.Exit(); - return Actions.ActOnFinishFunctionBody(MDecl, 0); + (void)Actions.ActOnFinishFunctionBody(MCDecl, 0); + return; } StmtResult FnBody(ParseCompoundStatementBody()); @@ -2864,7 +2883,7 @@ Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) { // Leave the function body scope. BodyScope.Exit(); - MDecl = Actions.ActOnFinishFunctionBody(MDecl, FnBody.take()); + (void)Actions.ActOnFinishFunctionBody(MCDecl, FnBody.take()); if (Tok.getLocation() != OrigLoc) { // Due to parsing error, we either went over the cached tokens or @@ -2878,5 +2897,5 @@ Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) { ConsumeAnyToken(); } - return MDecl; + return; } |