[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian closed 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-13 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 5de10ae0864dacf5f48daf476a4fa20177545d9b Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  13 +-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseTentative.cpp|   6 +-
 clang/lib/Sema/DeclSpec.cpp   |   9 +-
 clang/lib/Sema/SemaDecl.cpp   |  20 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   8 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  40 +
 clang/test/CXX/drs/dr16xx.cpp |   8 +-
 clang/test/CXX/drs/dr23xx.cpp |  38 -
 .../temp.class/temp.mem.enum/p1.cpp   |   8 +-
 clang/test/FixIt/fixit-c++11.cpp  |   6 +-
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   3 +-
 clang/test/SemaCXX/enum-scoped.cpp|  10 ++
 19 files changed, 185 insertions(+), 146 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc2fb3b25e3a54..e12a802e2e9ede 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -159,6 +159,8 @@ Improvements to Clang's diagnostics
 - The ``-Wshorten-64-to-32`` diagnostic is now grouped under 
``-Wimplicit-int-conversion`` instead
of ``-Wconversion``. Fixes `#69444 
`_.
 
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 754733a6c5fffd..40b47c3ca92e7d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,10 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enum specifier cannot be declared as a friend">,
+  InGroup>;
+def note_enum_friend : Note<
+  "remove 'enum%select{| struct| class}0' to befriend an enum">;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index d161147527dc34..316e8071169a3a 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,10 +346,7 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
+  enum FriendSpecified : bool { No, Yes };
 
 private:
   // storage-class-specifier
@@ -400,7 +397,7 @@ class DeclSpec {
 
   // friend-specifier
   LLVM_PREFERRED_TYPE(bool)
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   LLVM_PREFERRED_TYPE(ConstexprSpecKind)
@@ -491,7 +488,7 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), Friend_specified(false),
+FS_noreturn_specified(false), FriendSpecifiedFirst(false),
 ConstexprSpecifier(
 static_cast(ConstexprSpecKind::Unspecified)),
 Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {}
@@ -818,9 +815,11 @@ class DeclSpec {
 const char *, unsigned );
 
   FriendSpecified isFriendSpecified() const {
-return static_cast(Friend_specified);
+return static_cast(FriendLoc.isValid());
   }
 
+  bool isFriendSpecifiedFirst() const { return FriendSpecifiedFirst; }
+
   SourceLocation getFriendSpecLoc() const { return FriendLoc; }
 
   bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ed933f27f8df6b..978949a9803ac8 100644

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-12 Thread Erich Keane via cfe-commits

https://github.com/erichkeane approved this pull request.


https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-12 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Ping @erichkeane @cor3ntin 

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 921ee093c7366210a8e8587baab6f5d26ae506c3 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  14 +-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseTentative.cpp|   6 +-
 clang/lib/Sema/DeclSpec.cpp   |   9 +-
 clang/lib/Sema/SemaDecl.cpp   |  20 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   8 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  40 +
 clang/test/CXX/drs/dr16xx.cpp |   8 +-
 clang/test/CXX/drs/dr23xx.cpp |  38 -
 .../temp.class/temp.mem.enum/p1.cpp   |   8 +-
 clang/test/FixIt/fixit-c++11.cpp  |   6 +-
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   3 +-
 clang/test/SemaCXX/enum-scoped.cpp|  10 ++
 19 files changed, 186 insertions(+), 146 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 32440ee64e3ebe..65a516dc385d00 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -156,6 +156,8 @@ Improvements to Clang's diagnostics
 - The ``-Wshorten-64-to-32`` diagnostic is now grouped under 
``-Wimplicit-int-conversion`` instead
of ``-Wconversion``. Fixes `#69444 
`_.
 
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..adcdf2425c929d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,10 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enum specifier cannot be declared as a friend">,
+  InGroup>;
+def note_enum_friend : Note<
+  "remove 'enum%select{| struct| class}0' to befriend an enum">;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..3ea08ccf9809f4 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,10 +346,7 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
+  enum FriendSpecified : bool { No, Yes };
 
 private:
   // storage-class-specifier
@@ -380,7 +377,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,7 +468,7 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), Friend_specified(false),
+FS_noreturn_specified(false), FriendSpecifiedFirst(false),
 ConstexprSpecifier(
 static_cast(ConstexprSpecKind::Unspecified)),
 Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {}
@@ -797,9 +795,11 @@ class DeclSpec {
 const char *, unsigned );
 
   FriendSpecified isFriendSpecified() const {
-return static_cast(Friend_specified);
+return static_cast(FriendLoc.isValid());
   }
 
+  bool isFriendSpecifiedFirst() const { return FriendSpecifiedFirst; }
+
   SourceLocation getFriendSpecLoc() const { return FriendLoc; }
 
   bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll approved this pull request.


https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Vlad Serebrennikov via cfe-commits


@@ -17242,6 +17242,23 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
   return true;
   }
 
