objective-C++: Delayed parsing of most common
member functions defined inside an objc class implementation. wip. llvm-svn: 161667
This commit is contained in:
parent
b93df94238
commit
712bb81a6d
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue