aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseObjc.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-07-02 23:37:09 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-07-02 23:37:09 +0000
commit6c89eafc90f5c51a0bf185a993961170aee530c2 (patch)
tree1c52effa180188efec187d7271e24009d3c1d36a /lib/Parse/ParseObjc.cpp
parenta9e8b9e3e90fcfe10a04624a89c39b63c32614d1 (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.cpp63
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;
}