+  if (TUK == TUK_Friend && Kind == TagTypeKind::Enum) {
+// C++23 [dcl.type.elab]p4:
+//   If an elaborated-type-specifier appears with the friend specifier as
+//   an entire member-declaration, the member-declaration shall have one
+//   of the following forms:
+// friend class-key nested-name-specifier(opt) identifier ;
+// friend class-key simple-template-id ;
+// friend class-key nested-name-specifier template(opt)
+//   simple-template-id ;
+//
+// Since enum is not a class-key, so declarations like "friend enum E;"
+// are ill-formed. Although CWG2363 reaffirms that such declarations are
+// invalid, most implementations accept so we issue a pedantic warning.
+Diag(KWLoc, diag::ext_enum_friend) << FixItHint::CreateRemoval(

Endilll wrote:

I guess I should've left this comment in `fixit-c++11.cpp`.

> I added note_friend_enum in the most recent commit.

This addresses my concern, thank you.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Krystian Stasiowski via cfe-commits


@@ -17242,6 +17242,23 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
   return true;
   }
 
+  if (TUK == TUK_Friend && Kind == TagTypeKind::Enum) {
+// C++23 [dcl.type.elab]p4:
+//   If an elaborated-type-specifier appears with the friend specifier as
+//   an entire member-declaration, the member-declaration shall have one
+//   of the following forms:
+// friend class-key nested-name-specifier(opt) identifier ;
+// friend class-key simple-template-id ;
+// friend class-key nested-name-specifier template(opt)
+//   simple-template-id ;
+//
+// Since enum is not a class-key, so declarations like "friend enum E;"
+// are ill-formed. Although CWG2363 reaffirms that such declarations are
+// invalid, most implementations accept so we issue a pedantic warning.
+Diag(KWLoc, diag::ext_enum_friend) << FixItHint::CreateRemoval(

sdkrystian wrote:

@Endilll I added `note_friend_enum` in the most recent commit.

> Wording we settled with for diagnostic message is not the one. 

Could you elaborate on what you mean by this? The diagnostic now reads:
> elaborated enum specifier cannot be declared as a friend

Which Aaron seemed to be happy with.


https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 6f8851bf21ff0a6bc9b4f2ff39df6bf00f30ee34 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Sema/DeclSpec.h   |  14 +-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseTentative.cpp|   6 +-
 clang/lib/Sema/DeclSpec.cpp   |   9 +-
 clang/lib/Sema/SemaDecl.cpp   |  17 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   7 +-
 clang/test/CXX/drs/dr23xx.cpp |  33 -
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 19 files changed, 154 insertions(+), 144 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e158284aabeab..d06f4ea973a0a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -156,6 +156,8 @@ Improvements to Clang's diagnostics
 - The ``-Wshorten-64-to-32`` diagnostic is now grouped under 
``-Wimplicit-int-conversion`` instead
of ``-Wconversion``. Fixes `#69444 
`_.
 
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63..02cc061cbb319 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enum specifier cannot be declared as a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063..3ea08ccf9809f 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,10 +346,7 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
+  enum FriendSpecified : bool { No, Yes };
 
 private:
   // storage-class-specifier
@@ -380,7 +377,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,7 +468,7 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), Friend_specified(false),
+FS_noreturn_specified(false), FriendSpecifiedFirst(false),
 ConstexprSpecifier(
 static_cast(ConstexprSpecKind::Unspecified)),
 Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {}
@@ -797,9 +795,11 @@ class DeclSpec {
 const char *, unsigned );
 
   FriendSpecified isFriendSpecified() const {
-return static_cast(Friend_specified);
+return static_cast(FriendLoc.isValid());
   }
 
+  bool isFriendSpecifiedFirst() const { return FriendSpecifiedFirst; }
+
   SourceLocation getFriendSpecLoc() const { return FriendLoc; }
 
   bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 3c26003b5bda7..34fd1eef03779 100644
--- a/clang/include/clang/Sema/Sema.h
+++ 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-08 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 6f8851bf21ff0a6bc9b4f2ff39df6bf00f30ee34 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Sema/DeclSpec.h   |  14 +-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseTentative.cpp|   6 +-
 clang/lib/Sema/DeclSpec.cpp   |   9 +-
 clang/lib/Sema/SemaDecl.cpp   |  17 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   7 +-
 clang/test/CXX/drs/dr23xx.cpp |  33 -
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 19 files changed, 154 insertions(+), 144 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e158284aabeabc..d06f4ea973a0a6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -156,6 +156,8 @@ Improvements to Clang's diagnostics
 - The ``-Wshorten-64-to-32`` diagnostic is now grouped under 
``-Wimplicit-int-conversion`` instead
of ``-Wconversion``. Fixes `#69444 
`_.
 
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..02cc061cbb319a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enum specifier cannot be declared as a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..3ea08ccf9809f4 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,10 +346,7 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
+  enum FriendSpecified : bool { No, Yes };
 
 private:
   // storage-class-specifier
@@ -380,7 +377,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,7 +468,7 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), Friend_specified(false),
+FS_noreturn_specified(false), FriendSpecifiedFirst(false),
 ConstexprSpecifier(
 static_cast(ConstexprSpecKind::Unspecified)),
 Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {}
@@ -797,9 +795,11 @@ class DeclSpec {
 const char *, unsigned );
 
   FriendSpecified isFriendSpecified() const {
-return static_cast(Friend_specified);
+return static_cast(FriendLoc.isValid());
   }
 
+  bool isFriendSpecifiedFirst() const { return FriendSpecifiedFirst; }
+
   SourceLocation getFriendSpecLoc() const { return FriendLoc; }
 
   bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 3c26003b5bda7f..34fd1eef03779a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Vlad Serebrennikov via cfe-commits


@@ -17242,6 +17242,23 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
   return true;
   }
 
