In Parser::isCXXDeclarationSpecifier, consider a non-type identifier
followed by an identifier as declaration specificer (except for ObjC).
This allows e.g. an out-of-line C++ member function definitions to be
recognized as functions and not as variable declarations if the type
name for the first parameter is not recognized as a type--say, when there
is a function name shadowing an enum type name and the parameter is
missing the "enum" keyword needed to distinguish the two.
Note that returning TPResult::Error() instead of TPResult::True()
appears to have the same end result, while TPResult::Ambiguous()
results in a crash.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155163 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 28c5e8b..b5251a6 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -931,8 +931,12 @@
// recurse to handle whatever we get.
if (TryAnnotateTypeOrScopeToken())
return TPResult::Error();
- if (Tok.is(tok::identifier))
- return TPResult::False();
+ if (Tok.is(tok::identifier)) {
+ const Token &Next = NextToken();
+ bool NotObjC = !(getLangOpts().ObjC1 || getLangOpts().ObjC2);
+ return (NotObjC && Next.is(tok::identifier)) ?
+ TPResult::True() : TPResult::False();
+ }
return isCXXDeclarationSpecifier(BracedCastResult);
case tok::coloncolon: { // ::foo::bar