Re: [clang] 45d7080 - PR42694 Support explicit(bool) in older language modes as an extension.

2020-01-17 Thread Hans Wennborg via cfe-commits
Cherry-picked in 0a08d2c4e7830a1b2428c2c77f205ac74fa29899 and
2d2d057ae23036baecb5a2a4a7f929626f46921a. Thanks!

On Fri, Jan 17, 2020 at 3:14 AM Richard Smith  wrote:
>
> Also b78e8e0d79c47a6698a0abc10a37b8a253cb6064 which has an extra test file 
> that I forgot to git add.
>
> On Wed, 15 Jan 2020 at 18:52, Richard Smith  wrote:
>>
>> Hans, could this change be ported to the Clang 10 branch? In PR42694 the 
>> MSVC stdlib developers requested that Clang support this because their 
>> standard library will soon rely on it.
>>
>> On Wed, 15 Jan 2020 at 18:50, Richard Smith via cfe-commits 
>>  wrote:
>>>
>>>
>>> Author: Richard Smith
>>> Date: 2020-01-15T18:38:23-08:00
>>> New Revision: 45d70806f4386adfb62b0d75949a8aad58e0576f
>>>
>>> URL: 
>>> https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f
>>> DIFF: 
>>> https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f.diff
>>>
>>> LOG: PR42694 Support explicit(bool) in older language modes as an extension.
>>>
>>> This needs somewhat careful disambiguation, as C++2a explicit(bool) is a
>>> breaking change. We only enable it in cases where the source construct
>>> could not possibly be anything else.
>>>
>>> Added:
>>>
>>>
>>> Modified:
>>> clang/include/clang/Basic/DiagnosticParseKinds.td
>>> clang/include/clang/Parse/Parser.h
>>> clang/lib/Parse/ParseDecl.cpp
>>> clang/lib/Parse/ParseTentative.cpp
>>> clang/lib/Parse/Parser.cpp
>>> clang/test/SemaCXX/cxx2a-explicit-bool.cpp
>>>
>>> Removed:
>>>
>>>
>>>
>>> 
>>> diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
>>> b/clang/include/clang/Basic/DiagnosticParseKinds.td
>>> index cc6a74ac3e6d..41f788e7d9bd 100644
>>> --- a/clang/include/clang/Basic/DiagnosticParseKinds.td
>>> +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
>>> @@ -33,10 +33,6 @@ def err_asm_goto_cannot_have_output : Error<
>>>
>>>  let CategoryName = "Parse Issue" in {
>>>
>>> -def warn_cxx2a_compat_explicit_bool : Warning<
>>> -  "this expression will be parsed as explicit(bool) in C++2a">,
>>> -  InGroup, DefaultIgnore;
>>> -
>>>  def ext_empty_translation_unit : Extension<
>>>"ISO C requires a translation unit to contain at least one declaration">,
>>>InGroup>;
>>> @@ -684,6 +680,15 @@ def err_ms_property_expected_comma_or_rparen : Error<
>>>  def err_ms_property_initializer : Error<
>>>"property declaration cannot have an in-class initializer">;
>>>
>>> +def warn_cxx2a_compat_explicit_bool : Warning<
>>> +  "this expression will be parsed as explicit(bool) in C++2a">,
>>> +  InGroup, DefaultIgnore;
>>> +def warn_cxx17_compat_explicit_bool : Warning<
>>> +  "explicit(bool) is incompatible with C++ standards before C++2a">,
>>> +  InGroup, DefaultIgnore;
>>> +def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++2a extension">,
>>> +  InGroup;
>>> +
>>>  /// C++ Templates
>>>  def err_expected_template : Error<"expected template">;
>>>  def err_unknown_template_name : Error<
>>>
>>> diff  --git a/clang/include/clang/Parse/Parser.h 
>>> b/clang/include/clang/Parse/Parser.h
>>> index e320c9647818..b7bed4713992 100644
>>> --- a/clang/include/clang/Parse/Parser.h
>>> +++ b/clang/include/clang/Parse/Parser.h
>>> @@ -806,6 +806,16 @@ class Parser : public CodeCompletionHandler {
>>>   bool IsNewScope);
>>>bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
>>>
>>> +  bool MightBeCXXScopeToken() {
>>> +return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
>>> +   (Tok.is(tok::annot_template_id) &&
>>> +NextToken().is(tok::coloncolon)) ||
>>> +   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
>>> +  }
>>> +  bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
>>> +return MightBeCXXScopeToken() && 
>>> TryAnnotateCXXScopeToken(EnteringContext);
>>> +  }
>>> +
>>>  private:
>>>enum AnnotatedNameKind {
>>>  /// Annotation has failed and emitted an error.
>>> @@ -2395,6 +2405,11 @@ class Parser : public CodeCompletionHandler {
>>>/// rather than a less-than expression.
>>>TPResult isTemplateArgumentList(unsigned TokensToSkip);
>>>
>>> +  /// Determine whether an '(' after an 'explicit' keyword is part of a 
>>> C++20
>>> +  /// 'explicit(bool)' declaration, in earlier language modes where that 
>>> is an
>>> +  /// extension.
>>> +  TPResult isExplicitBool();
>>> +
>>>/// Determine whether an identifier has been tentatively declared as a
>>>/// non-type. Such tentative declarations should not be found to name a 
>>> type
>>>/// during a tentative parse, but also should not be annotated as a 
>>> non-type.
>>>
>>> diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
>>> index 69a3ed9cbad7..d8c5a0ab02d3 100644
>>> --- a/clang/lib/Parse/ParseDecl.cpp
>>> +++ 

Re: [clang] 45d7080 - PR42694 Support explicit(bool) in older language modes as an extension.

2020-01-16 Thread Richard Smith via cfe-commits
Also b78e8e0d79c47a6698a0abc10a37b8a253cb6064 which has an extra test file
that I forgot to git add.

On Wed, 15 Jan 2020 at 18:52, Richard Smith  wrote:

> Hans, could this change be ported to the Clang 10 branch? In PR42694 the
> MSVC stdlib developers requested that Clang support this because their
> standard library will soon rely on it.
>
> On Wed, 15 Jan 2020 at 18:50, Richard Smith via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>>
>> Author: Richard Smith
>> Date: 2020-01-15T18:38:23-08:00
>> New Revision: 45d70806f4386adfb62b0d75949a8aad58e0576f
>>
>> URL:
>> https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f
>> DIFF:
>> https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f.diff
>>
>> LOG: PR42694 Support explicit(bool) in older language modes as an
>> extension.
>>
>> This needs somewhat careful disambiguation, as C++2a explicit(bool) is a
>> breaking change. We only enable it in cases where the source construct
>> could not possibly be anything else.
>>
>> Added:
>>
>>
>> Modified:
>> clang/include/clang/Basic/DiagnosticParseKinds.td
>> clang/include/clang/Parse/Parser.h
>> clang/lib/Parse/ParseDecl.cpp
>> clang/lib/Parse/ParseTentative.cpp
>> clang/lib/Parse/Parser.cpp
>> clang/test/SemaCXX/cxx2a-explicit-bool.cpp
>>
>> Removed:
>>
>>
>>
>>
>> 
>> diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td
>> b/clang/include/clang/Basic/DiagnosticParseKinds.td
>> index cc6a74ac3e6d..41f788e7d9bd 100644
>> --- a/clang/include/clang/Basic/DiagnosticParseKinds.td
>> +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
>> @@ -33,10 +33,6 @@ def err_asm_goto_cannot_have_output : Error<
>>
>>  let CategoryName = "Parse Issue" in {
>>
>> -def warn_cxx2a_compat_explicit_bool : Warning<
>> -  "this expression will be parsed as explicit(bool) in C++2a">,
>> -  InGroup, DefaultIgnore;
>> -
>>  def ext_empty_translation_unit : Extension<
>>"ISO C requires a translation unit to contain at least one
>> declaration">,
>>InGroup>;
>> @@ -684,6 +680,15 @@ def err_ms_property_expected_comma_or_rparen : Error<
>>  def err_ms_property_initializer : Error<
>>"property declaration cannot have an in-class initializer">;
>>
>> +def warn_cxx2a_compat_explicit_bool : Warning<
>> +  "this expression will be parsed as explicit(bool) in C++2a">,
>> +  InGroup, DefaultIgnore;
>> +def warn_cxx17_compat_explicit_bool : Warning<
>> +  "explicit(bool) is incompatible with C++ standards before C++2a">,
>> +  InGroup, DefaultIgnore;
>> +def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++2a extension">,
>> +  InGroup;
>> +
>>  /// C++ Templates
>>  def err_expected_template : Error<"expected template">;
>>  def err_unknown_template_name : Error<
>>
>> diff  --git a/clang/include/clang/Parse/Parser.h
>> b/clang/include/clang/Parse/Parser.h
>> index e320c9647818..b7bed4713992 100644
>> --- a/clang/include/clang/Parse/Parser.h
>> +++ b/clang/include/clang/Parse/Parser.h
>> @@ -806,6 +806,16 @@ class Parser : public CodeCompletionHandler {
>>   bool IsNewScope);
>>bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
>>
>> +  bool MightBeCXXScopeToken() {
>> +return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
>> +   (Tok.is(tok::annot_template_id) &&
>> +NextToken().is(tok::coloncolon)) ||
>> +   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
>> +  }
>> +  bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
>> +return MightBeCXXScopeToken() &&
>> TryAnnotateCXXScopeToken(EnteringContext);
>> +  }
>> +
>>  private:
>>enum AnnotatedNameKind {
>>  /// Annotation has failed and emitted an error.
>> @@ -2395,6 +2405,11 @@ class Parser : public CodeCompletionHandler {
>>/// rather than a less-than expression.
>>TPResult isTemplateArgumentList(unsigned TokensToSkip);
>>
>> +  /// Determine whether an '(' after an 'explicit' keyword is part of a
>> C++20
>> +  /// 'explicit(bool)' declaration, in earlier language modes where that
>> is an
>> +  /// extension.
>> +  TPResult isExplicitBool();
>> +
>>/// Determine whether an identifier has been tentatively declared as a
>>/// non-type. Such tentative declarations should not be found to name
>> a type
>>/// during a tentative parse, but also should not be annotated as a
>> non-type.
>>
>> diff  --git a/clang/lib/Parse/ParseDecl.cpp
>> b/clang/lib/Parse/ParseDecl.cpp
>> index 69a3ed9cbad7..d8c5a0ab02d3 100644
>> --- a/clang/lib/Parse/ParseDecl.cpp
>> +++ b/clang/lib/Parse/ParseDecl.cpp
>> @@ -3617,7 +3617,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec
>> ,
>>ConsumedEnd = ExplicitLoc;
>>ConsumeToken(); // kw_explicit
>>if (Tok.is(tok::l_paren)) {
>> -if (getLangOpts().CPlusPlus2a) {
>> +if 

Re: [clang] 45d7080 - PR42694 Support explicit(bool) in older language modes as an extension.

2020-01-15 Thread Richard Smith via cfe-commits
Hans, could this change be ported to the Clang 10 branch? In PR42694 the
MSVC stdlib developers requested that Clang support this because their
standard library will soon rely on it.

On Wed, 15 Jan 2020 at 18:50, Richard Smith via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

>
> Author: Richard Smith
> Date: 2020-01-15T18:38:23-08:00
> New Revision: 45d70806f4386adfb62b0d75949a8aad58e0576f
>
> URL:
> https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f
> DIFF:
> https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f.diff
>
> LOG: PR42694 Support explicit(bool) in older language modes as an
> extension.
>
> This needs somewhat careful disambiguation, as C++2a explicit(bool) is a
> breaking change. We only enable it in cases where the source construct
> could not possibly be anything else.
>
> Added:
>
>
> Modified:
> clang/include/clang/Basic/DiagnosticParseKinds.td
> clang/include/clang/Parse/Parser.h
> clang/lib/Parse/ParseDecl.cpp
> clang/lib/Parse/ParseTentative.cpp
> clang/lib/Parse/Parser.cpp
> clang/test/SemaCXX/cxx2a-explicit-bool.cpp
>
> Removed:
>
>
>
>
> 
> diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td
> b/clang/include/clang/Basic/DiagnosticParseKinds.td
> index cc6a74ac3e6d..41f788e7d9bd 100644
> --- a/clang/include/clang/Basic/DiagnosticParseKinds.td
> +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
> @@ -33,10 +33,6 @@ def err_asm_goto_cannot_have_output : Error<
>
>  let CategoryName = "Parse Issue" in {
>
> -def warn_cxx2a_compat_explicit_bool : Warning<
> -  "this expression will be parsed as explicit(bool) in C++2a">,
> -  InGroup, DefaultIgnore;
> -
>  def ext_empty_translation_unit : Extension<
>"ISO C requires a translation unit to contain at least one
> declaration">,
>InGroup>;
> @@ -684,6 +680,15 @@ def err_ms_property_expected_comma_or_rparen : Error<
>  def err_ms_property_initializer : Error<
>"property declaration cannot have an in-class initializer">;
>
> +def warn_cxx2a_compat_explicit_bool : Warning<
> +  "this expression will be parsed as explicit(bool) in C++2a">,
> +  InGroup, DefaultIgnore;
> +def warn_cxx17_compat_explicit_bool : Warning<
> +  "explicit(bool) is incompatible with C++ standards before C++2a">,
> +  InGroup, DefaultIgnore;
> +def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++2a extension">,
> +  InGroup;
> +
>  /// C++ Templates
>  def err_expected_template : Error<"expected template">;
>  def err_unknown_template_name : Error<
>
> diff  --git a/clang/include/clang/Parse/Parser.h
> b/clang/include/clang/Parse/Parser.h
> index e320c9647818..b7bed4713992 100644
> --- a/clang/include/clang/Parse/Parser.h
> +++ b/clang/include/clang/Parse/Parser.h
> @@ -806,6 +806,16 @@ class Parser : public CodeCompletionHandler {
>   bool IsNewScope);
>bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
>
> +  bool MightBeCXXScopeToken() {
> +return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
> +   (Tok.is(tok::annot_template_id) &&
> +NextToken().is(tok::coloncolon)) ||
> +   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
> +  }
> +  bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
> +return MightBeCXXScopeToken() &&
> TryAnnotateCXXScopeToken(EnteringContext);
> +  }
> +
>  private:
>enum AnnotatedNameKind {
>  /// Annotation has failed and emitted an error.
> @@ -2395,6 +2405,11 @@ class Parser : public CodeCompletionHandler {
>/// rather than a less-than expression.
>TPResult isTemplateArgumentList(unsigned TokensToSkip);
>
> +  /// Determine whether an '(' after an 'explicit' keyword is part of a
> C++20
> +  /// 'explicit(bool)' declaration, in earlier language modes where that
> is an
> +  /// extension.
> +  TPResult isExplicitBool();
> +
>/// Determine whether an identifier has been tentatively declared as a
>/// non-type. Such tentative declarations should not be found to name a
> type
>/// during a tentative parse, but also should not be annotated as a
> non-type.
>
> diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
> index 69a3ed9cbad7..d8c5a0ab02d3 100644
> --- a/clang/lib/Parse/ParseDecl.cpp
> +++ b/clang/lib/Parse/ParseDecl.cpp
> @@ -3617,7 +3617,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec
> ,
>ConsumedEnd = ExplicitLoc;
>ConsumeToken(); // kw_explicit
>if (Tok.is(tok::l_paren)) {
> -if (getLangOpts().CPlusPlus2a) {
> +if (getLangOpts().CPlusPlus2a || isExplicitBool() ==
> TPResult::True) {
> +  Diag(Tok.getLocation(), getLangOpts().CPlusPlus2a
> +  ?
> diag::warn_cxx17_compat_explicit_bool
> +  : diag::ext_explicit_bool);
> +
>  

[clang] 45d7080 - PR42694 Support explicit(bool) in older language modes as an extension.

2020-01-15 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2020-01-15T18:38:23-08:00
New Revision: 45d70806f4386adfb62b0d75949a8aad58e0576f

URL: 
https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f
DIFF: 
https://github.com/llvm/llvm-project/commit/45d70806f4386adfb62b0d75949a8aad58e0576f.diff

LOG: PR42694 Support explicit(bool) in older language modes as an extension.

This needs somewhat careful disambiguation, as C++2a explicit(bool) is a
breaking change. We only enable it in cases where the source construct
could not possibly be anything else.

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseTentative.cpp
clang/lib/Parse/Parser.cpp
clang/test/SemaCXX/cxx2a-explicit-bool.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index cc6a74ac3e6d..41f788e7d9bd 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -33,10 +33,6 @@ def err_asm_goto_cannot_have_output : Error<
 
 let CategoryName = "Parse Issue" in {
 
-def warn_cxx2a_compat_explicit_bool : Warning<
-  "this expression will be parsed as explicit(bool) in C++2a">,
-  InGroup, DefaultIgnore;
-
 def ext_empty_translation_unit : Extension<
   "ISO C requires a translation unit to contain at least one declaration">,
   InGroup>;
@@ -684,6 +680,15 @@ def err_ms_property_expected_comma_or_rparen : Error<
 def err_ms_property_initializer : Error<
   "property declaration cannot have an in-class initializer">;
 
+def warn_cxx2a_compat_explicit_bool : Warning<
+  "this expression will be parsed as explicit(bool) in C++2a">,
+  InGroup, DefaultIgnore;
+def warn_cxx17_compat_explicit_bool : Warning<
+  "explicit(bool) is incompatible with C++ standards before C++2a">,
+  InGroup, DefaultIgnore;
+def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++2a extension">,
+  InGroup;
+
 /// C++ Templates
 def err_expected_template : Error<"expected template">;
 def err_unknown_template_name : Error<

diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index e320c9647818..b7bed4713992 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -806,6 +806,16 @@ class Parser : public CodeCompletionHandler {
  bool IsNewScope);
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
+  bool MightBeCXXScopeToken() {
+return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+   (Tok.is(tok::annot_template_id) &&
+NextToken().is(tok::coloncolon)) ||
+   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+  }
+  bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
+return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
+  }
+
 private:
   enum AnnotatedNameKind {
 /// Annotation has failed and emitted an error.
@@ -2395,6 +2405,11 @@ class Parser : public CodeCompletionHandler {
   /// rather than a less-than expression.
   TPResult isTemplateArgumentList(unsigned TokensToSkip);
 
+  /// Determine whether an '(' after an 'explicit' keyword is part of a C++20
+  /// 'explicit(bool)' declaration, in earlier language modes where that is an
+  /// extension.
+  TPResult isExplicitBool();
+
   /// Determine whether an identifier has been tentatively declared as a
   /// non-type. Such tentative declarations should not be found to name a type
   /// during a tentative parse, but also should not be annotated as a non-type.

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 69a3ed9cbad7..d8c5a0ab02d3 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3617,7 +3617,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec ,
   ConsumedEnd = ExplicitLoc;
   ConsumeToken(); // kw_explicit
   if (Tok.is(tok::l_paren)) {
-if (getLangOpts().CPlusPlus2a) {
+if (getLangOpts().CPlusPlus2a || isExplicitBool() == TPResult::True) {
+  Diag(Tok.getLocation(), getLangOpts().CPlusPlus2a
+  ? diag::warn_cxx17_compat_explicit_bool
+  : diag::ext_explicit_bool);
+
   ExprResult ExplicitExpr(static_cast(nullptr));
   BalancedDelimiterTracker Tracker(*this, tok::l_paren);
   Tracker.consumeOpen();
@@ -3630,8 +3634,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec ,
 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
   } else
 Tracker.skipToEnd();
-} else
+} else {
   Diag(Tok.getLocation(), diag::warn_cxx2a_compat_explicit_bool);
+}
   }