+  if (TUK == TUK_Friend && Kind == TagTypeKind::Enum) {
+// C++23 [dcl.type.elab]p4:
+//   If an elaborated-type-specifier appears with the friend specifier as
+//   an entire member-declaration, the member-declaration shall have one
+//   of the following forms:
+// friend class-key nested-name-specifier(opt) identifier ;
+// friend class-key simple-template-id ;
+// friend class-key nested-name-specifier template(opt)
+//   simple-template-id ;
+//
+// Since enum is not a class-key, so declarations like "friend enum E;"
+// are ill-formed. Although CWG2363 reaffirms that such declarations are
+// invalid, most implementations accept so we issue a pedantic warning.
+Diag(KWLoc, diag::ext_enum_friend) << FixItHint::CreateRemoval(

Endilll wrote:

Fixit message should definitely be easily actionable. Wording we settled with 
for diagnostic message is not the one. You can reuse the wording I proposed in 
that discussion (`Omit 'enum' keyword to befriend an enum`), or come up with 
your own. This should be much easier to word anyway.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

Alright, changes applied @Endilll 

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 8e3524f7d4a88a7b868dc3d69bf63a5708db6a1f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/4] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  22 ++-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 clang/test/CXX/drs/dr23xx.cpp |  29 
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 21 files changed, 154 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52a48c750fe55..2c5b570d682ab 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63..8e7959bd5a38d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc9..ab92d4e7e9a2f 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063..f3499edb7c681 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,10 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +468,9 @@ class DeclSpec {
 TypeSpecPipe(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Aaron Ballman via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

AaronBallman wrote:

I'd be okay with that, but I'd say `cannot be declared as a friend` just so it 
reads slightly better.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

Added a fixit. Since everyone seems to be learning towards "elaborated enum 
specifier", would everyone be happy with "elaborated enum specifier cannot be 
declared as friend"?

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 8e3524f7d4a88a7b868dc3d69bf63a5708db6a1f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/3] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  22 ++-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 clang/test/CXX/drs/dr23xx.cpp |  29 
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 21 files changed, 154 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52a48c750fe55b..2c5b570d682abe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..8e7959bd5a38d7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc92..ab92d4e7e9a2ff 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..f3499edb7c6813 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,10 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +468,9 @@ class DeclSpec {
 TypeSpecPipe(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 8e3524f7d4a88a7b868dc3d69bf63a5708db6a1f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/3] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  22 ++-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 clang/test/CXX/drs/dr23xx.cpp |  29 
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 21 files changed, 154 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52a48c750fe55b..2c5b570d682abe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..8e7959bd5a38d7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc92..ab92d4e7e9a2ff 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..f3499edb7c6813 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,10 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +468,9 @@ class DeclSpec {
 TypeSpecPipe(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

> > ISO C++ does not permits this declaration to be declared as friend because 
> > 'enum E' is an elaborated enum specifier.
> 
> There. Something along these lines

Not a huge fan of this phrasing. The wording of the diagnostic should already 
imply that such a declaration is invalid. Moreover:
- "elaborated enum specifier" isn't any "more correct" than "elaborated enum 
type"
- "declaration to be declared" is a bit redundant
- the phrasing implies that the declaration might be well-formed when written 
without `friend` (which it isn't).

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Aaron Ballman via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

AaronBallman wrote:

I'd go with: 

`friend declaration of %0 with an elaborated specifier is not allowed in ISO 
C++`

and I agree that a fix-it to remove the `enum` keyword would be great if we can 
do it (not all users are going to know what an "elaborated specifier" is, so 
the fix-it gives a bit of context to the diagnostic).

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

Another alternative: "friend declared using elaborated type specifier must be a 
class"

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

cor3ntin wrote:

> ISO C++ does not permits this declaration to be declared as friend because 
> 'enum E' is an elaborated enum specifier.

There. Something along these lines

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Vlad Serebrennikov via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

Endilll wrote:

I pinged @AaronBallman offline. He promised to take a look at this.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Vlad Serebrennikov via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

Endilll wrote:

I can't say I particularly like any of the three ideas suggested:
> A friend enumeration type cannot be declared using an elaborated type 
> specifier
> An elaborated type specifier starting with 'enum' cannot be declared as a 
> friend

I find both not too actionable for people out of the loop on the Standard. 
Among those two options, I prefer the latter.

> ISO C++ does not permits this declaration to be declared as friend because 
> 'enum E' is an elaborated specifier.

This is somewhat better, but isn't there an implication that elaborated type 
specifiers are not permitted in friend declarations?

> should we leave the current wording for the time being?

Sorry, I don't find the current wording `elaborated enumeration type cannot be 
a friend` acceptable.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

cor3ntin wrote:

> ISO C++ does not permits this declaration to be declared as friend because 
> 'enum E' is an elaborated specifier.

Bonus point for a fix-it removing enum

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 8e3524f7d4a88a7b868dc3d69bf63a5708db6a1f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  22 ++-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 clang/test/CXX/drs/dr23xx.cpp |  29 
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 21 files changed, 154 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52a48c750fe55b..2c5b570d682abe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..8e7959bd5a38d7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc92..ab92d4e7e9a2ff 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..f3499edb7c6813 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,10 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +468,9 @@ class DeclSpec {
 TypeSpecPipe(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

@Endilll I think I will settle for "A friend enumeration type cannot be 
declared using an elaborated type specifier" or "An elaborated type specifier 
starting with 'enum' cannot be declared as a friend". Which do you prefer, or 
should we leave the current wording for the time being?

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From bcb66f80b29e6a330e28955f1e1bfc52f4c7399e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  22 ++-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 clang/test/CXX/drs/dr23xx.cpp |  29 
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 21 files changed, 154 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52a48c750fe55b..2c5b570d682abe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..8e7959bd5a38d7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc92..ab92d4e7e9a2ff 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..f3499edb7c6813 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,10 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +468,9 @@ class DeclSpec {
 TypeSpecPipe(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 7718ac38a0c23597d7d02f0022eb89afe6d1b35f 
cb48321729a52d8883874baa85de48c40b8693cb -- 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp 
clang/include/clang/Parse/Parser.h clang/include/clang/Sema/DeclSpec.h 
clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseTentative.cpp 
clang/lib/Sema/DeclSpec.cpp clang/lib/Sema/SemaDecl.cpp 
clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp 
clang/test/CXX/drs/dr16xx.cpp clang/test/CXX/drs/dr23xx.cpp 
clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp 
clang/test/FixIt/fixit-c++11.cpp clang/test/Parser/cxx-decl.cpp 
clang/test/Parser/cxx0x-decl.cpp clang/test/SemaCXX/cxx98-compat.cpp 
clang/test/SemaCXX/enum-scoped.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 8b8646d121..da18cf88ed 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ private:
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool
-  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = 
DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool isConstructorDeclarator(
+  bool Unqualified, bool DeductionGuide = false,
+  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 8f8f6e2b08..3ea08ccf98 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,10 +346,7 @@ public:
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes
-  };
+  enum FriendSpecified : bool { No, Yes };
 
 private:
   // storage-class-specifier
@@ -471,9 +468,9 @@ public:
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false),
-FriendSpecifiedFirst(false), ConstexprSpecifier(static_cast(
- ConstexprSpecKind::Unspecified)),
+FS_noreturn_specified(false), FriendSpecifiedFirst(false),
+ConstexprSpecifier(
+static_cast(ConstexprSpecKind::Unspecified)),
 Attrs(attrFactory), writtenBS(), ObjCQualifiers(nullptr) {}
 
   // storage-class-specifier
diff --git a/clang/lib/Parse/ParseTentative.cpp 
b/clang/lib/Parse/ParseTentative.cpp
index a4f6498754..47c85030f4 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -79,9 +79,9 @@ bool Parser::isCXXDeclarationStatement(
 getCurScope(), *II, Tok.getLocation(), SS, /*Template=*/nullptr);
 if (Actions.isCurrentClassName(*II, getCurScope(), ) ||
 isDeductionGuide) {
-  if (isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(),
-  isDeductionGuide,
-  
/*IsFriend=*/DeclSpec::FriendSpecified::No))
+  if (isConstructorDeclarator(
+  /*Unqualified=*/SS.isEmpty(), isDeductionGuide,
+  /*IsFriend=*/DeclSpec::FriendSpecified::No))
 return true;
 } else if (SS.isNotEmpty()) {
   // If the scope is not empty, it could alternatively be something 
like

``




https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From bcb66f80b29e6a330e28955f1e1bfc52f4c7399e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  22 ++-
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 clang/test/CXX/drs/dr23xx.cpp |  29 
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 21 files changed, 154 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52a48c750fe55b..2c5b570d682abe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested 
name specifiers.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier in language modes after C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..8e7959bd5a38d7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc92..ab92d4e7e9a2ff 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063d..f3499edb7c6813 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,10 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecified : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +468,9 @@ class DeclSpec {
 TypeSpecPipe(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-07 Thread Krystian Stasiowski via cfe-commits


@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,

sdkrystian wrote:

@erichkeane The rationale behind removing `DeclSpec::FriendSpecified`:
- Writing `DeclSpec::FriendSpecified::Yes/No` is unnecessarily verbose.
- It isn't scalable when `FriendSpecified` is an unscoped enumeration type 
(enumerators would conflict). On the other hand, using a scoped enumeration 
type precludes implicit conversions to `bool`.
- `isConstructorDeclarator` is the only place where it's used, and the existing 
convention is to use `bool` parameters.

Nevertheless, I added a commit which reverts the change.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -252,4 +252,14 @@ namespace dr2397 { // dr2397: 17
 auto (*c)[5] = 
   }
 } // namespace dr2397
+
+// CWG2363 was closed as NAD, but its resolution does affirm that
+// a friend declaration cannot have an opaque-enumm-specifier.
+namespace dr2363 { // dr2363: yes
+struct A {
+  friend enum class E; // since-cxx11-error {{reference to enumeration must 
use 'enum' not 'enum class'}}

Endilll wrote:

Yes

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

@Endilll 
> Would it? I'd expect enumerators to have access to non-public constants.

The enumerators do not get any special access. Per [[class.friend] 
p3](http://eel.is/c++draft/class.friend#3):
> If the type specifier in a friend declaration designates a (possibly 
> cv-qualified) class type, that class is declared as a friend; otherwise, the 
> friend declaration is ignored.



https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

Endilll wrote:

> I don't think a note would be particularly helpful since the friend 
> declaration would be ignored anyways...

Would it? I'd expect enumerators to have access to non-public constants.
Even if doesn't hold, we should leave the opinion of usefulness to more 
opinionated tools like clang-tidy.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

Endilll wrote:

> This isn't quite correct either because enum can follow the friend keyword , 
> e.g.

Ugh, you are right. I think it even defeats your initial suggestions, which 
read `A friend declaration cannot use an elaborated type specifier starting 
with enum`, because it can when befriending a function, as you just showed. I 
guess no way around standardese then: `Elaborated type specifier cannot be used 
to befriend an enumeration. Consider omitting 'enum' keyword`. I'd like the 
wording to be accurate on terminology, yet actionable for users who are not 
well-versed in standardese.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From a39aab07696acfea3e3b78d6ad92c8b771eaf0d2 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/3] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  20 +--
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 20 files changed, 123 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index efd925e990f43..1624ba30dd326 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -145,6 +145,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7638a7e84c3c0..ca0c4509a9eb5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc9..ab92d4e7e9a2f 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063..c7266b66c014d 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +466,9 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -252,4 +252,14 @@ namespace dr2397 { // dr2397: 17
 auto (*c)[5] = 
   }
 } // namespace dr2397
+
+// CWG2363 was closed as NAD, but its resolution does affirm that
+// a friend declaration cannot have an opaque-enumm-specifier.
+namespace dr2363 { // dr2363: yes
+struct A {
+  friend enum class E; // since-cxx11-error {{reference to enumeration must 
use 'enum' not 'enum class'}}

sdkrystian wrote:

@Endilll like so?
```cpp
struct A {
  friend enum class E;
  // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum 
class'}}
  // expected-error@-2 {{elaborated enumeration type cannot be a friend}}
};
```

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:


> What if we skip complicated standardese altogether?
> 
> > 'enum' keyword is not allowed after 'friend' keyword

This isn't quite correct either because `enum` _can_ follow the `friend` 
keyword , e.g. 
```cpp
enum class E;
struct A
{
friend enum E f(); // ok
};
```

> Possibly followed by
> 
> > Omit 'enum' keyword if you intend to befriend an enumeration

I don't think a note would be particularly helpful since the friend declaration 
would be ignored anyways...

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

Endilll wrote:

I think now I see what do you want to achieve. I definitely missed that enums 
can be befriended, just not using elaborated type specifier syntax. Sorry for 
some of the comments I left coming from a wrong perspective.

What if we skip complicated standardese altogether?
> 'enum' keyword is not allowed after `friend` keyword

Possibly followed by
> Omit 'enum' if you intend to befriend an enumeration 

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

sdkrystian wrote:

@Endilll I tried to follow the existing "naming convention" used in other 
diagnostics to strike a balance between being correct & comprehensible for 
users. Removing "elaborated" isn't quite correct because an enumeration type 
_can_ be a friend (e.g. `enum class E; struct A { friend E; };`; such a 
declaration is ignored) -- you just can't declare a friend using an 
elaborated-type-specifier starting with `enum` (i.e. `friend enum E`). 

Here is an alternative if you think changing this is necessary:
> A friend declaration cannot use an elaborated type specifier starting with 
> `enum`



https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -252,4 +252,14 @@ namespace dr2397 { // dr2397: 17
 auto (*c)[5] = 
   }
 } // namespace dr2397
+
+// CWG2363 was closed as NAD, but its resolution does affirm that

Endilll wrote:

I find it totally normal for DR tests to tests NAD issues to affirm the status 
quo. You don't have to put this comment if you don't really want to.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -252,4 +252,14 @@ namespace dr2397 { // dr2397: 17
 auto (*c)[5] = 
   }
 } // namespace dr2397
+
+// CWG2363 was closed as NAD, but its resolution does affirm that
+// a friend declaration cannot have an opaque-enumm-specifier.
+namespace dr2363 { // dr2363: yes
+struct A {
+  friend enum class E; // since-cxx11-error {{reference to enumeration must 
use 'enum' not 'enum class'}}

Endilll wrote:

Can you follow the `// expected-error@-1` style of expected directives, like 
the rest of the file?

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,

Endilll wrote:

I don't think elaborated enumeration type is a thing (although elaborated type 
specifier is). I think the simplest solution is to remove "elaborated" from 
diagnostic message.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -252,4 +252,14 @@ namespace dr2397 { // dr2397: 17
 auto (*c)[5] = 
   }
 } // namespace dr2397
+
+// CWG2363 was closed as NAD, but its resolution does affirm that
+// a friend declaration cannot have an opaque-enumm-specifier.
+namespace dr2363 { // dr2363: yes
+struct A {
+  friend enum class E; // since-cxx11-error {{reference to enumeration must 
use 'enum' not 'enum class'}}
+   // expected-error@-1 {{elaborated enumeration type 
cannot be a friend}}
+};

Endilll wrote:

It would be nice to have a test case for unscoped enum with fixed underlying 
type, and also test cases when enum has been already declared by the point 
where it's befriended.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits


@@ -107,6 +107,7 @@ namespace dr1638 { // dr1638: 3.1
   struct B {
 friend enum class A::E;
 // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 
'enum class'}}
+// since-cxx11-error@-2 {{cannot be a friend}}

Endilll wrote:

Can you match the whole diagnostic message, like the rest of the tests in the 
file?

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Erich Keane via cfe-commits


@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;

erichkeane wrote:

I think you're right, thats the one!

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -145,6 +145,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.

sdkrystian wrote:

Yup, will do

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Erich Keane via cfe-commits


@@ -145,6 +145,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.

erichkeane wrote:

Ok, cool, I was a touch confused.  Can you change the wording of the release 
note? 

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;

sdkrystian wrote:

`LLVM_PREFERRED_TYPE` I believe

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits


@@ -145,6 +145,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.

sdkrystian wrote:

Yes :)

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Erich Keane via cfe-commits


