forked from OSchip/llvm-project
Accept over-qualified constructor in MSVC emulation mode
MSVC accepts this: class A { A::A(); }; Clang accepts regular member functions with extra qualification as an MS extension, but not constructors. This changes the parser to defer rejecting qualified constructors so that the same Sema logic can apply to constructors as regular member functions. This also improves the error message when MS extensions are disabled (in my opinion). Before it was: /Users/jason/Desktop/test.cpp:2:8: error: expected member name or ';' after declaration specifiers A::A(); ~~~~ ^ 1 error generated. After: /Users/jason/Desktop/test.cpp:2:6: error: extra qualification on member 'A' A::A(); ~~~^ 1 error generated. Patch by Jason Haslam. llvm-svn: 174980
This commit is contained in:
parent
c5c9713fcf
commit
d1c91f1763
|
@ -2274,8 +2274,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
// name, then the code is ill-formed; this interpretation is
|
||||
// reinforced by the NAD status of core issue 635.
|
||||
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
|
||||
if ((DSContext == DSC_top_level ||
|
||||
(DSContext == DSC_class && DS.isFriendSpecified())) &&
|
||||
if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
|
||||
TemplateId->Name &&
|
||||
Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
|
||||
if (isConstructorDeclarator()) {
|
||||
|
@ -2325,8 +2324,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
|
||||
// If we're in a context where the identifier could be a class name,
|
||||
// check whether this is a constructor declaration.
|
||||
if ((DSContext == DSC_top_level ||
|
||||
(DSContext == DSC_class && DS.isFriendSpecified())) &&
|
||||
if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
|
||||
Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
|
||||
&SS)) {
|
||||
if (isConstructorDeclarator())
|
||||
|
@ -4445,8 +4443,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
|||
else if (D.getCXXScopeSpec().isSet())
|
||||
AllowConstructorName =
|
||||
(D.getContext() == Declarator::FileContext ||
|
||||
(D.getContext() == Declarator::MemberContext &&
|
||||
D.getDeclSpec().isFriendSpecified()));
|
||||
D.getContext() == Declarator::MemberContext);
|
||||
else
|
||||
AllowConstructorName = (D.getContext() == Declarator::MemberContext);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
struct X0 {
|
||||
struct type { };
|
||||
|
||||
|
@ -41,3 +41,7 @@ template<typename T> X1<T>::X1() { }
|
|||
template<typename T> (X1<T>::X1)(double) { }
|
||||
template<typename T> X1<T> X1<T>::f1(int) { return 0; }
|
||||
template<typename T> X1<T> (X1<T>::f1)(type) { return 0; }
|
||||
|
||||
class A {
|
||||
A::A(); // expected-error{{extra qualification on member 'A'}}
|
||||
};
|
||||
|
|
|
@ -204,3 +204,7 @@ struct PR11150 {
|
|||
void f() { int __except = 0; }
|
||||
|
||||
void ::f(); // expected-warning{{extra qualification on member 'f'}}
|
||||
|
||||
class C {
|
||||
C::C(); // expected-warning{{extra qualification on member 'C'}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue