<div>On Tue, Feb 12, 2013 at 9:27 AM, Dmitri Gribenko <span dir="ltr"><<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>></span> wrote:</div><div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: gribozavr<br>
Date: Tue Feb 12 11:27:41 2013<br>
New Revision: 174980<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=174980&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=174980&view=rev</a><br>
Log:<br>
Accept over-qualified constructor in MSVC emulation mode<br>
<br>
MSVC accepts this:<br>
<br>
class A {<br>
  A::A();<br>
};<br>
<br>
Clang accepts regular member functions with extra qualification as an MS<br>
extension, but not constructors.  This changes the parser to defer rejecting<br>
qualified constructors so that the same Sema logic can apply to constructors as<br>
regular member functions.  This also improves the error message when MS<br>
extensions are disabled (in my opinion). Before it was:<br>
<br>
/Users/jason/Desktop/test.cpp:2:8: error: expected member name or ';' after declaration specifiers<br>
  A::A();<br>
  ~~~~ ^<br>
1 error generated.<br>
<br>
After:<br>
<br>
/Users/jason/Desktop/test.cpp:2:6: error: extra qualification on member 'A'<br>
  A::A();<br>
  ~~~^<br>
1 error generated.<br>
<br>
Patch by Jason Haslam.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Parse/ParseDecl.cpp<br>
    cfe/trunk/test/CXX/special/class.ctor/p1.cpp<br>
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=174980&r1=174979&r2=174980&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=174980&r1=174979&r2=174980&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Feb 12 11:27:41 2013<br>
@@ -2274,8 +2274,7 @@ void Parser::ParseDeclarationSpecifiers(<br>
         // name, then the code is ill-formed; this interpretation is<br>
         // reinforced by the NAD status of core issue 635.<br>
         TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);<br>
-        if ((DSContext == DSC_top_level ||<br>
-             (DSContext == DSC_class && DS.isFriendSpecified())) &&<br>
+        if ((DSContext == DSC_top_level || DSContext == DSC_class) &&<br>
             TemplateId->Name &&<br>
             Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {<br>
           if (isConstructorDeclarator()) {<br>
@@ -2325,8 +2324,7 @@ void Parser::ParseDeclarationSpecifiers(<br>
<br>
       // If we're in a context where the identifier could be a class name,<br>
       // check whether this is a constructor declaration.<br>
-      if ((DSContext == DSC_top_level ||<br>
-           (DSContext == DSC_class && DS.isFriendSpecified())) &&<br>
+      if ((DSContext == DSC_top_level || DSContext == DSC_class) &&<br>
           Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),<br>
                                      &SS)) {<br>
         if (isConstructorDeclarator())<br>
@@ -4445,8 +4443,7 @@ void Parser::ParseDirectDeclarator(Decla<br>
       else if (D.getCXXScopeSpec().isSet())<br>
         AllowConstructorName =<br>
           (D.getContext() == Declarator::FileContext ||<br>
-           (D.getContext() == Declarator::MemberContext &&<br>
-            D.getDeclSpec().isFriendSpecified()));<br>
+           D.getContext() == Declarator::MemberContext);<br>
       else<br>
         AllowConstructorName = (D.getContext() == Declarator::MemberContext);<br>
<br>
<br>
Modified: cfe/trunk/test/CXX/special/class.ctor/p1.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.ctor/p1.cpp?rev=174980&r1=174979&r2=174980&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.ctor/p1.cpp?rev=174980&r1=174979&r2=174980&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CXX/special/class.ctor/p1.cpp (original)<br>
+++ cfe/trunk/test/CXX/special/class.ctor/p1.cpp Tue Feb 12 11:27:41 2013<br>
@@ -1,5 +1,5 @@<br>
 // RUN: %clang_cc1 -fsyntax-only -verify %s<br>
-// expected-no-diagnostics<br>
+<br>
 struct X0 {<br>
   struct type { };<br>
<br>
@@ -41,3 +41,7 @@ template<typename T> X1<T>::X1() { }<br>
 template<typename T> (X1<T>::X1)(double) { }<br>
 template<typename T> X1<T> X1<T>::f1(int) { return 0; }<br>
 template<typename T> X1<T> (X1<T>::f1)(type) { return 0; }<br>
+<br>
+class A {<br>
+  A::A(); // expected-error{{extra qualification on member 'A'}}<br>
+};<br>
<br>
Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=174980&r1=174979&r2=174980&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=174980&r1=174979&r2=174980&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Tue Feb 12 11:27:41 2013<br>
@@ -204,3 +204,7 @@ struct PR11150 {<br>
 void f() { int __except = 0; }<br>
<br>
 void ::f(); // expected-warning{{extra qualification on member 'f'}}<br>
+<br>
+class C {<br>
+  C::C(); // expected-warning{{extra qualification on member 'C'}}<br>
+};<br></blockquote><div><br></div><div>We used to accept this code but now reject it:</div><div><br></div><div><div>typedef int T;</div><div>struct X { X::X(T()); } x;</div><div>void f() { X().T(); }</div></div><div><br>
</div><div>I'm not entirely sure whether the old or new behavior is correct (the new behavior matches g++ and EDG, though).</div></div></div>