@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,

erichkeane wrote:

I'm not a fan of 'bool' parames in general, so I'd prefer that the 
`FriendSpecified` stay in place.

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Erich Keane via cfe-commits


@@ -145,6 +145,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.

erichkeane wrote:

Do you mean, "in language modes after C++98"?

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Erich Keane via cfe-commits


@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;

erichkeane wrote:

Should these have that debug-attribute that we added not long ago?  I think it 
was `Preferred_Type` or something?

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-06 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Ping @Endilll @erichkeane 

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-01 Thread Krystian Stasiowski via cfe-commits


@@ -17534,79 +17534,6 @@ Decl 
*Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
   return Decl;
 }
 
-/// Perform semantic analysis of the given friend type declaration.
-///
-/// \returns A friend declaration that.
-FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation LocStart,

sdkrystian wrote:

@cor3ntin We call `CheckFriendTypeDecl` from two places: 
`Sema::ActOnFriendTypeDecl`, and `TemplateDeclInsantiator::VisitFriendDecl`. 
However, the only thing that `CheckFriendTypeDecl` does during instantiation is 
call `FriendDecl::Create` -- the other checks are only done when initially 
parsing the declaration.  


https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-01 Thread via cfe-commits


@@ -17534,79 +17534,6 @@ Decl 
*Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
   return Decl;
 }
 
