objective-C++: Delayed parsing of most common
member functions defined inside an objc class
implementation. wip.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161667 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 9f8f3ce..b830d9c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1340,12 +1340,7 @@
// 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
// start of a function definition in GCC-extended K&R C.
- // FIXME. Delayed parsing not done for c/c++ functions nested in namespace
- !isDeclarationAfterDeclarator() &&
- (!CurParsedObjCImpl || Tok.isNot(tok::l_brace) ||
- (getLangOpts().CPlusPlus &&
- (D.getCXXScopeSpec().isSet() ||
- !Actions.CurContext->isTranslationUnit())))) {
+ !isDeclarationAfterDeclarator()) {
if (isStartOfFunctionDefinition(D)) {
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
@@ -1401,14 +1396,6 @@
DeclsInGroup.push_back(FirstDecl);
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
// error, bail out.
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 7314228..3531deb 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1025,7 +1025,26 @@
}
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.
ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
diff --git a/test/SemaObjCXX/delay-parsing-cplusfuncs.mm b/test/SemaObjCXX/delay-parsing-cplusfuncs.mm
new file mode 100644
index 0000000..feae744
--- /dev/null
+++ b/test/SemaObjCXX/delay-parsing-cplusfuncs.mm
@@ -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