[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-28 Thread Alan Zhao via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4848f3bf2ff5: [C++2a] P0634r3: Down with typename! (authored 
by Rakete, committed by ayzhao).

Changed prior to commit:
  https://reviews.llvm.org/D53847?vs=463351=463596#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -959,11 +959,7 @@
   
   
 https://wg21.link/p2092r0;>P2092R0
-
-  Partial
-typename not yet optional (depends on P0634R3).
-  
-
+Clang 16
   
   
 https://wg21.link/p2113r0;>P2113R0
@@ -1052,7 +1048,7 @@
 
   typename optional in more contexts
   https://wg21.link/p0634r3;>P0634R3
-  No
+  Clang 16
 
 
   Pack expansion in lambda init-capture
Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-28 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

In D53847#3819344 , @ayzhao wrote:

> add test and fix for P2092 

These changes look good to me, thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 463351.
ayzhao added a comment.

add test and fix for P2092 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
  clang/test/CXX/module/module.interface/p2-2.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -959,11 +959,7 @@
   
   
 https://wg21.link/p2092r0;>P2092R0
-
-  Partial
-typename not yet optional (depends on P0634R3).
-  
-
+Clang 16
   
   
 https://wg21.link/p2113r0;>P2113R0
@@ -1052,7 +1048,7 @@
 
   typename optional in more contexts
   https://wg21.link/p0634r3;>P0634R3
-  No
+  Clang 16
 
 
   Pack expansion in lambda init-capture
Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

In D53847#3819200 , @cor3ntin wrote:

> Good catch
>
>   template
>   concept K = requires (typename T::Type X) { // (3)
>   X.next();
>   }
>
> That typename should be optional. Can you add a test for that? If it works 
> you can mark P2092  as fully supported.

Done.

The test originally failed, but it was a simple fix to get it to work.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-27 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

Good catch

  template
  concept K = requires (typename T::Type X) { // (3)
  X.next();
  }

That typename should be optional. Can you add a test for that? If it works you 
can mark P2092  as fully supported.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

In D53847#3817376 , @cor3ntin wrote:

> It's great to see this make progress.
> Can you update cxx_status.html and ReleaseNotes.txt?

Done.

I also saw that P2092R0 was marked as partially supported in `cxx_status.html` 
due to missing support for P0634R3, but I'm not familiar enough with P2092R0 to 
update that entry.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 463334.
ayzhao added a comment.

update cxx_status.html and ReleaseNotes.rst + rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/module/module.interface/p2-2.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1052,7 +1052,7 @@
 
   typename optional in more contexts
   https://wg21.link/p0634r3;>P0634R3
-  No
+  Clang 16
 
 
   Pack expansion in lambda init-capture
Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-27 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

It's great to see this make progress.
Can you update cxx_status.html and ReleaseNotes.txt?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-26 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462969.
ayzhao added a comment.

clang-format + rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/module/module.interface/p2-2.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-26 Thread Erich Keane via Phabricator via cfe-commits
erichkeane accepted this revision.
erichkeane added a comment.
This revision is now accepted and ready to land.

Thanks for looking into it. I think you're right that it is a mistake that we 
accepted that without the 'struct' keyword after a quick look, so I think I am 
OK with this. Please give @aaron.ballman a day or so to take a look if he 
wishes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-23 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

In D53847#3809072 , @erichkeane wrote:

> I think this is on the right track, but would like to see more work done on 
> that fixme before we commit (or at least better understand what is causing 
> this).  I'm afraid of what else can get us into that situation besides the 
> export-decl.

The `FIXME` has been removed; the problem seems to be that the test is broken. 
See https://reviews.llvm.org/D53847?id=462032#inline-1297092


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-23 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked an inline comment as done.
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:367
+// with this method returning a non-null ParsedType?
+if (isa(CurContext))
+  return nullptr;

ayzhao wrote:
> ayzhao wrote:
> > erichkeane wrote:
> > > Hmm... this scares me quite a bit, I don't really know what other fallout 
> > > results from this, or other code that would hit here.
> > > 
> > > We should probably spend more time making sure we understand this better.
> > Following up with my [previous 
> > comment](https://reviews.llvm.org/D53847?id=459205#inline-1291007) about 
> > the failing test that this hack was supposed to fix:
> > 
> > I added the `typename` keyword to the `export template` statement and lo 
> > and behold, Clang emits the same "declaration does not declare anything" 
> > diagnostic instead of the namespace scope diagnostic [0].
> > 
> > To me, this feels like that the [original test case was 
> > wrong](https://github.com/llvm/llvm-project/blob/a707675dbba9ca3ec6e668f86fea2240a85ca171/clang/test/CXX/module/module.interface/p2-2.cpp#L18):
> > 
> > 1. There should've been a `typename` keyword in the `export` statement. 
> > Perhaps the author of the test wasn't aware that the `typename` keyword was 
> > required, or perhaps the author already assumed that P0634r3 was already 
> > implemented in clang.
> > 1. The test currently passing (with Clang emitting the namespace diagnostic 
> > instead of the declaration diagnostic) seems to be a freak coincidence.
> > 
> > I'm not familiar at all with C++ modules - is this a bug with exporting 
> > types?
> > 
> > [0]: https://godbolt.org/z/PYvh68Tq7
> small fix: I linked to the wrong line when referencing the original test 
> case. The link should be 
> https://github.com/llvm/llvm-project/blob/a707675dbba9ca3ec6e668f86fea2240a85ca171/clang/test/CXX/module/module.interface/p2-2.cpp#L17
So my belief now is that the test `p2-2.cpp` is broken. I've removed the 
`FIXME` hack, and I created D134578 to fix the test. To keep the bots happy, I 
also cherry-picked D134578 into this patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-23 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462633.
ayzhao added a comment.

remove the hack for the test p2-2.cpp and patch in patch in D134578 
 which fixes the test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/module/module.interface/p2-2.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-23 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked 2 inline comments as done.
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:367
+// with this method returning a non-null ParsedType?
+if (isa(CurContext))
+  return nullptr;

ayzhao wrote:
> erichkeane wrote:
> > Hmm... this scares me quite a bit, I don't really know what other fallout 
> > results from this, or other code that would hit here.
> > 
> > We should probably spend more time making sure we understand this better.
> Following up with my [previous 
> comment](https://reviews.llvm.org/D53847?id=459205#inline-1291007) about the 
> failing test that this hack was supposed to fix:
> 
> I added the `typename` keyword to the `export template` statement and lo and 
> behold, Clang emits the same "declaration does not declare anything" 
> diagnostic instead of the namespace scope diagnostic [0].
> 
> To me, this feels like that the [original test case was 
> wrong](https://github.com/llvm/llvm-project/blob/a707675dbba9ca3ec6e668f86fea2240a85ca171/clang/test/CXX/module/module.interface/p2-2.cpp#L18):
> 
> 1. There should've been a `typename` keyword in the `export` statement. 
> Perhaps the author of the test wasn't aware that the `typename` keyword was 
> required, or perhaps the author already assumed that P0634r3 was already 
> implemented in clang.
> 1. The test currently passing (with Clang emitting the namespace diagnostic 
> instead of the declaration diagnostic) seems to be a freak coincidence.
> 
> I'm not familiar at all with C++ modules - is this a bug with exporting types?
> 
> [0]: https://godbolt.org/z/PYvh68Tq7
small fix: I linked to the wrong line when referencing the original test case. 
The link should be 
https://github.com/llvm/llvm-project/blob/a707675dbba9ca3ec6e668f86fea2240a85ca171/clang/test/CXX/module/module.interface/p2-2.cpp#L17


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-23 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:367
+// with this method returning a non-null ParsedType?
+if (isa(CurContext))
+  return nullptr;

erichkeane wrote:
> Hmm... this scares me quite a bit, I don't really know what other fallout 
> results from this, or other code that would hit here.
> 
> We should probably spend more time making sure we understand this better.
Following up with my [previous 
comment](https://reviews.llvm.org/D53847?id=459205#inline-1291007) about the 
failing test that this hack was supposed to fix:

I added the `typename` keyword to the `export template` statement and lo and 
behold, Clang emits the same "declaration does not declare anything" diagnostic 
instead of the namespace scope diagnostic [0].

To me, this feels like that the [original test case was 
wrong](https://github.com/llvm/llvm-project/blob/a707675dbba9ca3ec6e668f86fea2240a85ca171/clang/test/CXX/module/module.interface/p2-2.cpp#L18):

1. There should've been a `typename` keyword in the `export` statement. Perhaps 
the author of the test wasn't aware that the `typename` keyword was required, 
or perhaps the author already assumed that P0634r3 was already implemented in 
clang.
1. The test currently passing (with Clang emitting the namespace diagnostic 
instead of the declaration diagnostic) seems to be a freak coincidence.

I'm not familiar at all with C++ modules - is this a bug with exporting types?

[0]: https://godbolt.org/z/PYvh68Tq7


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-23 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462587.
ayzhao marked an inline comment as done.
ayzhao added a comment.

address some more review comments + rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked 4 inline comments as done.
ayzhao added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

aaron.ballman wrote:
> erichkeane wrote:
> > aaron.ballman wrote:
> > > erichkeane wrote:
> > > > aaron.ballman wrote:
> > > > > shafik wrote:
> > > > > > Instead of adding yet another `bool` flag maybe we can consider 
> > > > > > using something like `enum isFriend : bool {No, Yes}`.
> > > > > > 
> > > > > > I am sure @aaron.ballman will want to chime in here as well.
> > > > > Heh, so this is where I get worried about the scalability of using 
> > > > > enums for these. We really want to use three different enums here, 
> > > > > but do we really want to *add* three different enums? I'm unconvinced.
> > > > > 
> > > > > However, if we can come up with some template magic to allow for 
> > > > > named bool parameters as a generic interface, that would be valuable 
> > > > > to use.
> > > > I prefer enums over bools TBH, even if we end up with a million of then 
> > > > somewhere.
> > > > 
> > > > That said, what about:
> > > > 
> > > > https://godbolt.org/z/Kz6jdjobj
> > > > 
> > > > ```
> > > > template
> > > > class Is {
> > > > Is(bool v) : value(v){}
> > > >   public:
> > > >   bool value;
> > > >   static const Is Yes() { return Is{true};}
> > > >   static const Is No() { return Is{false};}
> > > > 
> > > >   operator bool() { return value; }
> > > > };
> > > > 
> > > > class Friend{}; // #1
> > > >  
> > > > void foo(Is f) {
> > > > if (f) {
> > > > ///...
> > > > }
> > > > }
> > > > 
> > > > void baz() {
> > > > foo(Is::Yes());
> > > > }
> > > > ```
> > > > 
> > > > Adding a 'new' thing is as simple as just adding #1 for anything we 
> > > > care about.  We might want to put them in a namespace of some sort, but 
> > > > perhaps not awful?
> > > Yeah, this is along the lines of what I was thinking of! However, I'm 
> > > still concerned about that approach because it involves adding a new type 
> > > for every situation we have a bool. Empty classes to use as a tag 
> > > definitely works, but I was hoping we could use a string literal rather 
> > > than a tag type so that we don't have the extra compile time overhead of 
> > > adding hundreds of new empty classes. e.g.,
> > > ```
> > > void foo(Is<"Friend"> f) {
> > >   if (f) {
> > >  // ...
> > >   }
> > > }
> > > 
> > > void baz() {
> > >   foo(Is<"Friend">::Yes); // Yay
> > >   foo(Is<"Enemy">::Yes); // Error for type mismatch with Is<"Friend">
> > > }
> > > ```
> > > However, that might require compiling with C++20 (I don't recall), so it 
> > > may not be a viable idea.
> > Yeah, referring to stringliterals is troublesome in C++17.  However, we 
> > COULD do that like:
> > 
> > ```
> > void foo(Is<"Friend"_Is> f) {
> >   if (f) {
> >  // ...
> >   }
> > }
> > 
> > void baz() {
> >   foo(Is<"Friend"_Is>::Yes); // Yay
> >   foo(Is<"Enemy"_Is>::Yes); // Error for type mismatch with Is<"Friend">
> > }```
> > 
> > by making operator _Is return an integer_sequence.
> That's a really neat idea! If you want to work it up into something that 
> could be plausible to add to ADT, I think it's worth an RFC to add the 
> interface. I'm guessing the diagnostic behavior of that would be kind of 
> gross, but once we move to C++20 we'd be able to use string literal template 
> arguments directly and get better diagnostic behavior. The critical part is 
> that the code is readable and we get diagnostics when passing an argument to 
> the wrong parameter.
I added a `FriendSpecified` enum for now.

I'm going to mark the comment chain as done so that they don't unnecessarily 
block the review.

I agree with the idea of a generic type to represent boolean arguments, but I 
think it would be out of scope of this patch and that Discourse would be a more 
appropriate place to discuss this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462317.
ayzhao added a comment.

fix spacing


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462315.
ayzhao added a comment.

Add FriendSpecified enum


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Sema/DeclSpec.h:1806
+// typename is allowed (C++2a [temp.res]p5]).
+enum class ImplicitTypenameContext {
+  No,

ayzhao wrote:
> aaron.ballman wrote:
> > Not opposed to this construct, but I am worried about how well it will 
> > scale. I don't know that we want to add a bunch of named enums that all 
> > boil down to a bool. (If someone thinks they have good ideas here, that'd 
> > be a good RFC topic for Discourse because we have a ton of interfaces that 
> > take a bunch of bools.)
> Ack. IIRC this `enum` was created as a result of [this 
> comment](https://reviews.llvm.org/D53847?id=198139#inline-545979) by @rsmith 
> expressing concern over adding an additional `bool` parameter to a function 
> with a lot of preexisting `bool` args.
> Ack. IIRC this enum was created as a result of this comment by @rsmith 
> expressing concern over adding an additional bool parameter to a function 
> with a lot of preexisting bool args.

Yeah, I spotted his suggestion (and am totally fine with implementing it here 
as you've done). I was mostly thinking about the future when someone tries to 
do this for every set of 2 or more bool parameters. :-D



Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

erichkeane wrote:
> aaron.ballman wrote:
> > erichkeane wrote:
> > > aaron.ballman wrote:
> > > > shafik wrote:
> > > > > Instead of adding yet another `bool` flag maybe we can consider using 
> > > > > something like `enum isFriend : bool {No, Yes}`.
> > > > > 
> > > > > I am sure @aaron.ballman will want to chime in here as well.
> > > > Heh, so this is where I get worried about the scalability of using 
> > > > enums for these. We really want to use three different enums here, but 
> > > > do we really want to *add* three different enums? I'm unconvinced.
> > > > 
> > > > However, if we can come up with some template magic to allow for named 
> > > > bool parameters as a generic interface, that would be valuable to use.
> > > I prefer enums over bools TBH, even if we end up with a million of then 
> > > somewhere.
> > > 
> > > That said, what about:
> > > 
> > > https://godbolt.org/z/Kz6jdjobj
> > > 
> > > ```
> > > template
> > > class Is {
> > > Is(bool v) : value(v){}
> > >   public:
> > >   bool value;
> > >   static const Is Yes() { return Is{true};}
> > >   static const Is No() { return Is{false};}
> > > 
> > >   operator bool() { return value; }
> > > };
> > > 
> > > class Friend{}; // #1
> > >  
> > > void foo(Is f) {
> > > if (f) {
> > > ///...
> > > }
> > > }
> > > 
> > > void baz() {
> > > foo(Is::Yes());
> > > }
> > > ```
> > > 
> > > Adding a 'new' thing is as simple as just adding #1 for anything we care 
> > > about.  We might want to put them in a namespace of some sort, but 
> > > perhaps not awful?
> > Yeah, this is along the lines of what I was thinking of! However, I'm still 
> > concerned about that approach because it involves adding a new type for 
> > every situation we have a bool. Empty classes to use as a tag definitely 
> > works, but I was hoping we could use a string literal rather than a tag 
> > type so that we don't have the extra compile time overhead of adding 
> > hundreds of new empty classes. e.g.,
> > ```
> > void foo(Is<"Friend"> f) {
> >   if (f) {
> >  // ...
> >   }
> > }
> > 
> > void baz() {
> >   foo(Is<"Friend">::Yes); // Yay
> >   foo(Is<"Enemy">::Yes); // Error for type mismatch with Is<"Friend">
> > }
> > ```
> > However, that might require compiling with C++20 (I don't recall), so it 
> > may not be a viable idea.
> Yeah, referring to stringliterals is troublesome in C++17.  However, we COULD 
> do that like:
> 
> ```
> void foo(Is<"Friend"_Is> f) {
>   if (f) {
>  // ...
>   }
> }
> 
> void baz() {
>   foo(Is<"Friend"_Is>::Yes); // Yay
>   foo(Is<"Enemy"_Is>::Yes); // Error for type mismatch with Is<"Friend">
> }```
> 
> by making operator _Is return an integer_sequence.
That's a really neat idea! If you want to work it up into something that could 
be plausible to add to ADT, I think it's worth an RFC to add the interface. I'm 
guessing the diagnostic behavior of that would be kind of gross, but once we 
move to C++20 we'd be able to use string literal template arguments directly 
and get better diagnostic behavior. The critical part is that the code is 
readable and we get diagnostics when passing an argument to the wrong parameter.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

aaron.ballman wrote:
> erichkeane wrote:
> > aaron.ballman wrote:
> > > shafik wrote:
> > > > Instead of adding yet another `bool` flag maybe we can consider using 
> > > > something like `enum isFriend : bool {No, Yes}`.
> > > > 
> > > > I am sure @aaron.ballman will want to chime in here as well.
> > > Heh, so this is where I get worried about the scalability of using enums 
> > > for these. We really want to use three different enums here, but do we 
> > > really want to *add* three different enums? I'm unconvinced.
> > > 
> > > However, if we can come up with some template magic to allow for named 
> > > bool parameters as a generic interface, that would be valuable to use.
> > I prefer enums over bools TBH, even if we end up with a million of then 
> > somewhere.
> > 
> > That said, what about:
> > 
> > https://godbolt.org/z/Kz6jdjobj
> > 
> > ```
> > template
> > class Is {
> > Is(bool v) : value(v){}
> >   public:
> >   bool value;
> >   static const Is Yes() { return Is{true};}
> >   static const Is No() { return Is{false};}
> > 
> >   operator bool() { return value; }
> > };
> > 
> > class Friend{}; // #1
> >  
> > void foo(Is f) {
> > if (f) {
> > ///...
> > }
> > }
> > 
> > void baz() {
> > foo(Is::Yes());
> > }
> > ```
> > 
> > Adding a 'new' thing is as simple as just adding #1 for anything we care 
> > about.  We might want to put them in a namespace of some sort, but perhaps 
> > not awful?
> Yeah, this is along the lines of what I was thinking of! However, I'm still 
> concerned about that approach because it involves adding a new type for every 
> situation we have a bool. Empty classes to use as a tag definitely works, but 
> I was hoping we could use a string literal rather than a tag type so that we 
> don't have the extra compile time overhead of adding hundreds of new empty 
> classes. e.g.,
> ```
> void foo(Is<"Friend"> f) {
>   if (f) {
>  // ...
>   }
> }
> 
> void baz() {
>   foo(Is<"Friend">::Yes); // Yay
>   foo(Is<"Enemy">::Yes); // Error for type mismatch with Is<"Friend">
> }
> ```
> However, that might require compiling with C++20 (I don't recall), so it may 
> not be a viable idea.
Yeah, referring to stringliterals is troublesome in C++17.  However, we COULD 
do that like:

```
void foo(Is<"Friend"_Is> f) {
  if (f) {
 // ...
  }
}

void baz() {
  foo(Is<"Friend"_Is>::Yes); // Yay
  foo(Is<"Enemy"_Is>::Yes); // Error for type mismatch with Is<"Friend">
}```

by making operator _Is return an integer_sequence.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/include/clang/Sema/DeclSpec.h:1806
+// typename is allowed (C++2a [temp.res]p5]).
+enum class ImplicitTypenameContext {
+  No,

aaron.ballman wrote:
> Not opposed to this construct, but I am worried about how well it will scale. 
> I don't know that we want to add a bunch of named enums that all boil down to 
> a bool. (If someone thinks they have good ideas here, that'd be a good RFC 
> topic for Discourse because we have a ton of interfaces that take a bunch of 
> bools.)
Ack. IIRC this `enum` was created as a result of [this 
comment](https://reviews.llvm.org/D53847?id=198139#inline-545979) by @rsmith 
expressing concern over adding an additional `bool` parameter to a function 
with a lot of preexisting `bool` args.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462239.
ayzhao marked 2 inline comments as done.
ayzhao added a comment.

address some comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

erichkeane wrote:
> aaron.ballman wrote:
> > shafik wrote:
> > > Instead of adding yet another `bool` flag maybe we can consider using 
> > > something like `enum isFriend : bool {No, Yes}`.
> > > 
> > > I am sure @aaron.ballman will want to chime in here as well.
> > Heh, so this is where I get worried about the scalability of using enums 
> > for these. We really want to use three different enums here, but do we 
> > really want to *add* three different enums? I'm unconvinced.
> > 
> > However, if we can come up with some template magic to allow for named bool 
> > parameters as a generic interface, that would be valuable to use.
> I prefer enums over bools TBH, even if we end up with a million of then 
> somewhere.
> 
> That said, what about:
> 
> https://godbolt.org/z/Kz6jdjobj
> 
> ```
> template
> class Is {
> Is(bool v) : value(v){}
>   public:
>   bool value;
>   static const Is Yes() { return Is{true};}
>   static const Is No() { return Is{false};}
> 
>   operator bool() { return value; }
> };
> 
> class Friend{}; // #1
>  
> void foo(Is f) {
> if (f) {
> ///...
> }
> }
> 
> void baz() {
> foo(Is::Yes());
> }
> ```
> 
> Adding a 'new' thing is as simple as just adding #1 for anything we care 
> about.  We might want to put them in a namespace of some sort, but perhaps 
> not awful?
Yeah, this is along the lines of what I was thinking of! However, I'm still 
concerned about that approach because it involves adding a new type for every 
situation we have a bool. Empty classes to use as a tag definitely works, but I 
was hoping we could use a string literal rather than a tag type so that we 
don't have the extra compile time overhead of adding hundreds of new empty 
classes. e.g.,
```
void foo(Is<"Friend"> f) {
  if (f) {
 // ...
  }
}

void baz() {
  foo(Is<"Friend">::Yes); // Yay
  foo(Is<"Enemy">::Yes); // Error for type mismatch with Is<"Friend">
}
```
However, that might require compiling with C++20 (I don't recall), so it may 
not be a viable idea.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

aaron.ballman wrote:
> shafik wrote:
> > Instead of adding yet another `bool` flag maybe we can consider using 
> > something like `enum isFriend : bool {No, Yes}`.
> > 
> > I am sure @aaron.ballman will want to chime in here as well.
> Heh, so this is where I get worried about the scalability of using enums for 
> these. We really want to use three different enums here, but do we really 
> want to *add* three different enums? I'm unconvinced.
> 
> However, if we can come up with some template magic to allow for named bool 
> parameters as a generic interface, that would be valuable to use.
I prefer enums over bools TBH, even if we end up with a million of then 
somewhere.

That said, what about:

https://godbolt.org/z/Kz6jdjobj

```
template
class Is {
Is(bool v) : value(v){}
  public:
  bool value;
  static const Is Yes() { return Is{true};}
  static const Is No() { return Is{false};}

  operator bool() { return value; }
};

class Friend{}; // #1
 
void foo(Is f) {
if (f) {
///...
}
}

void baz() {
foo(Is::Yes());
}
```

Adding a 'new' thing is as simple as just adding #1 for anything we care about. 
 We might want to put them in a namespace of some sort, but perhaps not awful?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Parse/Parser.h:2343
+  static ImplicitTypenameContext
+  isImplicitTypenameContext(DeclSpecContext DSC) {
+switch (DSC) {

Starting with `is` implies contextual conversion to bool (generally), so I'd 
suggest renaming.



Comment at: clang/include/clang/Sema/DeclSpec.h:1806
+// typename is allowed (C++2a [temp.res]p5]).
+enum class ImplicitTypenameContext {
+  No,

Not opposed to this construct, but I am worried about how well it will scale. I 
don't know that we want to add a bunch of named enums that all boil down to a 
bool. (If someone thinks they have good ideas here, that'd be a good RFC topic 
for Discourse because we have a ton of interfaces that take a bunch of bools.)



Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

shafik wrote:
> Instead of adding yet another `bool` flag maybe we can consider using 
> something like `enum isFriend : bool {No, Yes}`.
> 
> I am sure @aaron.ballman will want to chime in here as well.
Heh, so this is where I get worried about the scalability of using enums for 
these. We really want to use three different enums here, but do we really want 
to *add* three different enums? I'm unconvinced.

However, if we can come up with some template magic to allow for named bool 
parameters as a generic interface, that would be valuable to use.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 46.
ayzhao marked 2 inline comments as done.
ayzhao added a comment.

address some review comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

I think this is on the right track, but would like to see more work done on 
that fixme before we commit (or at least better understand what is causing 
this).  I'm afraid of what else can get us into that situation besides the 
export-decl.




Comment at: clang/lib/Sema/SemaDecl.cpp:367
+// with this method returning a non-null ParsedType?
+if (isa(CurContext))
+  return nullptr;

Hmm... this scares me quite a bit, I don't really know what other fallout 
results from this, or other code that would hit here.

We should probably spend more time making sure we understand this better.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-22 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a subscriber: aaron.ballman.
shafik added a comment.

I made mostly small comments but I think @aaron.ballman and/or @erichkeane 
should take a look as well.




Comment at: clang/lib/Parse/ParseDecl.cpp:3434-3435
  ) &&
-  isConstructorDeclarator(/*Unqualified*/ false))
+  isConstructorDeclarator(/*Unqualified*/ false,
+  /*DeductionGuide*/ false,
+  DS.isFriendSpecified()))





Comment at: clang/lib/Parse/ParseDecl.cpp:5592
+bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
+ bool IsFriend) {
   TentativeParsingAction TPA(*this);

Instead of adding yet another `bool` flag maybe we can consider using something 
like `enum isFriend : bool {No, Yes}`.

I am sure @aaron.ballman will want to chime in here as well.



Comment at: clang/lib/Parse/ParseTemplate.cpp:20
 #include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"

Do we still need this?



Comment at: clang/lib/Parse/ParseTemplate.cpp:1450
 TemplateArgsPtr, TemplateId->RAngleLoc,
-/*IsCtorOrDtorName*/ false, IsClassName);
+/*IsCtorOrDtorName*/ false, IsClassName, 
AllowImplicitTypename);
   // Create the new "type" annotation token.





Comment at: clang/lib/Sema/Sema.cpp:51
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/TimeProfiler.h"

Do we need this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-21 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 462032.
ayzhao added a comment.

rebase + upload; also friendly ping!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/include/clang/Sema/DeclSpec.h:1918
+  /// Lookup result of declarator, if any.
+  std::unique_ptr PrevLookupResult;
+

shafik wrote:
> Why do we need this one shot previous lookup result? I am struggling to see 
> the connection between `isDeclaratorFunctionLike(...)` and where we check 
> `hasPrevLookupResult(...)` and why it matter.
Removed



Comment at: clang/lib/Sema/DeclSpec.cpp:1502-1504
+  LookupResult LR = std::move(*PrevLookupResult);
+  PrevLookupResult.reset();
+  return LR;

shafik wrote:
> 
Ended up removing `PrevLookupResult` per my other comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 461729.
ayzhao marked 2 inline comments as done.
ayzhao added a comment.

remove PrevLookupResult + put Declarator(...) and ~Declarator() definitions 
back in the header files to reduce the diff since we're no longer overloading 
the constructor.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 461699.
ayzhao added a comment.

rebase + clang-format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked an inline comment as done.
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaTemplate.cpp:3377-3379
   // FIXME: This is not quite correct recovery as we don't transform SS
   // into the corresponding dependent form (and we don't diagnose missing
   // 'template' keywords within SS as a result).

ayzhao wrote:
> Rakete wrote:
> > rsmith wrote:
> > > Rakete wrote:
> > > > Rakete wrote:
> > > > > rsmith wrote:
> > > > > > This FIXME is concerning. Is this a problem with this patch? (Is 
> > > > > > the FIXME wrong now?)
> > > > > Yes you're right, I believe it not longer applies due to the change 
> > > > > in ParseDecl.cpp in ParseDeclarationSpecifiers.
> > > > Although I'm not that sure I fully understand what that comments 
> > > > alludes to.
> > > The example would be something like this:
> > > 
> > > ```
> > > template struct X {
> > >   template struct Y { Y(); using V = int; };
> > >   template typename Y::V f();
> > > };
> > > template template
> > > X::Y::V X::f() {} 
> > > ```
> > > 
> > > Clang trunk today points out that the `typename` keyword is missing on 
> > > the final line, but fails to point out that the `template` keyword is 
> > > also missing. The reason is that in the case where that construct is 
> > > valid:
> > > 
> > > ```
> > > template template
> > > X::Y::Y() {}
> > > ```
> > > 
> > > ... we are "entering the context" of the //nested-name-specifier//, which 
> > > means we don't need a `template` keyword.
> > > 
> > > If the FIXME is fixed, then we should diagnose the missing `template` in 
> > > the above program.
> > > 
> > > Also, because we don't rebuild the //nested-name-specifier// as a 
> > > dependent nested name specifier in this case, we fail to match it against 
> > > the declaration in the class, so in my example above, we also produce an 
> > > "out-of-line definition does not match" error.
> > > 
> > > 
> > > A closely-related issue can be seen in an example such as:
> > > 
> > > ```
> > > template struct X {
> > >   template struct Y { Y(); typedef void V; }; 
> > >   template typename Y::V::W f();
> > > };
> > > template template
> > > X::template Y::V::W X::f() { return 0; } 
> > > ```
> > > 
> > > Here, we produce a completely bogus error:
> > > 
> > > ```
> > > :6:13: error: 'X::Y::V' (aka 'void') is not a class, namespace, or 
> > > enumeration
> > > X::template Y::V::W X::f() { return 0; } 
> > > ^
> > > ```
> > > 
> > > ... because we parse this in "entering context" mode and so resolve 
> > > `X::Y::V` to the type in the primary template (that is, `void`). 
> > > That's wrong: we should defer resolving this name to a type until we know 
> > > what `T` and `U` are, or until we know that we're *actually* entering the 
> > > context. Specifically, the above program can be extended as follows:
> > > 
> > > ```
> > > template<> template<> struct X::Y {
> > >   struct V { using W = int; };
> > > };
> > > void call(X x) { x.f(); } // OK, f returns int
> > > ```
> > > 
> > > The above program should be accepted by this patch, if the FIXME is 
> > > indeed now fixed. Please add it as a testcase :)
> > Oh ok, got it thanks. So no, the program is still not accepted in clang, 
> > and a pretty dumb side effect of it is that 
> > 
> > ```
> > template struct X {
> >   template struct Y { Y(); using V = int; };
> >   template typename Y::V f();
> > };
> > template template
> > X::Y::V X::f() {}
> > ```
> > 
> > is accepted without the diagnostic for the missing `template`. :(
> Currently looking into this.
> 
> It is interesting to note that for the following example in one of the parent 
> comments:
> 
> ```
> template struct X {
>   template struct Y { Y(); typedef void V; }; 
>   template typename Y::V::W f();
> };
> template template
> X::template Y::V::W X::f() { return 0; }
> ```
> 
> GCC doesn't like the fact that the `template` keyword is on the final line if 
> compiled with `-pedantic` [0]:
> 
> ```
> :6:16: warning: keyword 'template' not allowed in declarator-id 
> [-Wpedantic]
> 6 | X::template Y::V::W X::f() { return 0; }
>   |^~~~
> Compiler returned: 0
> ```
> 
> [0]: https://godbolt.org/z/dYddW3ErY
This is starting to feel like a separate issue. I filed 
https://github.com/llvm/llvm-project/issues/57853 to track it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-19 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 461403.
ayzhao added a comment.

remove extra blank line


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-19 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 461401.
ayzhao added a comment.

fix typo


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-16 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaTemplate.cpp:3377-3379
   // FIXME: This is not quite correct recovery as we don't transform SS
   // into the corresponding dependent form (and we don't diagnose missing
   // 'template' keywords within SS as a result).

Rakete wrote:
> rsmith wrote:
> > Rakete wrote:
> > > Rakete wrote:
> > > > rsmith wrote:
> > > > > This FIXME is concerning. Is this a problem with this patch? (Is the 
> > > > > FIXME wrong now?)
> > > > Yes you're right, I believe it not longer applies due to the change in 
> > > > ParseDecl.cpp in ParseDeclarationSpecifiers.
> > > Although I'm not that sure I fully understand what that comments alludes 
> > > to.
> > The example would be something like this:
> > 
> > ```
> > template struct X {
> >   template struct Y { Y(); using V = int; };
> >   template typename Y::V f();
> > };
> > template template
> > X::Y::V X::f() {} 
> > ```
> > 
> > Clang trunk today points out that the `typename` keyword is missing on the 
> > final line, but fails to point out that the `template` keyword is also 
> > missing. The reason is that in the case where that construct is valid:
> > 
> > ```
> > template template
> > X::Y::Y() {}
> > ```
> > 
> > ... we are "entering the context" of the //nested-name-specifier//, which 
> > means we don't need a `template` keyword.
> > 
> > If the FIXME is fixed, then we should diagnose the missing `template` in 
> > the above program.
> > 
> > Also, because we don't rebuild the //nested-name-specifier// as a dependent 
> > nested name specifier in this case, we fail to match it against the 
> > declaration in the class, so in my example above, we also produce an 
> > "out-of-line definition does not match" error.
> > 
> > 
> > A closely-related issue can be seen in an example such as:
> > 
> > ```
> > template struct X {
> >   template struct Y { Y(); typedef void V; }; 
> >   template typename Y::V::W f();
> > };
> > template template
> > X::template Y::V::W X::f() { return 0; } 
> > ```
> > 
> > Here, we produce a completely bogus error:
> > 
> > ```
> > :6:13: error: 'X::Y::V' (aka 'void') is not a class, namespace, or 
> > enumeration
> > X::template Y::V::W X::f() { return 0; } 
> > ^
> > ```
> > 
> > ... because we parse this in "entering context" mode and so resolve 
> > `X::Y::V` to the type in the primary template (that is, `void`). 
> > That's wrong: we should defer resolving this name to a type until we know 
> > what `T` and `U` are, or until we know that we're *actually* entering the 
> > context. Specifically, the above program can be extended as follows:
> > 
> > ```
> > template<> template<> struct X::Y {
> >   struct V { using W = int; };
> > };
> > void call(X x) { x.f(); } // OK, f returns int
> > ```
> > 
> > The above program should be accepted by this patch, if the FIXME is indeed 
> > now fixed. Please add it as a testcase :)
> Oh ok, got it thanks. So no, the program is still not accepted in clang, and 
> a pretty dumb side effect of it is that 
> 
> ```
> template struct X {
>   template struct Y { Y(); using V = int; };
>   template typename Y::V f();
> };
> template template
> X::Y::V X::f() {}
> ```
> 
> is accepted without the diagnostic for the missing `template`. :(
Currently looking into this.

It is interesting to note that for the following example in one of the parent 
comments:

```
template struct X {
  template struct Y { Y(); typedef void V; }; 
  template typename Y::V::W f();
};
template template
X::template Y::V::W X::f() { return 0; }
```

GCC doesn't like the fact that the `template` keyword is on the final line if 
compiled with `-pedantic` [0]:

```
:6:16: warning: keyword 'template' not allowed in declarator-id 
[-Wpedantic]
6 | X::template Y::V::W X::f() { return 0; }
  |^~~~
Compiler returned: 0
```

[0]: https://godbolt.org/z/dYddW3ErY


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-15 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 460514.
ayzhao added a comment.

hacky fix for the test CXX/module/module.interface/p2-2.cpp

If anyone has a better idea on how to fix this test, feedback is **very** 
welcome.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-15 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:362
+// allow this as an extension.
+if (AllowImplicitTypename == ImplicitTypenameContext::No &&
+!isClassName && !IsCtorOrDtorName)

ayzhao wrote:
> Status update:
> 
> This line is currently causing 
> [p2-2.cpp](https://github.com/llvm/llvm-project/blob/main/clang/test/CXX/module/module.interface/p2-2.cpp)
>  to fail with the following error:
> 
> ```
> FAIL: Clang :: CXX/module/module.interface/p2-2.cpp (2 of 17555)
>  TEST 'Clang :: CXX/module/module.interface/p2-2.cpp' 
> FAILED 
> Script:
> --
> : 'RUN: at line 3';   /dev/shm/ayzhao_llvm/llvm-project/build/bin/clang -cc1 
> -internal-isystem 
> /dev/shm/ayzhao_llvm/llvm-project/build/lib/clang/16.0.0/include 
> -nostdsysteminc -std=c++20 
> /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
>  -verify
> --
> Exit Code: 1
>  
> Command Output (stderr):
> --
> error: 'error' diagnostics expected but not seen:
>   File 
> /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
>  Line 17: cannot export 'iterator' as it is not at namespace scope
>   File 
> /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
>  Line 35: cannot export 'iterator' as it is not at namespace scope
> error: 'error' diagnostics seen but not expected:
>   File 
> /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
>  Line 17: declaration does not declare anything
>   File 
> /dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
>  Line 35: declaration does not declare anything
> 4 errors generated.
>  
> --
>  
> 
> ```
> 
> A reduced repro is here:
> 
> ```
> export module X;
> 
> export template 
> struct X {
>   struct iterator {
> T node;
>   };
> };
> 
> export template  X::iterator;
> ```
> 
> `Sema::getTypeName(...)` is called from [these 
> lines](https://github.com/llvm/llvm-project/blob/ace05124f5494173ae4769259d49f33d75d6f76b/clang/lib/Parse/ParseDecl.cpp#L3391-L3396),
>  with the result being that `TypeRep` is null in main but not null in this 
> patch.
> 
> I'm still in the process of trying to figure out how to resolve this, but any 
> suggestions/insights would be **very** welcome.
I fixed this with the following diff:

```
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1375431d8998..dacba4d18021 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -362,6 +362,11 @@ ParsedType Sema::getTypeName(const IdentifierInfo , 
SourceLocation NameLoc,
 if (AllowImplicitTypename == ImplicitTypenameContext::No &&
 !isClassName && !IsCtorOrDtorName)
   return nullptr;
+// FIXME: This hack is required in order to make the test
+// CXX/module/module.interface/p2-2.cpp pass. Can we get this working
+// with this method returning a non-null ParsedType?
+if (isa(CurContext))
+  return nullptr;
 bool IsImplicitTypename = !isClassName && !IsCtorOrDtorName;
 if (IsImplicitTypename) {
   SourceLocation QualifiedLoc = SS->getRange().getBegin();
```

It's very hacky, but it works (for now)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-15 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added subscribers: ChuanqiXu, cor3ntin.
cor3ntin added a comment.

Maybe @ChuanqiXu Can help as it seems module related


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-15 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:362
+// allow this as an extension.
+if (AllowImplicitTypename == ImplicitTypenameContext::No &&
+!isClassName && !IsCtorOrDtorName)

Status update:

This line is currently causing 
[p2-2.cpp](https://github.com/llvm/llvm-project/blob/main/clang/test/CXX/module/module.interface/p2-2.cpp)
 to fail with the following error:

```
FAIL: Clang :: CXX/module/module.interface/p2-2.cpp (2 of 17555)
 TEST 'Clang :: CXX/module/module.interface/p2-2.cpp' 
FAILED 
Script:
--
: 'RUN: at line 3';   /dev/shm/ayzhao_llvm/llvm-project/build/bin/clang -cc1 
-internal-isystem 
/dev/shm/ayzhao_llvm/llvm-project/build/lib/clang/16.0.0/include 
-nostdsysteminc -std=c++20 
/dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
 -verify
--
Exit Code: 1
 
Command Output (stderr):
--
error: 'error' diagnostics expected but not seen:
  File 
/dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
 Line 17: cannot export 'iterator' as it is not at namespace scope
  File 
/dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
 Line 35: cannot export 'iterator' as it is not at namespace scope
error: 'error' diagnostics seen but not expected:
  File 
/dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
 Line 17: declaration does not declare anything
  File 
/dev/shm/ayzhao_llvm/llvm-project/clang/test/CXX/module/module.interface/p2-2.cpp
 Line 35: declaration does not declare anything
4 errors generated.
 
--
 

```

A reduced repro is here:

```
export module X;

export template 
struct X {
  struct iterator {
T node;
  };
};

export template  X::iterator;
```

`Sema::getTypeName(...)` is called from [these 
lines](https://github.com/llvm/llvm-project/blob/ace05124f5494173ae4769259d49f33d75d6f76b/clang/lib/Parse/ParseDecl.cpp#L3391-L3396),
 with the result being that `TypeRep` is null in main but not null in this 
patch.

I'm still in the process of trying to figure out how to resolve this, but any 
suggestions/insights would be **very** welcome.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-09 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 459205.
ayzhao added a comment.

Fix typename-specifier-3.cpp test

Things done:

- the warning should also include a check that C++20 is required
- the warning should only show up for precxx17, as %std_cxx17- translates to 
-std=c++2b


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // precxx17-warning{{missing 'typename' prior to dependent type name B::X; implicit 'typename' is a C++20 extension}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-08 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 458930.
ayzhao marked 2 inline comments as done.
ayzhao added a comment.

p5.cpp -> p4.cpp, removed debug statements

haven't yet fully grokked this patch. still looking into fixing test failures 
and PrevLookupResult.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p4.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-08 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked an inline comment as done.
ayzhao added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:4321
+ isCXXDeclarationSpecifier(ITC_Never, TPResult::True) !=
+ TPResult::True) ||
+(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(ITC_Yes))) {

rsmith wrote:
> Rakete wrote:
> > rsmith wrote:
> > > It seems like a wording oversight that we don't assume `typename` in an 
> > > //enum-base//. Probably would be good to raise this on the core reflector.
> > Do you know why this isn't allowed in `operator` ids?
> There's already been discussion of that on the core reflector, and people 
> seem to agree it's an oversight in the wording. If you want to accept that 
> here, I think that's fine, under the assumption that this will be fixed by 
> DR. (If you want to follow the wording-as-moved, that's fine too.)
> It seems like a wording oversight that we don't assume `typename` in an 
> //enum-base//. Probably would be good to raise this on the core reflector.

Marking this as done for now; this patch currently returns an error if 
`typename` is assumed in an //enum-base//.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-08 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 458901.
ayzhao added a comment.

remove obsolete FIXME


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-08 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 458900.
ayzhao added a comment.

Fix failing test in p5.cpp where typename should be required for enum-base

(N.B. due to 
https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7,
 the correct error should now be missing 'typename' rather than forbidden enum 
forward references)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-07 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

Maybe I missed it but I don't see a test that covers temp.res p5 
 e.g.:

  template  void f(int i) {
T::x * i;  // This will be assumed to be the expression
   //   T::x multiplied by i
   // Not a declaration of variable i of 
   //   type pointer to T::x?
  }
  
  struct Foo {
   typedef int x;
  };
  
  struct Bar {
static int const x = 5;
  };
  
  int main() {
f(1);  // OK
f(1);  // error: Foo::x is a type
  }




Comment at: clang/include/clang/Sema/DeclSpec.h:1918
+  /// Lookup result of declarator, if any.
+  std::unique_ptr PrevLookupResult;
+

Why do we need this one shot previous lookup result? I am struggling to see the 
connection between `isDeclaratorFunctionLike(...)` and where we check 
`hasPrevLookupResult(...)` and why it matter.



Comment at: clang/lib/Parse/ParseDecl.cpp:6479
+else if (D.getContext() == DeclaratorContext::Member) {
+  llvm::dbgs() << __FUNCTION__ << ": " << __LINE__ << "\n";
+  AllowImplicitTypename = ImplicitTypenameContext::Yes;

Looks like there are a few of these left over as debugging lines, the should 
removed.



Comment at: clang/lib/Sema/DeclSpec.cpp:1502-1504
+  LookupResult LR = std::move(*PrevLookupResult);
+  PrevLookupResult.reset();
+  return LR;





Comment at: clang/test/CXX/temp/temp.res/p5.cpp:1
+// RUN: %clang_cc1 -std=c++20 -pedantic -verify %s
+

It looks like this is [temp.res p4 
now](https://eel.is/c++draft/temp.res#general-4)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-07 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked an inline comment as done.
ayzhao added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:5100-5101
   bool IsConstructor = false;
-  if (isDeclarationSpecifier())
+  if (isDeclarationSpecifier(ITC_Never))
 IsConstructor = true;
   else if (Tok.is(tok::identifier) ||

rsmith wrote:
> Rakete wrote:
> > rsmith wrote:
> > > Oh, this could be a problem.
> > > 
> > > If this *is* a constructor declaration, then this is implicit typename 
> > > context: this is either a "//parameter-declaration// in a 
> > > //member-declaration//" ([temp.res]/5.2.3) or a 
> > > "//parameter-declaration// in a //declarator// of a function or function 
> > > template declaration whose //declarator-id// is qualified". But if it's 
> > > *not* a constructor declaration, then this is either the 
> > > //declarator-id// of a declaration or the //nested-name-specifier// of a 
> > > pointer-to-member declarator:
> > > 
> > > ```
> > > template
> > > struct C {
> > >   C(T::type); // implicit typename context
> > >   friend C (T::fn)(); // not implicit typename context, declarator-id of 
> > > friend declaration
> > >   C(T::type::*x)[3]; // not implicit typename context, pointer-to-member 
> > > type
> > > };
> > > ```
> > > 
> > > I think we need to use `ITC_Yes` here, in order to correctly disambiguate 
> > > the first example above. Please add tests for the other two cases to make 
> > > sure this doesn't break them -- but I'm worried this **will** break the 
> > > second case, because it will incorrectly annotate `T::fn` as a type.
> > Yeah it does the break the second. Would just checking whether a `friend` 
> > is there be good enough? clang doesn't seem to actively propose to add  a 
> > friend if there's one missing, so if we add a `IsFriend` parameter and then 
> > check if it is set than always return `false`, it should work. Is that 
> > acceptable? It would break the nice error message you get if you write 
> > `friend C(int);`, but if we restrict it when `isDeclarationSpecifier` 
> > return false (with `Never`) would that be better (that's what I'm doing 
> > right now)?
> > 
> > Another solution would be to tentatively parse the whole thing, but that 
> > can be pretty expensive I believe.
> This seems a little fragile against future grammar changes, but I think the 
> `IsFriend` check is correct -- I *think* the only way we can see a 
> //qualified-id// here in a valid non-constructor, non-nested-name-specifier 
> case is in a friend declaration.
I _think_ the first comment in this chain can be marked as done given that the 
test cases are now in `p5.cpp` and Clang compiles them without errors with the 
help of the `IsFriend` check.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-07 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 458580.
ayzhao marked 12 inline comments as done.
ayzhao added a comment.

address code review comments from shafik@


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-07 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

First set of comments.




Comment at: clang/include/clang/Parse/Parser.h:2418
+DS, TemplateInfo, AS, DSC, LateAttrs,
+(ImplicitTypenameContext)isImplicitTypenameContext(DSC));
+  }

Why don't we just have `isImplicitTypenameContext(...)` return an 
`ImplicitTypenameContext`?



Comment at: clang/include/clang/Sema/DeclSpec.h:1809
+enum class ImplicitTypenameContext {
+  Never,
+  Yes,

Since you use `Yes` for the positive option how about `No` for the negative 
option? `Yes`/`Never` feel like an odd pair.



Comment at: clang/lib/Parse/ParseDecl.cpp:3608
   Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) 
&&
-  isConstructorDeclarator(/*Unqualified*/true))
+  isConstructorDeclarator(/*Unqualified*/ true,
+  /*DeductionGuide*/ false,





Comment at: clang/lib/Parse/ParseDecl.cpp:3609
+  isConstructorDeclarator(/*Unqualified*/ true,
+  /*DeductionGuide*/ false,
+  DS.isFriendSpecified()))





Comment at: clang/lib/Parse/ParseDeclCXX.cpp:1248
 if (TemplateId->mightBeType()) {
-  AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/ true);
+  AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Never, 
/*IsClassName*/ true);
 





Comment at: clang/lib/Parse/ParseDeclCXX.cpp:1290
 takeTemplateIdAnnotation(Tok)->mightBeType())
-  AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/ true);
+  AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Never, 
/*IsClassName*/ true);
 





Comment at: clang/lib/Parse/ParseDeclCXX.cpp:1311
   /*WantNontrivialTypeSourceInfo=*/true,
-  /*IsClassTemplateDeductionContext*/ false, );
+  /*IsClassTemplateDeductionContext*/ false, 
ImplicitTypenameContext::Never,);
   if (!Type) {





Comment at: clang/lib/Parse/ParseTentative.cpp:446
+  TPResult R = isCXXDeclarationSpecifier(ImplicitTypenameContext::Never, 
+ /*BracedCastResult*/ TPResult::True,
  );





Comment at: clang/lib/Parse/Parser.cpp:2035
 /*IsCtorOrDtorName=*/false,
-/*NonTrivialTypeSourceInfo*/true,
-/*IsClassTemplateDeductionContext*/true)) {
+/*NonTrivialTypeSourceInfo*/ true,
+/*IsClassTemplateDeductionContext*/ true, AllowImplicitTypename)) {





Comment at: clang/lib/Parse/Parser.cpp:2036
+/*NonTrivialTypeSourceInfo*/ true,
+/*IsClassTemplateDeductionContext*/ true, AllowImplicitTypename)) {
   SourceLocation BeginLoc = Tok.getLocation();





Comment at: clang/lib/Sema/DeclSpec.cpp:27
 #include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Sema/Lookup.h"
 #include "llvm/ADT/STLExtras.h"

Duplicate include.



Comment at: clang/lib/Sema/DeclSpec.cpp:1474
+
+// Declarator::Declarator(const DeclSpec , DeclaratorContext C)
+//   : DS(ds), Range(ds.getSourceRange()), Context(C),

Dead code?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-07 Thread James Y Knight via Phabricator via cfe-commits
jyknight added a comment.

>> Also, do you know if having posted this patch is agreement for licensing 
>> this code? Or do we need to get explicit agreement from the original author 
>> before committing a version of this?
>
> I've never seen that be an issue before, and I don't see enough in 
> https://llvm.org/docs/DeveloperPolicy.html#copyright-license-and-patents to 
> be clear about the answer to that.  @tstellar could perhaps answer.

Contributing the patch to phab was agreement to contribute to llvm under the 
llvm license, you do not need further permission to take over and finish and 
commit a patch from phab. Per the standard apache2 terms in the llvm license, 
"Unless You explicitly state otherwise, any Contribution intentionally 
submitted for inclusion in the Work by You to the Licensor shall be under the 
terms and conditions of this License, without any additional terms or 
conditions."


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-06 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 458329.
ayzhao added a comment.

Update commit with contributions from @royjacobson


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/rounding-math-crash.cpp
  clang/test/SemaCXX/typo-correction.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -28,7 +28,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -193,11 +193,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++20 extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++20 extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++20 extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++20 extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{a type specifier is required}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++20 extension}}
Index: clang/test/SemaCXX/typo-correction.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-09-02 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

In D53847#3745415 , @royjacobson wrote:

> I looked at this a bit about a week ago and got it down to 3-4 tests failing, 
> but I'm not sure how much time I'll have to continue working on it. If one of 
> you wants to take over I'll be happy to send you what I've currently got. 
> @erichkeane @ilya-biryukov
>
> Also, do you know if having posted this patch is agreement for licensing this 
> code? Or do we need to get explicit agreement from the original author before 
> committing a version of this?

I'm currently looking at this patch; please do send me what you have.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-24 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a subscriber: tstellar.
erichkeane added a comment.

In D53847#3745415 , @royjacobson wrote:

> I looked at this a bit about a week ago and got it down to 3-4 tests failing, 
> but I'm not sure how much time I'll have to continue working on it. If one of 
> you wants to take over I'll be happy to send you what I've currently got. 
> @erichkeane @ilya-biryukov
>
> Also, do you know if having posted this patch is agreement for licensing this 
> code? Or do we need to get explicit agreement from the original author before 
> committing a version of this?

I've never seen that be an issue before, and I don't see enough in 
https://llvm.org/docs/DeveloperPolicy.html#copyright-license-and-patents to be 
clear about the answer to that.  @tstellar could perhaps answer.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-24 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

I looked at this a bit about a week ago and got it down to 3-4 tests failing, 
but I'm not sure how much time I'll have to continue working on it. If one of 
you wants to take over I'll be happy to send you what I've currently got. 
@erichkeane @ilya-biryukov

Also, do you know if having posted this patch is agreement for licensing this 
code? Or do we need to get explicit agreement from the original author before 
committing a version of this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-22 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D53847#3735758 , @erichkeane wrote:

> In D53847#3735738 , @ilya-biryukov 
> wrote:
>
>> In D53847#3735704 , @erichkeane 
>> wrote:
>>
>>> Note that this would also let us mark P2324 
>>>  as complete as well.  @ilya-biryukov : 
>>> Since there is no response, I suspect the answer here is someone should 
>>> take this over.  Were you going to?
>>
>> I could, but also busy with other things and happy to give this one away.
>> Would you be interested to take it over instead?
>
> Also very busy with other things, but was sorta looking into closing the 
> partial P2324 .  I haven't dug into this one 
> much in a while, but I was sort of wondering if this is a candidate for being 
> 'split up' into smaller patches/handle 1 case at a time. If i have time next 
> week, I might just start looking into making this work for single-examples, 
> rather than everything.

Welp, spoke too soon, my concepts stuff got reverted again, so I'll be 
workingon that for a while now, so I wont' have time to jump on this today.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-19 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D53847#3735738 , @ilya-biryukov 
wrote:

> In D53847#3735704 , @erichkeane 
> wrote:
>
>> Note that this would also let us mark P2324  
>> as complete as well.  @ilya-biryukov : Since there is no response, I suspect 
>> the answer here is someone should take this over.  Were you going to?
>
> I could, but also busy with other things and happy to give this one away.
> Would you be interested to take it over instead?

Also very busy with other things, but was sorta looking into closing the 
partial P2324 .  I haven't dug into this one 
much in a while, but I was sort of wondering if this is a candidate for being 
'split up' into smaller patches/handle 1 case at a time. If i have time next 
week, I might just start looking into making this work for single-examples, 
rather than everything.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-19 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

In D53847#3735704 , @erichkeane wrote:

> Note that this would also let us mark P2324  
> as complete as well.  @ilya-biryukov : Since there is no response, I suspect 
> the answer here is someone should take this over.  Were you going to?

I could, but also busy with other things and happy to give this one away.
Would you be interested to take it over instead?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-19 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D53847#3706965 , @ilya-biryukov 
wrote:

> Hey! Also wondering what's the status of this.
> @Rakete do you plan to finish the patch? Or would it be ok if someone 
> takes it over?

Note that this would also let us mark P2324  as 
complete as well.  @ilya-biryukov : Since there is no response, I suspect the 
answer here is someone should take this over.  Were you going to?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-08-08 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

Hey! Also wondering what's the status of this.
@Rakete do you plan to finish the patch? Or would it be ok if someone takes 
it over?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-03-02 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.
Herald added a project: All.

In D53847#3252460 , @cjdb wrote:

> What's the status of this patch?

It appears to me that the 'delta' right now is a couple of cases where this 
patch doesn't properly diagnose/warn (see the convo in SemaTemplate.cpp )


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2022-01-18 Thread Christopher Di Bella via Phabricator via cfe-commits
cjdb added a comment.

What's the status of this patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-06-24 Thread Vivek Pandya via Phabricator via cfe-commits
vivekvpandya added a comment.

Minor suggestion, you may want to update http://clang.llvm.org/cxx_status.html 
page for "typename optional in more contexts" with in this change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-27 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete marked an inline comment as done.
Rakete added inline comments.



Comment at: clang/lib/Sema/SemaTemplate.cpp:3377-3379
   // FIXME: This is not quite correct recovery as we don't transform SS
   // into the corresponding dependent form (and we don't diagnose missing
   // 'template' keywords within SS as a result).

rsmith wrote:
> Rakete wrote:
> > Rakete wrote:
> > > rsmith wrote:
> > > > This FIXME is concerning. Is this a problem with this patch? (Is the 
> > > > FIXME wrong now?)
> > > Yes you're right, I believe it not longer applies due to the change in 
> > > ParseDecl.cpp in ParseDeclarationSpecifiers.
> > Although I'm not that sure I fully understand what that comments alludes to.
> The example would be something like this:
> 
> ```
> template struct X {
>   template struct Y { Y(); using V = int; };
>   template typename Y::V f();
> };
> template template
> X::Y::V X::f() {} 
> ```
> 
> Clang trunk today points out that the `typename` keyword is missing on the 
> final line, but fails to point out that the `template` keyword is also 
> missing. The reason is that in the case where that construct is valid:
> 
> ```
> template template
> X::Y::Y() {}
> ```
> 
> ... we are "entering the context" of the //nested-name-specifier//, which 
> means we don't need a `template` keyword.
> 
> If the FIXME is fixed, then we should diagnose the missing `template` in the 
> above program.
> 
> Also, because we don't rebuild the //nested-name-specifier// as a dependent 
> nested name specifier in this case, we fail to match it against the 
> declaration in the class, so in my example above, we also produce an 
> "out-of-line definition does not match" error.
> 
> 
> A closely-related issue can be seen in an example such as:
> 
> ```
> template struct X {
>   template struct Y { Y(); typedef void V; }; 
>   template typename Y::V::W f();
> };
> template template
> X::template Y::V::W X::f() { return 0; } 
> ```
> 
> Here, we produce a completely bogus error:
> 
> ```
> :6:13: error: 'X::Y::V' (aka 'void') is not a class, namespace, or 
> enumeration
> X::template Y::V::W X::f() { return 0; } 
> ^
> ```
> 
> ... because we parse this in "entering context" mode and so resolve 
> `X::Y::V` to the type in the primary template (that is, `void`). That's 
> wrong: we should defer resolving this name to a type until we know what `T` 
> and `U` are, or until we know that we're *actually* entering the context. 
> Specifically, the above program can be extended as follows:
> 
> ```
> template<> template<> struct X::Y {
>   struct V { using W = int; };
> };
> void call(X x) { x.f(); } // OK, f returns int
> ```
> 
> The above program should be accepted by this patch, if the FIXME is indeed 
> now fixed. Please add it as a testcase :)
Oh ok, got it thanks. So no, the program is still not accepted in clang, and a 
pretty dumb side effect of it is that 

```
template struct X {
  template struct Y { Y(); using V = int; };
  template typename Y::V f();
};
template template
X::Y::V X::f() {}
```

is accepted without the diagnostic for the missing `template`. :(


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-22 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith marked 2 inline comments as done.
rsmith added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:4321
+ isCXXDeclarationSpecifier(ITC_Never, TPResult::True) !=
+ TPResult::True) ||
+(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(ITC_Yes))) {

Rakete wrote:
> rsmith wrote:
> > It seems like a wording oversight that we don't assume `typename` in an 
> > //enum-base//. Probably would be good to raise this on the core reflector.
> Do you know why this isn't allowed in `operator` ids?
There's already been discussion of that on the core reflector, and people seem 
to agree it's an oversight in the wording. If you want to accept that here, I 
think that's fine, under the assumption that this will be fixed by DR. (If you 
want to follow the wording-as-moved, that's fine too.)



Comment at: clang/lib/Parse/ParseDecl.cpp:5100-5101
   bool IsConstructor = false;
-  if (isDeclarationSpecifier())
+  if (isDeclarationSpecifier(ITC_Never))
 IsConstructor = true;
   else if (Tok.is(tok::identifier) ||

Rakete wrote:
> rsmith wrote:
> > Oh, this could be a problem.
> > 
> > If this *is* a constructor declaration, then this is implicit typename 
> > context: this is either a "//parameter-declaration// in a 
> > //member-declaration//" ([temp.res]/5.2.3) or a "//parameter-declaration// 
> > in a //declarator// of a function or function template declaration whose 
> > //declarator-id// is qualified". But if it's *not* a constructor 
> > declaration, then this is either the //declarator-id// of a declaration or 
> > the //nested-name-specifier// of a pointer-to-member declarator:
> > 
> > ```
> > template
> > struct C {
> >   C(T::type); // implicit typename context
> >   friend C (T::fn)(); // not implicit typename context, declarator-id of 
> > friend declaration
> >   C(T::type::*x)[3]; // not implicit typename context, pointer-to-member 
> > type
> > };
> > ```
> > 
> > I think we need to use `ITC_Yes` here, in order to correctly disambiguate 
> > the first example above. Please add tests for the other two cases to make 
> > sure this doesn't break them -- but I'm worried this **will** break the 
> > second case, because it will incorrectly annotate `T::fn` as a type.
> Yeah it does the break the second. Would just checking whether a `friend` is 
> there be good enough? clang doesn't seem to actively propose to add  a friend 
> if there's one missing, so if we add a `IsFriend` parameter and then check if 
> it is set than always return `false`, it should work. Is that acceptable? It 
> would break the nice error message you get if you write `friend C(int);`, but 
> if we restrict it when `isDeclarationSpecifier` return false (with `Never`) 
> would that be better (that's what I'm doing right now)?
> 
> Another solution would be to tentatively parse the whole thing, but that can 
> be pretty expensive I believe.
This seems a little fragile against future grammar changes, but I think the 
`IsFriend` check is correct -- I *think* the only way we can see a 
//qualified-id// here in a valid non-constructor, non-nested-name-specifier 
case is in a friend declaration.



Comment at: clang/lib/Sema/SemaTemplate.cpp:3377-3379
   // FIXME: This is not quite correct recovery as we don't transform SS
   // into the corresponding dependent form (and we don't diagnose missing
   // 'template' keywords within SS as a result).

Rakete wrote:
> Rakete wrote:
> > rsmith wrote:
> > > This FIXME is concerning. Is this a problem with this patch? (Is the 
> > > FIXME wrong now?)
> > Yes you're right, I believe it not longer applies due to the change in 
> > ParseDecl.cpp in ParseDeclarationSpecifiers.
> Although I'm not that sure I fully understand what that comments alludes to.
The example would be something like this:

```
template struct X {
  template struct Y { Y(); using V = int; };
  template typename Y::V f();
};
template template
X::Y::V X::f() {} 
```

Clang trunk today points out that the `typename` keyword is missing on the 
final line, but fails to point out that the `template` keyword is also missing. 
The reason is that in the case where that construct is valid:

```
template template
X::Y::Y() {}
```

... we are "entering the context" of the //nested-name-specifier//, which means 
we don't need a `template` keyword.

If the FIXME is fixed, then we should diagnose the missing `template` in the 
above program.

Also, because we don't rebuild the //nested-name-specifier// as a dependent 
nested name specifier in this case, we fail to match it against the declaration 
in the class, so in my example above, we also produce an "out-of-line 
definition does not match" error.


A closely-related issue can be seen in an example such as:

```
template struct X {
  template struct Y { Y(); typedef void V; }; 
  template typename Y::V::W f();
};

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-22 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:4321
+ isCXXDeclarationSpecifier(ITC_Never, TPResult::True) !=
+ TPResult::True) ||
+(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(ITC_Yes))) {

rsmith wrote:
> It seems like a wording oversight that we don't assume `typename` in an 
> //enum-base//. Probably would be good to raise this on the core reflector.
Do you know why this isn't allowed in `operator` ids?



Comment at: clang/lib/Parse/ParseDecl.cpp:5100-5101
   bool IsConstructor = false;
-  if (isDeclarationSpecifier())
+  if (isDeclarationSpecifier(ITC_Never))
 IsConstructor = true;
   else if (Tok.is(tok::identifier) ||

rsmith wrote:
> Oh, this could be a problem.
> 
> If this *is* a constructor declaration, then this is implicit typename 
> context: this is either a "//parameter-declaration// in a 
> //member-declaration//" ([temp.res]/5.2.3) or a "//parameter-declaration// in 
> a //declarator// of a function or function template declaration whose 
> //declarator-id// is qualified". But if it's *not* a constructor declaration, 
> then this is either the //declarator-id// of a declaration or the 
> //nested-name-specifier// of a pointer-to-member declarator:
> 
> ```
> template
> struct C {
>   C(T::type); // implicit typename context
>   friend C (T::fn)(); // not implicit typename context, declarator-id of 
> friend declaration
>   C(T::type::*x)[3]; // not implicit typename context, pointer-to-member type
> };
> ```
> 
> I think we need to use `ITC_Yes` here, in order to correctly disambiguate the 
> first example above. Please add tests for the other two cases to make sure 
> this doesn't break them -- but I'm worried this **will** break the second 
> case, because it will incorrectly annotate `T::fn` as a type.
Yeah it does the break the second. Would just checking whether a `friend` is 
there be good enough? clang doesn't seem to actively propose to add  a friend 
if there's one missing, so if we add a `IsFriend` parameter and then check if 
it is set than always return `false`, it should work. Is that acceptable? It 
would break the nice error message you get if you write `friend C(int);`, but 
if we restrict it when `isDeclarationSpecifier` return false (with `Never`) 
would that be better (that's what I'm doing right now)?

Another solution would be to tentatively parse the whole thing, but that can be 
pretty expensive I believe.



Comment at: clang/lib/Sema/SemaTemplate.cpp:3377-3379
   // FIXME: This is not quite correct recovery as we don't transform SS
   // into the corresponding dependent form (and we don't diagnose missing
   // 'template' keywords within SS as a result).

rsmith wrote:
> This FIXME is concerning. Is this a problem with this patch? (Is the FIXME 
> wrong now?)
Yes you're right, I believe it not longer applies due to the change in 
ParseDecl.cpp in ParseDeclarationSpecifiers.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-22 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 200767.
Rakete marked 11 inline comments as done.
Rakete added a comment.

- rebased
- addressed review comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -27,7 +27,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -195,11 +195,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -84,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -116,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: clang/test/SemaCXX/MicrosoftSuper.cpp
===
--- 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-21 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/include/clang/Sema/DeclSpec.h:1753-1758
+// Describes whether the current context is a context where an implicit
+// typename is allowed (C++2a [temp.res]p5]).
+enum ImplicitTypenameContext {
+  ITC_Never,
+  ITC_Yes,
+};

Consider using an `enum class` here.



Comment at: clang/lib/Parse/ParseDecl.cpp:2652-2654
+  // But only if we are not in a function prototype scope.
+  if (getCurScope()->isFunctionPrototypeScope())
+break;

rsmith wrote:
> Can you split out this error recovery improvement and commit it separately 
> before the rest of this work? It doesn't appear to have any dependency on the 
> rest of the change.
Looks like you need to rebase; the change was committed but is still in the 
latest version of this patch.



Comment at: clang/lib/Parse/ParseDecl.cpp:4321
+ isCXXDeclarationSpecifier(ITC_Never, TPResult::True) !=
+ TPResult::True) ||
+(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(ITC_Yes))) {

It seems like a wording oversight that we don't assume `typename` in an 
//enum-base//. Probably would be good to raise this on the core reflector.



Comment at: clang/lib/Parse/ParseDecl.cpp:4322
+ TPResult::True) ||
+(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(ITC_Yes))) {
   // We'll parse this as a bitfield later.

Using a different `ITC` value for non-C++ compilations seems surprising. (It 
should never make any difference outside of C++, but leaves the reader 
wondering why the two are different.) Can we use `ITC_Never` here for 
consistency?



Comment at: clang/lib/Parse/ParseDecl.cpp:5100-5101
   bool IsConstructor = false;
-  if (isDeclarationSpecifier())
+  if (isDeclarationSpecifier(ITC_Never))
 IsConstructor = true;
   else if (Tok.is(tok::identifier) ||

Oh, this could be a problem.

If this *is* a constructor declaration, then this is implicit typename context: 
this is either a "//parameter-declaration// in a //member-declaration//" 
([temp.res]/5.2.3) or a "//parameter-declaration// in a //declarator// of a 
function or function template declaration whose //declarator-id// is 
qualified". But if it's *not* a constructor declaration, then this is either 
the //declarator-id// of a declaration or the //nested-name-specifier// of a 
pointer-to-member declarator:

```
template
struct C {
  C(T::type); // implicit typename context
  friend C (T::fn)(); // not implicit typename context, declarator-id of friend 
declaration
  C(T::type::*x)[3]; // not implicit typename context, pointer-to-member type
};
```

I think we need to use `ITC_Yes` here, in order to correctly disambiguate the 
first example above. Please add tests for the other two cases to make sure this 
doesn't break them -- but I'm worried this **will** break the second case, 
because it will incorrectly annotate `T::fn` as a type.



Comment at: clang/lib/Sema/Sema.cpp:2219
+  
+  D.setPrevLookupResult(llvm::make_unique(std::move(LR)));
+  return Result;

Consider moving the `make_unique` earlier (directly before 
`LookupQualifiedName`) to avoid needing to move the `LookupResult` object into 
different storage here.



Comment at: clang/lib/Sema/SemaTemplate.cpp:3369
 if (!LookupCtx && isDependentScopeSpecifier(SS)) {
-  Diag(SS.getBeginLoc(), diag::err_typename_missing_template)
-<< SS.getScopeRep() << TemplateII->getName();
-  // Recover as if 'typename' were specified.
+  // C++2a relaxes some of those restrictinos in [temp.res]p5.
+  if (getLangOpts().CPlusPlus2a)

Are there any cases where we would call this for which C++20 still requires a 
`typename` keyword? Should this function be passed an `ImplicitTypenameContext`?



Comment at: clang/lib/Sema/SemaTemplate.cpp:3377-3379
   // FIXME: This is not quite correct recovery as we don't transform SS
   // into the corresponding dependent form (and we don't diagnose missing
   // 'template' keywords within SS as a result).

This FIXME is concerning. Is this a problem with this patch? (Is the FIXME 
wrong now?)



Comment at: clang/test/CXX/drs/dr5xx.cpp:485
 namespace dr542 { // dr542: yes
-#if __cplusplus >= 201103L
+#if __cplusplus >= 201103L && __cplusplus <= 201703L
   struct A { A() = delete; int n; };

A comment here explaining that `A` and `B` stop being aggregates in C++20 would 
be nice. (Nicer would be changing the testcase so it still tests the relevant 
rule in C++20 mode, if that's possible...)



Comment at: clang/test/CXX/temp/temp.res/p5.cpp:1
+// RUN: %clang_cc1 -std=c++2a -pedantic -verify %s
+

Please add tests for enum-base and 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-21 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 200440.
Rakete added a comment.

Add support for implicit typenames of the form T::template U


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p3.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/Parser/editor-placeholder-recovery.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/unknown-type-name.cpp
  clang/test/SemaTemplate/alias-templates.cpp
  clang/test/SemaTemplate/typename-specifier-3.cpp

Index: clang/test/SemaTemplate/typename-specifier-3.cpp
===
--- clang/test/SemaTemplate/typename-specifier-3.cpp
+++ clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -27,7 +27,7 @@
   typedef int arg;
 };
 struct C {
-  typedef B::X x; // expected-error {{missing 'typename'}}
+  typedef B::X x; // expected-warning {{missing 'typename'}}
 };
   };
 
Index: clang/test/SemaTemplate/alias-templates.cpp
===
--- clang/test/SemaTemplate/alias-templates.cpp
+++ clang/test/SemaTemplate/alias-templates.cpp
@@ -195,11 +195,10 @@
   struct base {
 template  struct derived;
   };
-  // FIXME: The diagnostics here are terrible.
   template 
-  using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived = base::template derived; // expected-warning {{missing 'typename'}}
   template 
-  using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}}
+  using derived2 = ::PR16904::base::template derived; // expected-warning {{missing 'typename'}}
 }
 
 namespace PR14858 {
Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-21 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete marked an inline comment as done.
Rakete added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:4859
 // recurse to handle whatever we get.
-if (TryAnnotateTypeOrScopeToken())
+if (TryAnnotateTypeOrScopeToken(!getCurScope()->isTemplateParamScope()))
   return true;

rsmith wrote:
> This seems surprising to me; I'd expect to have an implicit `typename` here 
> approximately when not `DisambiguatingWithExpression`. Also basing this off 
> the scope seems wrong, as we can switch into and out of implicit `typename` 
> contexts multiple times within a scope. Eg, in `template T::template U>` we get an implicit `typename` for `T::template U` but 
> not for `T::V` despite them being in the same scope.
> 
> Should the callers of this function be passing in an "implicit `typename`" 
> flag?
Seems like `template >` isn't accepted as a 
context with an implicit typename (for the `T::template`). I'll look into it :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-21 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 200423.
Rakete marked 10 inline comments as done.
Rakete added a comment.

- Addressed review comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/Parser/editor-placeholder-recovery.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/unknown-type-name.cpp

Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: clang/test/SemaCXX/MicrosoftSuper.cpp
===
--- clang/test/SemaCXX/MicrosoftSuper.cpp
+++ clang/test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: clang/test/SemaCXX/MicrosoftExtensions.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:1784
  bool IsClassTemplateDeductionContext = true,
+ bool AllowImplicitTypename = false,
  IdentifierInfo **CorrectedII = nullptr);

It's dangerous to add a `bool` parameter like this, in a long list of `bool` 
parameters with default arguments. Please add an `enum` for 
`AllowImplicitTypename` and use it instead of the boolean flag.



Comment at: clang/lib/Parse/ParseDecl.cpp:2652-2654
+  // But only if we are not in a function prototype scope.
+  if (getCurScope()->isFunctionPrototypeScope())
+break;

Can you split out this error recovery improvement and commit it separately 
before the rest of this work? It doesn't appear to have any dependency on the 
rest of the change.



Comment at: clang/lib/Parse/ParseDecl.cpp:4859
 // recurse to handle whatever we get.
-if (TryAnnotateTypeOrScopeToken())
+if (TryAnnotateTypeOrScopeToken(!getCurScope()->isTemplateParamScope()))
   return true;

This seems surprising to me; I'd expect to have an implicit `typename` here 
approximately when not `DisambiguatingWithExpression`. Also basing this off the 
scope seems wrong, as we can switch into and out of implicit `typename` 
contexts multiple times within a scope. Eg, in `template>` we get an implicit `typename` for `T::template U` but not 
for `T::V` despite them being in the same scope.

Should the callers of this function be passing in an "implicit `typename`" flag?



Comment at: clang/lib/Parse/ParseDecl.cpp:5882
   if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
+bool AllowImplicitTypename = false;
+if (D.getCXXScopeSpec().isSet())

A citation of the relevant wording here would be useful.



Comment at: clang/lib/Parse/ParseDecl.cpp:6444
+
+  bool AllowImplicitTypename;
+  if (D.getContext() == DeclaratorContext::MemberContext ||

Likewise a citation of the relevant rule here would be useful.



Comment at: clang/lib/Parse/ParseTentative.cpp:1280
+  bool AllowImplicitTypename) {
+  const bool NoImplicitTypename = !HasMissingTypename || 
!AllowImplicitTypename;
+

This seems unclear to me.

I think we should be passing `AllowImplicitTypename` directly to 
`TryAnnotate...`, rather than taking `HasMissingTypename` into account -- 
`AllowImplicitTypename` reflects the language rules, whereas 
`HasMissingTypename` is just an error recovery tool, so `HasMissingTypename` 
should not have any influence on how we annotate the token stream unless we 
actually detect an error.



Comment at: clang/lib/Parse/ParseTentative.cpp:1342
 // We annotated this token as something. Recurse to handle whatever we got.
 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
   }

These recursive steps need to pass in the `AllowImplicitTypename` flag. Maybe 
the default argument should be removed for safety.



Comment at: clang/lib/Parse/Parser.cpp:1490
 Parser::AnnotatedNameKind
 Parser::TryAnnotateName(bool IsAddressOfOperand,
 std::unique_ptr CCC) {

Have you checked that this is never called in an implicit typename context?

Please update the documentation for this to say that it can never be called in 
such a context, or add an `AllowImplicitTypename` parameter as necessary.



Comment at: clang/lib/Sema/SemaTemplate.cpp:9503
+  QualType T = CheckTypenameType(
+  TypenameLoc.isValid() || IsImplicitTypename ? ETK_Typename : ETK_None,
+  TypenameLoc, QualifierLoc, II, IdLoc);

Please parenthesize the left-hand-side of this ternary operator.



Comment at: clang/test/CXX/drs/dr1xx.cpp:61
 struct B { typedef int X; };
-B::X x; // expected-error {{missing 'typename'}}
+B::X x; // expected-error {{implicit 'typename' is a C++2a extension}}
 struct C : B { X x; }; // expected-error {{unknown type name}}

For each of these `test/CXX/drs` tests that you change, please add a C++20 
`RUN:` line and update the diagnostic expectations to match in pre- and 
post-C++20 mode as applicable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-05-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 198139.
Rakete added a comment.

Don't leak memory and friendly ping :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/Parser/editor-placeholder-recovery.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/unknown-type-name.cpp

Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: clang/test/SemaCXX/MicrosoftSuper.cpp
===
--- clang/test/SemaCXX/MicrosoftSuper.cpp
+++ clang/test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: clang/test/SemaCXX/MicrosoftExtensions.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-03-10 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 190013.
Rakete added a comment.

Don't relookup the qualified-id and use the cached one instead if possible.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/Parser/editor-placeholder-recovery.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/unknown-type-name.cpp

Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: clang/test/SemaCXX/MicrosoftSuper.cpp
===
--- clang/test/SemaCXX/MicrosoftSuper.cpp
+++ clang/test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: clang/test/SemaCXX/MicrosoftExtensions.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-03-10 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete added a comment.

rsmith:

> Some thoughts on this:
> 
> - Can this be unified with the lookup code in HandleDeclarator? This is 
> really the same lookup, repeated in two places.

What I wrote:

> I don't think so, because HandleDeclarator is called after having already 
> parsed the function declaration. I cached it now, but the cleanest solution 
> that I could think of is to use new. Is this appropriate? Or do you have an 
> alternative suggestion?

Maybe a `llvm::Optional` is more appropriate?

> - It'd be nice to cache this lookup, rather than performing it three times 
> (once when disambiguating a parenthesized initializer from a function 
> declaration, once when we're about to parse a parameter-declaration-clause, 
> and once in HandleDeclarator after parsing completes -- though at least 
> that's reduced to two lookups if you make the change I suggested in 
> ParseParameterDeclarationClause)

Hmm let me see what I can do about that.

> - If we don't do the caching, what happens if lookup fails due to ambiguity? 
> Do we get the same error multiple times (once for each time we perform the 
> lookup)?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2019-03-10 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 190012.
Rakete added a comment.
Herald added a subscriber: jdoerfert.
Herald added a project: clang.

Fix a bug where `T::value` inside a functional cast in a template argument 
would be interpreted as a function type.

Also added the missing test file that got lost in a previous revision for some 
reason. :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/drs/dr1xx.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/drs/dr4xx.cpp
  clang/test/CXX/drs/dr5xx.cpp
  clang/test/CXX/temp/temp.res/p5.cpp
  clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  clang/test/FixIt/fixit.cpp
  clang/test/Parser/cxx-member-initializers.cpp
  clang/test/Parser/editor-placeholder-recovery.cpp
  clang/test/SemaCXX/MicrosoftCompatibility.cpp
  clang/test/SemaCXX/MicrosoftExtensions.cpp
  clang/test/SemaCXX/MicrosoftSuper.cpp
  clang/test/SemaCXX/unknown-type-name.cpp

Index: clang/test/SemaCXX/unknown-type-name.cpp
===
--- clang/test/SemaCXX/unknown-type-name.cpp
+++ clang/test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: clang/test/SemaCXX/MicrosoftSuper.cpp
===
--- clang/test/SemaCXX/MicrosoftSuper.cpp
+++ clang/test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-12-14 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 178289.
Rakete added a comment.

@rsmith do you have any more comments?

ping/rebase.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/DeclSpec.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/Parser/cxx-member-initializers.cpp
  test/Parser/editor-placeholder-recovery.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: test/SemaCXX/MicrosoftExtensions.cpp
===
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -526,7 +526,7 @@
 
 namespace PR32750 {
 template struct A {};
-template struct B : A> { A::C::D d; }; // expected-error {{missing 'typename' 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-12-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 176554.
Rakete added a comment.

Rebase + friendly ping :)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/DeclSpec.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/Parser/cxx-member-initializers.cpp
  test/Parser/editor-placeholder-recovery.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: test/SemaCXX/MicrosoftExtensions.cpp
===
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -526,7 +526,7 @@
 
 namespace PR32750 {
 template struct A {};
-template struct B : A> { A::C::D d; }; // expected-error {{missing 'typename' prior to dependent type 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-27 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 175553.
Rakete added a comment.

Rebase and friendly ping! :)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53847/new/

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/DeclSpec.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/Parser/cxx-member-initializers.cpp
  test/Parser/editor-placeholder-recovery.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: test/SemaCXX/MicrosoftExtensions.cpp
===
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -526,7 +526,7 @@
 
 namespace PR32750 {
 template struct A {};
-template struct B : A> { A::C::D d; }; // expected-error {{missing 'typename' prior to dependent type 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-14 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete added inline comments.



Comment at: include/clang/Parse/Parser.h:2119
   DeclSpecContext DSC = DeclSpecContext::DSC_normal,
-  LateParsedAttrList *LateAttrs = nullptr);
+  LateParsedAttrList *LateAttrs = nullptr) {
+return ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, LateAttrs,

Rakete wrote:
> This overload is unnecessary; I accidentally included it. I'll change it 
> later so that Phab doesn't lose the review comments.
Actually, it's less repetitive if I leave it. So I'll just leave it be.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-14 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete added inline comments.



Comment at: lib/Sema/Sema.cpp:2006-2019
+bool Sema::isDeclaratorFunctionLike(const Declarator ) {
+  assert(D.getCXXScopeSpec().isSet() &&
+ "can only be called for qualified names");
+  LookupResult LR(*this, D.getIdentifier(), D.getBeginLoc(), 
LookupOrdinaryName,
+  ForVisibleRedeclaration);
+  DeclContext *DC = computeDeclContext(D.getCXXScopeSpec());
+  if (!DC)

rsmith wrote:
> Some thoughts on this:
> 
>  * Can this be unified with the lookup code in `HandleDeclarator`? This is 
> really the same lookup, repeated in two places.
>  * It'd be nice to cache this lookup, rather than performing it three times 
> (once when disambiguating a parenthesized initializer from a function 
> declaration, once when we're about to parse a parameter-declaration-clause, 
> and once in `HandleDeclarator` after parsing completes -- though at least 
> that's reduced to two lookups if you make the change I suggested in 
> `ParseParameterDeclarationClause`)
>  * If we don't do the caching, what happens if lookup fails due to ambiguity? 
> Do we get the same error multiple times (once for each time we perform the 
> lookup)?
I don't think so, because `HandleDeclarator` is called after having already 
parsed the function declaration. I cached it now, but the cleanest solution 
that I could think of is to use `new`. Is this appropriate? Or do you have an 
alternative suggestion?


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-14 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 174158.
Rakete marked 11 inline comments as done.
Rakete added a comment.

Addressed review comments :)


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/DeclSpec.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/Parser/cxx-member-initializers.cpp
  test/Parser/editor-placeholder-recovery.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: test/SemaCXX/MicrosoftExtensions.cpp
===
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -526,7 +526,7 @@
 
 namespace PR32750 {
 template struct A {};
-template struct B : A> { A::C::D d; }; // expected-error {{missing 'typename' prior to dependent type name 'A::C::D'}}

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-12 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

Thank you, this is looking really good.




Comment at: include/clang/Parse/Parser.h:2054
+case DeclSpecContext::DSC_template_param:
+case DeclSpecContext::DSC_template_type_arg:
+case DeclSpecContext::DSC_normal:

Rakete wrote:
> rsmith wrote:
> > This doesn't seem right to me. Doesn't this mean that `X` will change 
> > from being a non-type template argument to being a type template argument?
> > 
> > Maybe that's a bug in the wording paper, though, since that context *is* a 
> > /type-id/.
> AFAIK no it won't, but I can't really tell if that's the right behavior or 
> not. This patch doesn't touch the `X` case.
I don't think I agree. `ParseTemplateArgument`, after disambiguation, parses a 
type name in `TemplateArgContext`, which results in a `DeclSpecContext` of 
`DSC_template_type_arg`, which means that we treat the context as an implicit 
typename context.

It looks to me like that will cause us to accept implicit `typename` in cases 
that we can disambiguate as being type template arguments, which would be 
wrong. For example, it looks like `X` would be incorrectly 
accepted: `typename` is required here because this type-id is not an implicit 
typename context.

Perhaps the right way to fix this would be to change 
`Parser::getDeclSpecContextFromDeclaratorContext` to map `TemplateArgContext` 
to a different kind of `DeclSpecContext` than `TemplateTypeArgContext` so that 
we can tell the difference here.



Comment at: lib/Parse/ParseDecl.cpp:6433
 
-ParseDeclarationSpecifiers(DS);
+bool AllowImplicitTypename;
+if (D.getContext() == DeclaratorContext::MemberContext ||

We should determine this up-front rather than computing it once per parameter 
that we parse.



Comment at: lib/Parse/ParseDecl.cpp:6439
+  AllowImplicitTypename =
+  D.getCXXScopeSpec().isSet() && Actions.isDeclaratorFunctionLike(D);
 

I don't think you need to do name lookup here. I think you can use 
`D.isFunctionDeclaratorAFunctionDeclaration()` instead of 
`isDeclaratorFunctionLike(D)` -- because we've already committed to parsing 
this as a function declaration in that case, a qualified function name will 
either redeclare something from its context (in which case implicit typename is 
permitted) or be ill-formed.



Comment at: lib/Parse/Parser.cpp:1518
+if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(
+SS, !WasScopeAnnotation, /*AllowImplicitTypename=*/true))
   return ANK_Error;

What justifies allowing implicit typename here? Don't we need the caller to 
tell us if that's OK?

... actually, perhaps this tentatively-declared identifiers logic should only 
be performed if `SS.isEmpty()` (because a tentatively-declared identifier can 
never be found within a scope named by a nested-name-specifier), at which point 
the value of this flag doesn't matter.



Comment at: lib/Parse/Parser.cpp:1783
+AllowImplicitTypename &&
+getCurScope()->isFunctionPrototypeScope())) {
   SourceLocation BeginLoc = Tok.getLocation();

Do we need this scope check? (It would seem preferable to trust the caller to 
have passed in the right flag value, if we can.)



Comment at: lib/Sema/Sema.cpp:2006-2019
+bool Sema::isDeclaratorFunctionLike(const Declarator ) {
+  assert(D.getCXXScopeSpec().isSet() &&
+ "can only be called for qualified names");
+  LookupResult LR(*this, D.getIdentifier(), D.getBeginLoc(), 
LookupOrdinaryName,
+  ForVisibleRedeclaration);
+  DeclContext *DC = computeDeclContext(D.getCXXScopeSpec());
+  if (!DC)

Some thoughts on this:

 * Can this be unified with the lookup code in `HandleDeclarator`? This is 
really the same lookup, repeated in two places.
 * It'd be nice to cache this lookup, rather than performing it three times 
(once when disambiguating a parenthesized initializer from a function 
declaration, once when we're about to parse a parameter-declaration-clause, and 
once in `HandleDeclarator` after parsing completes -- though at least that's 
reduced to two lookups if you make the change I suggested in 
`ParseParameterDeclarationClause`)
 * If we don't do the caching, what happens if lookup fails due to ambiguity? 
Do we get the same error multiple times (once for each time we perform the 
lookup)?



Comment at: lib/Sema/Sema.cpp:2010
+  LookupResult LR(*this, D.getIdentifier(), D.getBeginLoc(), 
LookupOrdinaryName,
+  ForVisibleRedeclaration);
+  DeclContext *DC = computeDeclContext(D.getCXXScopeSpec());

Should this be `forRedeclarationInCurContext()`?



Comment at: lib/Sema/Sema.cpp:2011
+  ForVisibleRedeclaration);
+  DeclContext *DC = computeDeclContext(D.getCXXScopeSpec());
+  if (!DC)


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-07 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete marked 9 inline comments as done.
Rakete added a comment.

I also found another diagnostic regression:

  template 
  T::type();

The previous error message was something with "nested name specifier does not 
refer to class ...". Now, the T::type part is interpreted as type and so we get 
a "expected unqualified-id" error message.




Comment at: include/clang/Parse/Parser.h:2119
   DeclSpecContext DSC = DeclSpecContext::DSC_normal,
-  LateParsedAttrList *LateAttrs = nullptr);
+  LateParsedAttrList *LateAttrs = nullptr) {
+return ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, LateAttrs,

This overload is unnecessary; I accidentally included it. I'll change it later 
so that Phab doesn't lose the review comments.



Comment at: include/clang/Parse/Parser.h:2054
+case DeclSpecContext::DSC_template_param:
+case DeclSpecContext::DSC_template_type_arg:
+case DeclSpecContext::DSC_normal:

rsmith wrote:
> This doesn't seem right to me. Doesn't this mean that `X` will change 
> from being a non-type template argument to being a type template argument?
> 
> Maybe that's a bug in the wording paper, though, since that context *is* a 
> /type-id/.
AFAIK no it won't, but I can't really tell if that's the right behavior or not. 
This patch doesn't touch the `X` case.



Comment at: test/SemaCXX/unknown-type-name.cpp:121-122
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}

rsmith wrote:
> rsmith wrote:
> > This is a diagnostic quality regression. Perhaps that's an inevitable 
> > consequence of P0634, but we should at least try to do better.
> This is marked "done" but doesn't seem to be done?
Oops, don't know why I did that. I can't figure out a way to fix this. I can 
implement a basic heuristic to detect some very basic cases like this one, but 
I don't think it's worth it.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-07 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 173056.
Rakete added a comment.

Addressed review comments! :)


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/Parser/editor-placeholder-recovery.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -72,9 +72,7 @@
 
 int *p;
 
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-//here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
 
 int f2(undeclared, 0); // expected-error{{undeclared identifier}}
 
@@ -86,11 +84,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +116,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: test/SemaCXX/MicrosoftExtensions.cpp
===
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -526,7 +526,7 @@
 
 namespace PR32750 {
 template struct A {};
-template struct B : A> { A::C::D d; }; // expected-error {{missing 'typename' prior to dependent type name 'A::C::D'}}
+template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++2a extension}}
 }
 
 #else
Index: test/SemaCXX/MicrosoftCompatibility.cpp

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:4462-4463
+  DefaultIgnore;
+def ext_implicit_typename : ExtWarn<"implicit 'typename' is a C++2a 
extension">,
+  InGroup;
 

Please make the start of this diagnostic match the non-extension case:

"missing 'typename' prior to dependent type name %0; implicit 'typename' is a 
C++2a extension"



Comment at: include/clang/Parse/Parser.h:1998
+DSC_condition, // condition declaration context
+DSC_block, // declaration within a block
   };

Maybe `compound_stmt` rather than `block`? The term "block" is unfortunately 
ambgiuous within Clang due to the Apple Blocks extension using the same name 
for something else.

... but see below, I don't think we need this at all.



Comment at: include/clang/Parse/Parser.h:2054
+case DeclSpecContext::DSC_template_param:
+case DeclSpecContext::DSC_template_type_arg:
+case DeclSpecContext::DSC_normal:

This doesn't seem right to me. Doesn't this mean that `X` will change 
from being a non-type template argument to being a type template argument?

Maybe that's a bug in the wording paper, though, since that context *is* a 
/type-id/.



Comment at: include/clang/Parse/Parser.h:2055-2056
+case DeclSpecContext::DSC_template_type_arg:
+case DeclSpecContext::DSC_normal:
+  return true;
+

Please don't enable this for the "normal" case. If there are more special cases 
that need the "implicit typename" treatment, we should explicitly identify them 
rather than making this the default.

Please also get rid of `DSC_block`, because it's then the same as `DSC_normal` 
again.)



Comment at: lib/Parse/ParseDecl.cpp:2677-2705
 Parser::DeclSpecContext
 Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
   if (Context == DeclaratorContext::MemberContext)
 return DeclSpecContext::DSC_class;
   if (Context == DeclaratorContext::FileContext)
 return DeclSpecContext::DSC_top_level;
   if (Context == DeclaratorContext::TemplateParamContext)

Can you convert this into a covering `switch`?



Comment at: lib/Parse/ParseDecl.cpp:5842
+
+if (!IsFunctionDecl && IsAmbiguous) {
+  // We have an ambiguity between a function and a variable:

This is an interesting approach, and it seems like a useful error-recovery 
rule, but I'm not really sure I see how it can work as part of an 
implementation of this paper. We need the "is this a redeclaration of a 
function with a qualified name?" check when we parse the type of a parameter, 
not merely for disambiguation. For example, given

```
template int f(int, T::x);
```

... we should reject, because `typename` is required in the declaration of the 
second parameter, even though we can disambiguate this as a function 
declaration without even looking at those tokens (the `int,` can't be anything 
else).

It seems to me that we should do this lookup (possibly lazily) at some point 
before we parse a /qualified-id/ as a parameter type, and feed that into the 
`getTypeName` call we eventually make for the parameter type. (This should also 
be given as *input* to the disambiguation we do here, so that we can determine 
that `template int f(T::x)` is a variable but `template 
int N::f(T::x)` is a function.)



Comment at: lib/Parse/ParseDecl.cpp:5847-5858
+LookupResult LR(Actions, D.getIdentifier(), D.getBeginLoc(),
+Sema::LookupOrdinaryName,
+Sema::ForVisibleRedeclaration);
+DeclContext *DC = Actions.computeDeclContext(D.getCXXScopeSpec());
+assert(DC && "couldn't find decl context of qualified name");
+Actions.LookupQualifiedName(LR, DC);
+

It's not OK to do this from the parser: you should instead add a function to 
the `Sema` interface to perform the query you want here ("does this name 
declare a function / function template?"), and call that from wherever is 
appropriate in the parser.



Comment at: lib/Parse/ParseTentative.cpp:1794-1797
+// But still mark the declaration as ambiguous, as the tie-breakter is
+// not perfect.
+if (IsAmbiguous)
+  *IsAmbiguous = true;

We should not be setting `InvalidAsDeclaration` to `true` for a 
missing`typename` in a context where `typename` is implied. That way lies chaos.



Comment at: lib/Sema/SemaDecl.cpp:317-320
+// We need to delay this diagnostic for function parameters, because
+// at that point we don't know whether the declarator-id of the
+// function is qualified, which affects the interpretation of
+// a dependent qualified name.

I'm very unhappy with this approach. The proposal is careful 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 172218.
Rakete added a comment.

I'm pretty sure I implemented the rules correctly now :)


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/p5.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,15 +36,15 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
 void f(T::type) { } // expected-error{{missing 'typename'}}
@@ -86,11 +86,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -118,4 +118,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
@@ -127,8 +127,8 @@
   typename __super::XXX a;
   typedef typename __super::XXX b;
 
-  __super::XXX c; // expected-error {{missing 'typename'}}
-  typedef __super::XXX d; // expected-error {{missing 'typename'}}
+  __super::XXX c; // expected-warning {{implicit 'typename' is a C++2a extension}}
+  typedef __super::XXX d; // expected-warning {{implicit 'typename' is a C++2a extension}}
 
   void foo() {
 typename __super::XXX e;
Index: test/SemaCXX/MicrosoftExtensions.cpp
===
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -526,7 +526,7 @@
 
 namespace PR32750 {
 template struct A {};
-template struct B : A> { A::C::D d; }; // expected-error {{missing 'typename' prior to dependent type name 'A::C::D'}}
+template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++2a extension}}
 }
 
 #else
Index: test/SemaCXX/MicrosoftCompatibility.cpp
===
--- test/SemaCXX/MicrosoftCompatibility.cpp
+++ test/SemaCXX/MicrosoftCompatibility.cpp
@@ -199,25 +199,25 @@
typedef B Base2;
typedef A Base3;
 
-   A::TYPE a1; // expected-warning {{missing 'typename' prior to dependent type name}}
-   Base1::TYPE a2; // expected-warning {{missing 'typename' prior to dependent type name}}
+   A::TYPE a1; // 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete added inline comments.



Comment at: test/SemaCXX/unknown-type-name.cpp:50
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a 
extension}}
 

rsmith wrote:
> Rakete wrote:
> > rsmith wrote:
> > > This is wrong.
> > > 
> > > ```
> > > template
> > > X f(T::type);
> > > ```
> > > 
> > > declares a variable template. This would be valid if the name `f` were a 
> > > //qualified-id//, and lookup for `f` found a function template, though.
> > > 
> > > (Same for the next 7 cases.)
> > I agree, but those are definitions, so the next 7 cases and this now are 
> > correct.
> I think you've misunderstood the rule. The rule that I think you're referring 
> to is:
> 
> "A qualified-id is assumed to name a type if it is a decl-specifier of the 
> decl-specifier-seq of a simple-declaration or a function-definition in 
> namespace scope"
> 
> But the decl-specifier-seq is just the type *before* the function name, not 
> the parameter's types. There is no special case for function definitions.
Oh I did! Thanks. Let me update my revision :)


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: test/SemaCXX/unknown-type-name.cpp:50
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a 
extension}}
 

Rakete wrote:
> rsmith wrote:
> > This is wrong.
> > 
> > ```
> > template
> > X f(T::type);
> > ```
> > 
> > declares a variable template. This would be valid if the name `f` were a 
> > //qualified-id//, and lookup for `f` found a function template, though.
> > 
> > (Same for the next 7 cases.)
> I agree, but those are definitions, so the next 7 cases and this now are 
> correct.
I think you've misunderstood the rule. The rule that I think you're referring 
to is:

"A qualified-id is assumed to name a type if it is a decl-specifier of the 
decl-specifier-seq of a simple-declaration or a function-definition in 
namespace scope"

But the decl-specifier-seq is just the type *before* the function name, not the 
parameter's types. There is no special case for function definitions.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 172147.
Rakete marked an inline comment as done.
Rakete added a comment.

Remove spaces to be consistent.


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Scope.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/p5.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,39 +36,39 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning{{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning{{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void g(T::type x) { } // expected-error{{missing 'typename'}}
+void g(T::type x) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type, int) { } // expected-error{{missing 'typename'}}
+void f(T::type, int) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(T::type x, char) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type) { } // expected-error{{missing 'typename'}}
+void f(int, T::type) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(char, T::type x) { } // expected-error{{missing 'typename'}}
+void f(char, T::type x) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type, int) { } // expected-error{{missing 'typename'}}
+void f(int, T::type, int) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(int, T::type x, char) { } // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 int *p;
 
@@ -86,11 +86,11 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning{{implicit 'typename' is a C++2a extension}}
 
 template int h(T::type, int); // expected-error{{missing 'typename'}}
 template int h(T::type x, char); // expected-error{{missing 'typename'}}
@@ -100,7 +100,7 @@
 // expected-warning@-2 {{variable templates are a C++14 extension}}
 #endif
 template int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 'typename'}}
+template int junk3(T::junk) = delete; // expected-warning{{implicit 'typename' is a C++2a extension}}
 #if __cplusplus <= 199711L
 //expected-warning@-2 {{deleted function definitions are a C++11 extension}}
 #endif
@@ -118,4 +118,5 @@
 // FIXME: We know which type specifier should have been specified here. Provide
 //a fix-it to add 'typename A::type'
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}
Index: test/SemaCXX/MicrosoftSuper.cpp
===
--- test/SemaCXX/MicrosoftSuper.cpp
+++ test/SemaCXX/MicrosoftSuper.cpp
@@ -108,8 +108,8 @@
   

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete marked 7 inline comments as done.
Rakete added inline comments.



Comment at: lib/Parse/Parser.cpp:1778
+/*IsClassTemplateDeductionContext*/true,
+/*AllowImplicitTypename*/false)) {
   SourceLocation BeginLoc = Tok.getLocation();

rsmith wrote:
> Don't we need to sometimes allow an implicit typename here for correct 
> disambiguation?
This is done elsewhere now. :)



Comment at: test/SemaCXX/unknown-type-name.cpp:50
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a 
extension}}
 

rsmith wrote:
> This is wrong.
> 
> ```
> template
> X f(T::type);
> ```
> 
> declares a variable template. This would be valid if the name `f` were a 
> //qualified-id//, and lookup for `f` found a function template, though.
> 
> (Same for the next 7 cases.)
I agree, but those are definitions, so the next 7 cases and this now are 
correct.



Comment at: test/SemaCXX/unknown-type-name.cpp:102-103
 #endif
-template int junk2(T::junk) throw(); // expected-error{{missing 
'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 
'typename'}}
+template int junk2(T::junk) throw(); // expected-warning 
{{implicit 'typename' is a C++2a extension}}
+template int junk3(T::junk) = delete; // expected-warning 
{{implicit 'typename' is a C++2a extension}}
 #if __cplusplus <= 199711L

rsmith wrote:
> These two are incorrect.
Only the first one is incorrect (i.e. doesn't have implicit typename). The 
second one does, because it's a function definition.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-11-01 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 172146.
Rakete marked 6 inline comments as done.
Rakete added a comment.

Addressed review comments! :)


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Scope.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTentative.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/p5.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,39 +36,39 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void g(T::type x) { } // expected-error{{missing 'typename'}}
+void g(T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type, int) { } // expected-error{{missing 'typename'}}
+void f(T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type) { } // expected-error{{missing 'typename'}}
+void f(int, T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(char, T::type x) { } // expected-error{{missing 'typename'}}
+void f(char, T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type, int) { } // expected-error{{missing 'typename'}}
+void f(int, T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(int, T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 int *p;
 
@@ -86,26 +86,26 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
 
-template int h(T::type, int); // expected-error{{missing 'typename'}}
-template int h(T::type x, char); // expected-error{{missing 'typename'}}
+template int h(T::type, int); // expected-error {{missing 'typename'}}
+template int h(T::type x, char); // expected-error {{missing 'typename'}}
 
 template int junk1(T::junk);
 #if __cplusplus <= 201103L
 // expected-warning@-2 {{variable templates are a C++14 extension}}
 #endif
-template int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 'typename'}}
+template int junk2(T::junk) throw(); // expected-error {{missing 'typename'}}
+template int junk3(T::junk) = delete; // expected-warning {{implicit 'typename' is a C++2a extension}}
 #if __cplusplus <= 199711L
 //expected-warning@-2 {{deleted function definitions are a C++11 extension}}
 #endif
 
-template int junk4(T::junk j); // expected-error{{missing 'typename'}}
+template int junk4(T::junk j); // expected-error {{missing 'typename'}}
 
 // FIXME: We can tell this was intended to be a function because it does not
 //have a dependent nested 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-10-29 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: test/SemaCXX/unknown-type-name.cpp:1
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify -std=c++98 %s

rsmith wrote:
> Several of the changes in this file look wrong to me.
Specifics below.



Comment at: test/SemaCXX/unknown-type-name.cpp:50
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a 
extension}}
 

This is wrong.

```
template
X f(T::type);
```

declares a variable template. This would be valid if the name `f` were a 
//qualified-id//, and lookup for `f` found a function template, though.

(Same for the next 7 cases.)



Comment at: test/SemaCXX/unknown-type-name.cpp:95-96
 
-template int h(T::type, int); // expected-error{{missing 
'typename'}}
-template int h(T::type x, char); // expected-error{{missing 
'typename'}}
+template int h(T::type, int); // expected-warning {{implicit 
'typename' is a C++2a extension}}
+template int h(T::type x, char); // expected-warning {{implicit 
'typename' is a C++2a extension}}
 

No implicit `typename` for these two (but the previous two are fine).



Comment at: test/SemaCXX/unknown-type-name.cpp:102-103
 #endif
-template int junk2(T::junk) throw(); // expected-error{{missing 
'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 
'typename'}}
+template int junk2(T::junk) throw(); // expected-warning 
{{implicit 'typename' is a C++2a extension}}
+template int junk3(T::junk) = delete; // expected-warning 
{{implicit 'typename' is a C++2a extension}}
 #if __cplusplus <= 199711L

These two are incorrect.



Comment at: test/SemaCXX/unknown-type-name.cpp:108
 
-template int junk4(T::junk j); // expected-error{{missing 
'typename'}}
+template int junk4(T::junk j); // expected-warning {{implicit 
'typename' is a C++2a extension}}
 

This one is incorrect.



Comment at: test/SemaCXX/unknown-type-name.cpp:121-122
 template
-A::g() { } // expected-error{{requires a type specifier}}
+A::g() { } // expected-error{{expected unqualified-id}}
+// expected-warning@-1{{implicit 'typename' is a C++2a extension}}

This is a diagnostic quality regression. Perhaps that's an inevitable 
consequence of P0634, but we should at least try to do better.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-10-29 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/Parse/ParseDecl.cpp:3105
+  isClassTemplateDeductionContext(DSContext),
+  /*AllowImplicitTypename=*/true);
 

This looks overly broad: shouldn't this depend on the DSContext?



Comment at: lib/Parse/Parser.cpp:1778
+/*IsClassTemplateDeductionContext*/true,
+/*AllowImplicitTypename*/false)) {
   SourceLocation BeginLoc = Tok.getLocation();

Don't we need to sometimes allow an implicit typename here for correct 
disambiguation?



Comment at: test/CXX/temp/temp.res/p5.cpp:1
+// RUN: %clang_cc1 -std=c++2a -pedantic -verify %s
+

Negative tests are as important as positive tests; please add as many cases as 
you can think of where this should *not* apply, to make sure it doesn't. Pay 
particular attention to grammar ambiguities that typename resolves.



Comment at: test/CXX/temp/temp.res/p5.cpp:15
+  // it is a qualified name in a type-id-only context (see below), or
+  // [it's smallest enclosing [/new/defining/]-type-id is]:
+  // - a new-type-id

it's -> its



Comment at: test/FixIt/fixit.cpp:214
-  expected-error {{function definition declared 'typedef'}} \
-  expected-error {{missing 'typename' prior to dependent}}
-  return Mystery::get();

Please retain this, and add a FixItHint to the new extension warning so that it 
still works.



Comment at: test/SemaCXX/PR11358.cpp:15
 void test() {
-  Container::iterator i = c.begin(); // expected-error{{missing 
'typename'}}
+  Container::iterator i = c.begin(); // expected-warning{{implicit 
'typename' is a C++2a extension}}
 }

This is a bug. There's no implicit typename in this context. (Likewise later in 
this file.)



Comment at: test/SemaCXX/unknown-type-name.cpp:1
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify -std=c++98 %s

Several of the changes in this file look wrong to me.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-10-29 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 171612.
Rakete added a comment.

Fix easy errors in tests that I missed by adding explicit template 
instantations.


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDecl.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/p5.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/PR11358.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,39 +36,39 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void g(T::type x) { } // expected-error{{missing 'typename'}}
+void g(T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type, int) { } // expected-error{{missing 'typename'}}
+void f(T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type) { } // expected-error{{missing 'typename'}}
+void f(int, T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(char, T::type x) { } // expected-error{{missing 'typename'}}
+void f(char, T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type, int) { } // expected-error{{missing 'typename'}}
+void f(int, T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(int, T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 int *p;
 
@@ -86,26 +86,26 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
 
-template int h(T::type, int); // expected-error{{missing 'typename'}}
-template int h(T::type x, char); // expected-error{{missing 'typename'}}
+template int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template int junk1(T::junk);
 #if __cplusplus <= 201103L
 // expected-warning@-2 {{variable templates are a C++14 extension}}
 #endif
-template int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 'typename'}}
+template int junk2(T::junk) throw(); // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int junk3(T::junk) = delete; // expected-warning {{implicit 'typename' is a C++2a extension}}
 #if __cplusplus <= 199711L
 //expected-warning@-2 {{deleted function definitions are a C++11 extension}}
 #endif
 
-template int junk4(T::junk j); // expected-error{{missing 'typename'}}
+template int junk4(T::junk j); // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 // FIXME: We can tell this was intended to be a function because it does not
 //have a dependent nested name specifier.
@@ -118,4 +118,5 @@
 // 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-10-29 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 171609.
Rakete added a comment.

Remove unneeded -Wc++2a-compat flag in tests.


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDecl.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/p5.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/PR11358.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -36,39 +36,39 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void g(T::type x) { } // expected-error{{missing 'typename'}}
+void g(T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type, int) { } // expected-error{{missing 'typename'}}
+void f(T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type) { } // expected-error{{missing 'typename'}}
+void f(int, T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(char, T::type x) { } // expected-error{{missing 'typename'}}
+void f(char, T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type, int) { } // expected-error{{missing 'typename'}}
+void f(int, T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(int, T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 int *p;
 
@@ -86,26 +86,26 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
 
-template int h(T::type, int); // expected-error{{missing 'typename'}}
-template int h(T::type x, char); // expected-error{{missing 'typename'}}
+template int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template int junk1(T::junk);
 #if __cplusplus <= 201103L
 // expected-warning@-2 {{variable templates are a C++14 extension}}
 #endif
-template int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 'typename'}}
+template int junk2(T::junk) throw(); // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int junk3(T::junk) = delete; // expected-warning {{implicit 'typename' is a C++2a extension}}
 #if __cplusplus <= 199711L
 //expected-warning@-2 {{deleted function definitions are a C++11 extension}}
 #endif
 
-template int junk4(T::junk j); // expected-error{{missing 'typename'}}
+template int junk4(T::junk j); // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 // FIXME: We can tell this was intended to be a function because it does not
 //have a dependent nested name specifier.
@@ -118,4 +118,5 @@
 // FIXME: We know which type specifier 

[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-10-29 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete added inline comments.



Comment at: test/CXX/temp/temp.res/p5.cpp:71
+
+// FIXME: This is ok.
+template 

I think the below is well-formed according to the quote above, but I'm not sure 
I understand it correctly.


Repository:
  rC Clang

https://reviews.llvm.org/D53847



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53847: [C++2a] P0634r3: Down with typename!

2018-10-29 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete created this revision.
Rakete added a reviewer: rsmith.

This patch implements P0634r3 that removes the need for 'typename' in certain 
contexts.

For example,

  template 
  using foo = T::type; // ok

This is also allowed in previous language versions as an extension, because I 
think it's pretty useful. :)


Repository:
  rC Clang

https://reviews.llvm.org/D53847

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/Parser.cpp
  lib/Sema/SemaDecl.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/drs/dr5xx.cpp
  test/CXX/temp/temp.res/p5.cpp
  test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
  test/FixIt/fixit.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp
  test/SemaCXX/MicrosoftExtensions.cpp
  test/SemaCXX/MicrosoftSuper.cpp
  test/SemaCXX/PR11358.cpp
  test/SemaCXX/unknown-type-name.cpp

Index: test/SemaCXX/unknown-type-name.cpp
===
--- test/SemaCXX/unknown-type-name.cpp
+++ test/SemaCXX/unknown-type-name.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -Wc++2a-compat -fsyntax-only -verify -std=c++11 %s
 
 // PR3990
 namespace N {
@@ -36,39 +36,39 @@
 
   static int n;
   static type m;
-  static int h(T::type, int); // expected-error{{missing 'typename'}}
-  static int h(T::type x, char); // expected-error{{missing 'typename'}}
+  static int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+  static int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 };
 
 template
-A::type g(T t) { return t; } // expected-error{{missing 'typename'}}
+A::type g(T t) { return t; } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-A::type A::f() { return type(); } // expected-error{{missing 'typename'}}
+A::type A::f() { return type(); } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type) { } // expected-error{{missing 'typename'}}
+void f(T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void g(T::type x) { } // expected-error{{missing 'typename'}}
+void g(T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type, int) { } // expected-error{{missing 'typename'}}
+void f(T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type) { } // expected-error{{missing 'typename'}}
+void f(int, T::type) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(char, T::type x) { } // expected-error{{missing 'typename'}}
+void f(char, T::type x) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type, int) { } // expected-error{{missing 'typename'}}
+void f(int, T::type, int) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template
-void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
+void f(int, T::type x, char) { } // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 int *p;
 
@@ -86,26 +86,26 @@
 
 template int A::n(T::value); // ok
 template
-A::type // expected-error{{missing 'typename'}}
+A::type // expected-warning {{implicit 'typename' is a C++2a extension}}
 A::m(T::value, 0); // ok
 
-template int A::h(T::type, int) {} // expected-error{{missing 'typename'}}
-template int A::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+template int A::h(T::type, int) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int A::h(T::type x, char) {} // expected-warning {{implicit 'typename' is a C++2a extension}}
 
-template int h(T::type, int); // expected-error{{missing 'typename'}}
-template int h(T::type x, char); // expected-error{{missing 'typename'}}
+template int h(T::type, int); // expected-warning {{implicit 'typename' is a C++2a extension}}
+template int h(T::type x, char); // expected-warning {{implicit 'typename' is a C++2a extension}}
 
 template int junk1(T::junk);
 #if __cplusplus <= 201103L
 // expected-warning@-2 {{variable templates are a C++14 extension}}
 #endif
-template int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
-template int junk3(T::junk) = delete; // expected-error{{missing 'typename'}}
+template int junk2(T::junk) throw(); // expected-warning {{implicit 'typename' is