-/// Perform semantic analysis of the given friend type declaration.
-///
-/// \returns A friend declaration that.
-FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation LocStart,

cor3ntin wrote:

Why remove the function? 
I think it might be cleaner to add additional parameters to it ( ie, the 
template arguments)

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-01 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@cor3ntin I added a test with a note stating that 
[CWG2363](http://wg21.link/CWG2363) was closed as NAD

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-01 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From a39aab07696acfea3e3b78d6ad92c8b771eaf0d2 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH 1/2] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   1 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  20 +--
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 20 files changed, 123 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index efd925e990f43..1624ba30dd326 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -145,6 +145,7 @@ Improvements to Clang's diagnostics
   prints.
 
 - Clang now diagnoses member template declarations with multiple declarators.
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7638a7e84c3c0..ca0c4509a9eb5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index da18cf88edcc9..ab92d4e7e9a2f 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2552,10 +2552,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063..c7266b66c014d 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +466,9 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-01 Thread via cfe-commits

cor3ntin wrote:

Can you add a test for CWG2363 just showing we have the intended behavior ? (in 
CXX/drs/26xx.cpp)

https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-02-01 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 16931f5be26b689f6142ffa272e07be50b1d35d6 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  20 +--
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 20 files changed, 124 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ec9e3ef07057f..c0b547869ea72 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -144,6 +144,8 @@ Improvements to Clang's diagnostics
 - Clang now applies syntax highlighting to the code snippets it
   prints.
 
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7638a7e84c3c0..ca0c4509a9eb5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 4a066acf511a1..16411e1947ffc 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2551,10 +2551,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063..c7266b66c014d 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +466,9 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-01-31 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/80171
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-01-31 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/80171

