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
This commit is contained in:
Kaelyn Uhrain 2012-04-19 23:17:45 +00:00
Родитель 0c5d0a8052
Коммит 434ed260eb
2 изменённых файлов: 18 добавлений и 2 удалений

Просмотреть файл

@ -931,8 +931,12 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult) {
// 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

Просмотреть файл

@ -204,3 +204,15 @@ template<template<typename> Foo, // expected-error {{template template parameter
template<typename> typename Bar, // expected-error {{template template parameter requires 'class' after the parameter list}}
template<typename> struct Baz> // expected-error {{template template parameter requires 'class' after the parameter list}}
void func();
namespace ShadowedTagType {
class Foo {
public:
enum Bar { X, Y };
void SetBar(Bar bar);
Bar Bar();
private:
Bar bar_; // expected-error {{must use 'enum' tag to refer to type 'Bar' in this scope}}
};
void Foo::SetBar(Bar bar) { bar_ = bar; } // expected-error {{must use 'enum' tag to refer to type 'Bar' in this scope}}