objective-C++: Delayed parsing of most common

member functions defined inside an objc class
implementation. wip.

llvm-svn: 161667
This commit is contained in:
Fariborz Jahanian 2012-08-10 15:54:40 +00:00
parent b93df94238
commit 712bb81a6d
3 changed files with 59 additions and 15 deletions

View File

@ -1340,12 +1340,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// Look at the next token to make sure that this isn't a function // Look at the next token to make sure that this isn't a function
// declaration. We have to check this because __attribute__ might be the // declaration. We have to check this because __attribute__ might be the
// start of a function definition in GCC-extended K&R C. // start of a function definition in GCC-extended K&R C.
// FIXME. Delayed parsing not done for c/c++ functions nested in namespace !isDeclarationAfterDeclarator()) {
!isDeclarationAfterDeclarator() &&
(!CurParsedObjCImpl || Tok.isNot(tok::l_brace) ||
(getLangOpts().CPlusPlus &&
(D.getCXXScopeSpec().isSet() ||
!Actions.CurContext->isTranslationUnit())))) {
if (isStartOfFunctionDefinition(D)) { if (isStartOfFunctionDefinition(D)) {
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
@ -1401,14 +1396,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
DeclsInGroup.push_back(FirstDecl); DeclsInGroup.push_back(FirstDecl);
bool ExpectSemi = Context != Declarator::ForContext; bool ExpectSemi = Context != Declarator::ForContext;
if (CurParsedObjCImpl && D.isFunctionDeclarator() &&
Tok.is(tok::l_brace)) {
// Consume the tokens and store them for later parsing.
StashAwayMethodOrFunctionBodyTokens(FirstDecl);
CurParsedObjCImpl->HasCFunction = true;
ExpectSemi = false;
}
// If we don't have a comma, it is either the end of the list (a ';') or an // If we don't have a comma, it is either the end of the list (a ';') or an
// error, bail out. // error, bail out.

View File

@ -1025,7 +1025,26 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
} }
return DP; return DP;
} }
else if (CurParsedObjCImpl && Tok.is(tok::l_brace) &&
!TemplateInfo.TemplateParams &&
Actions.CurContext->isTranslationUnit()) {
MultiTemplateParamsArg TemplateParameterLists(Actions, 0, 0);
ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
Scope *ParentScope = getCurScope()->getParent();
D.setFunctionDefinitionKind(FDK_Definition);
Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,
move(TemplateParameterLists));
D.complete(FuncDecl);
D.getMutableDeclSpec().abort();
if (FuncDecl) {
// Consume the tokens and store them for later parsing.
StashAwayMethodOrFunctionBodyTokens(FuncDecl);
CurParsedObjCImpl->HasCFunction = true;
return FuncDecl;
}
}
// Enter a scope for the function body. // Enter a scope for the function body.
ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);

View File

@ -0,0 +1,38 @@
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Werror -verify -Wno-objc-root-class %s
// rdar://10387088
@interface MyClass
- (void)someMethod;
@end
struct S {
int bar(MyClass * myObject);
int gorfbar(MyClass * myObject);
};
@implementation MyClass
- (void)someMethod {
[self privateMethod]; // clang already does not warn here
}
int S::bar(MyClass * myObject) {
[myObject privateMethod];
return gorfbar(myObject);
}
- (void)privateMethod { }
int S::gorfbar(MyClass * myObject) {
[myObject privateMethod];
[myObject privateMethod1];
return getMe + bar(myObject);
}
- (void)privateMethod1 {
getMe = getMe+1;
}
static int getMe;
@end