>From 62e3b97ac668b7a12331b01cb5e11549d28dd533 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  20 +--
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 20 files changed, 124 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 323157c4db1f1..de474b884b90d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -143,6 +143,8 @@ Improvements to Clang's diagnostics
 - Clang now applies syntax highlighting to the code snippets it
   prints.
 
+- Clang now diagnoses friend declarations with an ``enum`` 
elaborated-type-specifier outside of C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1c0ebbe4e6834..7bb026679f6cd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 4a066acf511a1..16411e1947ffc 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2551,10 +2551,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// Specifies the context in which type-id/expression
   /// disambiguation will occur.
diff --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index 77638def60063..c7266b66c014d 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -346,11 +346,6 @@ class DeclSpec {
 // FIXME: Attributes should be included here.
   };
 
-  enum FriendSpecified : bool {
-No,
-Yes,
-  };
-
 private:
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
@@ -380,7 +375,8 @@ class DeclSpec {
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
-  unsigned Friend_specified : 1;
+  unsigned FriendSpecified : 1;
+  unsigned FriendSpecifiedFirst : 1;
 
   // constexpr-specifier
   unsigned ConstexprSpecifier : 2;
@@ -470,9 +466,9 @@ class DeclSpec {
 TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false),
 TypeQualifiers(TQ_unspecified), FS_inline_specified(false),
 FS_forceinline_specified(false), FS_virtual_specified(false),
-FS_noreturn_specified(false), 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-01-31 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Krystian Stasiowski (sdkrystian)


Changes

According to [[dcl.type.elab]p4](http://eel.is/c++draft/dcl.type.elab#4):
 If an _elaborated-type-specifier_ appears with the `friend` specifier as 
an entire _member-declaration_, the _member-declaration_ shall have one of the 
following forms:
 `friend` _class-key_ _nested-name-specifier_(opt) _identifier_ `;`
 `friend` _class-key_ _simple-template-id_ `;`
 `friend` _class-key_ _nested-name-specifier_ `template`(opt) 
_simple-template-id_ `;`

Notably absent from this list is the `enum` form of an 
_elaborated-type-specifier_ "`enum` _nested-name-specifier_(opt) _identifier_", 
which appears to be intentional per the resolution of 
[CWG2363](http://wg21.link/CWG2363). 

Most major implementations accept these declarations, so the diagnostic is a 
pedantic warning across all C++ versions. 

In addition to the trivial cases previously diagnosed in C++98, we now diagnose 
cases where the _elaborated-type-specifier_ has a dependent 
_nested-name-specifier_:
```cpp
templatetypename T
struct A
{
enum class E;
};

struct B
{
templatetypename T
friend enum AT::E; // pedantic warning: elaborated enumeration type 
cannot be a friend
};

templatetypename T
struct C
{
friend enum T::E;  // pedantic warning: elaborated enumeration type cannot 
be a friend
};
```


---

Patch is 24.44 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/80171.diff


20 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2-4) 
- (modified) clang/include/clang/Parse/Parser.h (+4-4) 
- (modified) clang/include/clang/Sema/DeclSpec.h (+8-12) 
- (modified) clang/include/clang/Sema/Sema.h (-3) 
- (modified) clang/lib/Parse/ParseDecl.cpp (+1-1) 
- (modified) clang/lib/Parse/ParseTentative.cpp (+1-1) 
- (modified) clang/lib/Sema/DeclSpec.cpp (+3-7) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+16) 
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+38-99) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+2-5) 
- (modified) clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp 
(+2-4) 
- (added) clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp (+33) 
- (modified) clang/test/CXX/drs/dr16xx.cpp (+1) 
- (modified) clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp 
(+3-2) 
- (modified) clang/test/FixIt/fixit-c++11.cpp (+1) 
- (modified) clang/test/Parser/cxx-decl.cpp (-3) 
- (modified) clang/test/Parser/cxx0x-decl.cpp (+1-1) 
- (modified) clang/test/SemaCXX/cxx98-compat.cpp (+1-1) 
- (modified) clang/test/SemaCXX/enum-scoped.cpp (+5) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 323157c4db1f1..68987cb179221 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -143,6 +143,8 @@ Improvements to Clang's diagnostics
 - Clang now applies syntax highlighting to the code snippets it
   prints.
 
+- Clang now diagnoses friend declarations with an `enum` 
elaborated-type-specifier outside of C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1c0ebbe4e6834..7bb026679f6cd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 4a066acf511a1..16411e1947ffc 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2551,10 +2551,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false,
+  bool IsFriend = false,
+  const ParsedTemplateInfo *TemplateInfo = nullptr);
 
   /// 

[clang] [Clang][Sema] Diagnose friend declarations with enum elaborated-type-specifier in all language modes (PR #80171)

2024-01-31 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian created 
https://github.com/llvm/llvm-project/pull/80171

According to [[dcl.type.elab]p4](http://eel.is/c++draft/dcl.type.elab#4):
> If an _elaborated-type-specifier_ appears with the `friend` specifier as an 
> entire _member-declaration_, the _member-declaration_ shall have one of the 
> following forms:
> `friend` _class-key_ _nested-name-specifier_(opt) _identifier_ `;`
> `friend` _class-key_ _simple-template-id_ `;`
> `friend` _class-key_ _nested-name-specifier_ `template`(opt) 
> _simple-template-id_ `;`

Notably absent from this list is the `enum` form of an 
_elaborated-type-specifier_ "`enum` _nested-name-specifier_(opt) _identifier_", 
which appears to be intentional per the resolution of 
[CWG2363](http://wg21.link/CWG2363). 

Most major implementations accept these declarations, so the diagnostic is a 
pedantic warning across all C++ versions. 

In addition to the trivial cases previously diagnosed in C++98, we now diagnose 
cases where the _elaborated-type-specifier_ has a dependent 
_nested-name-specifier_:
```cpp
template
struct A
{
enum class E;
};

struct B
{
template
friend enum A::E; // pedantic warning: elaborated enumeration type 
cannot be a friend
};

template
struct C
{
friend enum T::E;  // pedantic warning: elaborated enumeration type cannot 
be a friend
};
```


>From 4328b548228cc9ffa761887afefdb11261b904f7 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 31 Jan 2024 11:09:11 -0500
Subject: [PATCH] [Clang][Sema] Diagnose friend declarations with enum
 elaborated-type-specifier in all language modes

---
 clang/docs/ReleaseNotes.rst   |   2 +
 .../clang/Basic/DiagnosticSemaKinds.td|   6 +-
 clang/include/clang/Parse/Parser.h|   8 +-
 clang/include/clang/Sema/DeclSpec.h   |  20 +--
 clang/include/clang/Sema/Sema.h   |   3 -
 clang/lib/Parse/ParseDecl.cpp |   2 +-
 clang/lib/Parse/ParseTentative.cpp|   2 +-
 clang/lib/Sema/DeclSpec.cpp   |  10 +-
 clang/lib/Sema/SemaDecl.cpp   |  16 ++
 clang/lib/Sema/SemaDeclCXX.cpp| 137 +-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |   7 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p3.cpp|   6 +-
 .../dcl.spec/dcl.type/dcl.type.elab/p4.cpp|  33 +
 clang/test/CXX/drs/dr16xx.cpp |   1 +
 .../temp.class/temp.mem.enum/p1.cpp   |   5 +-
 clang/test/FixIt/fixit-c++11.cpp  |   1 +
 clang/test/Parser/cxx-decl.cpp|   3 -
 clang/test/Parser/cxx0x-decl.cpp  |   2 +-
 clang/test/SemaCXX/cxx98-compat.cpp   |   2 +-
 clang/test/SemaCXX/enum-scoped.cpp|   5 +
 20 files changed, 124 insertions(+), 147 deletions(-)
 create mode 100644 
clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p4.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 323157c4db1f1..68987cb179221 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -143,6 +143,8 @@ Improvements to Clang's diagnostics
 - Clang now applies syntax highlighting to the code snippets it
   prints.
 
+- Clang now diagnoses friend declarations with an `enum` 
elaborated-type-specifier outside of C++98.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1c0ebbe4e6834..7bb026679f6cd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,10 +1637,8 @@ def err_inline_namespace_std : Error<
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
 def ext_enum_friend : ExtWarn<
-  "befriending enumeration type %0 is a C++11 extension">, InGroup;
-def warn_cxx98_compat_enum_friend : Warning<
-  "befriending enumeration type %0 is incompatible with C++98">,
-  InGroup, DefaultIgnore;
+  "elaborated enumeration type cannot be a friend">,
+  InGroup>;
 def ext_nonclass_type_friend : ExtWarn<
   "non-class friend type %0 is a C++11 extension">, InGroup;
 def warn_cxx98_compat_nonclass_type_friend : Warning<
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 4a066acf511a1..16411e1947ffc 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2551,10 +2551,10 @@ class Parser : public CodeCompletionHandler {
   /// Starting with a scope specifier, identifier, or
   /// template-id that refers to the current class, determine whether
   /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-  bool Unqualified, bool DeductionGuide = false,
-  DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-  const ParsedTemplateInfo *TemplateInfo = nullptr);
+  bool
+  isConstructorDeclarator(bool Unqualified, bool