Hi Gauthier,

Your commit seemed to have broken the build on Windows. Can you take a look?

http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/110

494.204 [1215/36/2881] Linking CXX executable bin\clang-query.exe
FAILED: bin/clang-query.exe 
cmd.exe /C "cd . && "C:\Program Files (x86)\CMake\bin\cmake.exe" -E vs_link_exe 
--intdir=tools\clang\tools\extra\clang-query\tool\CMakeFiles\clang-query.dir 
--manifests  -- 
C:\PROGRA~2\MIB055~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe
 /nologo 
tools\clang\tools\extra\clang-query\tool\CMakeFiles\clang-query.dir\ClangQuery.cpp.obj
 
tools\clang\tools\extra\clang-query\tool\CMakeFiles\clang-query.dir\__\__\__\__\__\__\resources\windows_version_resource.rc.res
  /out:bin\clang-query.exe /implib:lib\clang-query.lib /pdb:bin\clang-query.pdb 
/version:0.0  /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console  
lib\LLVMLineEditor.lib lib\LLVMSupport.lib lib\clangAST.lib 
lib\clangASTMatchers.lib lib\clangBasic.lib lib\clangDynamicASTMatchers.lib 
lib\clangFrontend.lib lib\clangQuery.lib lib\clangSerialization.lib 
lib\clangTooling.lib lib\LLVMLineEditor.lib lib\clangDynamicASTMatchers.lib 
lib\clangFrontend.lib lib\clangParse.lib lib\LLVMMCParser.lib 
lib\LLVMProfileData.lib lib\clangSerialization.lib lib\clangSema.lib 
lib\clangEdit.lib lib\clangAnalysis.lib lib\clangASTMatchers.lib 
lib\LLVMBitReader.lib lib\clangDriver.lib version.lib lib\LLVMOption.lib 
lib\clangFormat.lib lib\clangToolingInclusions.lib lib\clangToolingCore.lib 
lib\clangAST.lib lib\clangRewrite.lib lib\clangLex.lib lib\clangBasic.lib 
lib\LLVMCore.lib lib\LLVMRemarks.lib lib\LLVMMC.lib lib\LLVMBinaryFormat.lib 
lib\LLVMDebugInfoCodeView.lib lib\LLVMDebugInfoMSF.lib lib\LLVMSupport.lib 
psapi.lib shell32.lib ole32.lib uuid.lib advapi32.lib delayimp.lib 
-delayload:shell32.dll -delayload:ole32.dll lib\LLVMDemangle.lib kernel32.lib 
user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib 
comdlg32.lib advapi32.lib && cd ."
LINK: command 
"C:\PROGRA~2\MIB055~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe
 /nologo 
tools\clang\tools\extra\clang-query\tool\CMakeFiles\clang-query.dir\ClangQuery.cpp.obj
 
tools\clang\tools\extra\clang-query\tool\CMakeFiles\clang-query.dir\__\__\__\__\__\__\resources\windows_version_resource.rc.res
 /out:bin\clang-query.exe /implib:lib\clang-query.lib /pdb:bin\clang-query.pdb 
/version:0.0 /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console 
lib\LLVMLineEditor.lib lib\LLVMSupport.lib lib\clangAST.lib 
lib\clangASTMatchers.lib lib\clangBasic.lib lib\clangDynamicASTMatchers.lib 
lib\clangFrontend.lib lib\clangQuery.lib lib\clangSerialization.lib 
lib\clangTooling.lib lib\LLVMLineEditor.lib lib\clangDynamicASTMatchers.lib 
lib\clangFrontend.lib lib\clangParse.lib lib\LLVMMCParser.lib 
lib\LLVMProfileData.lib lib\clangSerialization.lib lib\clangSema.lib 
lib\clangEdit.lib lib\clangAnalysis.lib lib\clangASTMatchers.lib 
lib\LLVMBitReader.lib lib\clangDriver.lib version.lib lib\LLVMOption.lib 
lib\clangFormat.lib lib\clangToolingInclusions.lib lib\clangToolingCore.lib 
lib\clangAST.lib lib\clangRewrite.lib lib\clangLex.lib lib\clangBasic.lib 
lib\LLVMCore.lib lib\LLVMRemarks.lib lib\LLVMMC.lib lib\LLVMBinaryFormat.lib 
lib\LLVMDebugInfoCodeView.lib lib\LLVMDebugInfoMSF.lib lib\LLVMSupport.lib 
psapi.lib shell32.lib ole32.lib uuid.lib advapi32.lib delayimp.lib 
-delayload:shell32.dll -delayload:ole32.dll lib\LLVMDemangle.lib kernel32.lib 
user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib 
comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:bin\clang-query.exe.manifest" 
failed (exit code 1120) with the following output:
clangDynamicASTMatchers.lib(Registry.cpp.obj) : error LNK2019: unresolved 
external symbol "class 
clang::ast_matchers::internal::VariadicDynCastAllOfMatcher<class 
clang::Decl,class clang::CXXDeductionGuideDecl> const 
clang::ast_matchers::cxxDeductionGuideDecl" 
(?cxxDeductionGuideDecl@ast_matchers@clang@@3V?$VariadicDynCastAllOfMatcher@VDecl@clang@@VCXXDeductionGuideDecl@2@@internal@12@B)
 referenced in function "public: __cdecl 
clang::ast_matchers::dynamic::`anonymous 
namespace'::RegistryMaps::RegistryMaps(void)" 
(??0RegistryMaps@?A0x914e59e4@dynamic@ast_matchers@clang@@QEAA@XZ)
bin\clang-query.exe : fatal error LNK1120: 1 unresolved externals

Douglas Yung

-----Original Message-----
From: cfe-commits <cfe-commits-boun...@lists.llvm.org> On Behalf Of Gauthier 
Harnisch via cfe-commits
Sent: Wednesday, June 19, 2019 11:28
To: cfe-commits@lists.llvm.org
Subject: r363855 - [clang] Adapt ASTMatcher to explicit(bool) specifier

Author: tyker
Date: Wed Jun 19 11:27:56 2019
New Revision: 363855

URL: http://llvm.org/viewvc/llvm-project?rev=363855&view=rev
Log:
[clang] Adapt ASTMatcher to explicit(bool) specifier

Summary:
Changes:
 - add an ast matcher for deductiong guide.
 - allow isExplicit matcher for deductiong guide.
 - add hasExplicitSpecifier matcher which give access to the expression of the 
explicit specifier if present.

Reviewers: klimek, rsmith, aaron.ballman

Reviewed By: aaron.ballman

Subscribers: aaron.ballman, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61552

Modified:
    cfe/trunk/docs/LibASTMatchersReference.html
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=363855&r1=363854&r2=363855&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Wed Jun 19 11:27:56 2019
@@ -194,6 +194,16 @@ Example matches the operator.
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a 
+href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&
+gt;</td><td class="name" onclick="toggle('cxxDeductionGuideDecl0')"><a 
+name="cxxDeductionGuideDecl0Anchor">cxxDeductionGuideDecl</a></td><td>M
+atcher&lt;<a 
+href="https://clang.llvm.org/doxygen/classclang_1_1CXXDeductionGuideDec
+l.html">CXXDeductionGuideDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="cxxDeductionGuideDecl0"><pre>Matches 
user-defined and implicitly generated deduction guide.
+
+Example matches the deduction guide.
+  template&lt;typename T&gt;
+  class X { X(int) };
+  X(int) -&gt; X&lt;int&gt;;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;</td><td
 class="name" onclick="toggle('cxxDestructorDecl0')"><a 
name="cxxDestructorDecl0Anchor">cxxDestructorDecl</a></td><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1CXXDestructorDecl.html";>CXXDestructorDecl</a>&gt;...</td></tr>
 <tr><td colspan="4" class="doc" id="cxxDestructorDecl0"><pre>Matches explicit 
C++ destructor declarations.
 
@@ -2222,18 +2232,26 @@ cxxConstructorDecl(isDelegatingConstruct
 
 
 <tr><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html";>CXXConstructorDecl</a>&gt;</td><td
 class="name" onclick="toggle('isExplicit0')"><a 
name="isExplicit0Anchor">isExplicit</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches constructor and 
conversion declarations that are marked with -the explicit keyword.
+<tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches 
+constructor, conversion function, and deduction guide declarations that 
+have an explicit specifier if this explicit specifier is resolved to true.
 
 Given
+  template&lt;bool b&gt;
   struct S {
     S(int); // #1
     explicit S(double); // #2
     operator int(); // #3
     explicit operator bool(); // #4
-  };
-cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+    explicit(false) S(bool) // # 7
+    explicit(true) S(char) // # 8
+    explicit(b) S(S) // # 9
+  };
+  S(int) -&gt; S&lt;true&gt; // #5
+  explicit S(double) -&gt; S&lt;false&gt; // #6
+cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
 cxxConversionDecl(isExplicit()) will match #4, but not #3.
+cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
 </pre></td></tr>
 
 
@@ -2251,18 +2269,26 @@ cxxConstructorDecl(isMoveConstructor())
 
 
 <tr><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html";>CXXConversionDecl</a>&gt;</td><td
 class="name" onclick="toggle('isExplicit1')"><a 
name="isExplicit1Anchor">isExplicit</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isExplicit1"><pre>Matches constructor and 
conversion declarations that are marked with -the explicit keyword.
+<tr><td colspan="4" class="doc" id="isExplicit1"><pre>Matches 
+constructor, conversion function, and deduction guide declarations that 
+have an explicit specifier if this explicit specifier is resolved to true.
 
 Given
+  template&lt;bool b&gt;
   struct S {
     S(int); // #1
     explicit S(double); // #2
     operator int(); // #3
     explicit operator bool(); // #4
-  };
-cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+    explicit(false) S(bool) // # 7
+    explicit(true) S(char) // # 8
+    explicit(b) S(S) // # 9
+  };
+  S(int) -&gt; S&lt;true&gt; // #5
+  explicit S(double) -&gt; S&lt;false&gt; // #6
+cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
 cxxConversionDecl(isExplicit()) will match #4, but not #3.
+cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
 </pre></td></tr>
 
 
@@ -2317,6 +2343,30 @@ cxxConstructorDecl(hasAnyConstructorInit
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a 
+href="https://clang.llvm.org/doxygen/classclang_1_1CXXDeductionGuideDec
+l.html">CXXDeductionGuideDecl</a>&gt;</td><td class="name" 
+onclick="toggle('isExplicit2')"><a 
+name="isExplicit2Anchor">isExplicit</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicit2"><pre>Matches 
+constructor, conversion function, and deduction guide declarations that 
+have an explicit specifier if this explicit specifier is resolved to true.
+
+Given
+  template&lt;bool b&gt;
+  struct S {
+    S(int); // #1
+    explicit S(double); // #2
+    operator int(); // #3
+    explicit operator bool(); // #4
+    explicit(false) S(bool) // # 7
+    explicit(true) S(char) // # 8
+    explicit(b) S(S) // # 9
+  };
+  S(int) -&gt; S&lt;true&gt; // #5
+  explicit S(double) -&gt; S&lt;false&gt; // #6
+cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
+cxxConversionDecl(isExplicit()) will match #4, but not #3.
+cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html";>CXXDependentScopeMemberExpr</a>&gt;</td><td
 class="name" onclick="toggle('isArrow2')"><a 
name="isArrow2Anchor">isArrow</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isArrow2"><pre>Matches member expressions 
that are called with '-&gt;' as opposed  to '.'.
@@ -6007,6 +6057,29 @@ with compoundStmt()  </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a 
+href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html";>F
+unctionDecl</a>&gt;</td><td class="name" 
onclick="toggle('hasExplicitSpecifier0')"><a 
name="hasExplicitSpecifier0Anchor">hasExplicitSpecifier</a></td><td>Matcher&lt;<a
 href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html";>Expr</a>&gt; 
InnerMatcher</td></tr> <tr><td colspan="4" class="doc" 
id="hasExplicitSpecifier0"><pre>Matches the expression in an explicit specifier 
if present in the given declaration.
+
+Given
+  template&lt;bool b&gt;
+  struct S {
+    S(int); // #1
+    explicit S(double); // #2
+    operator int(); // #3
+    explicit operator bool(); // #4
+    explicit(false) S(bool) // # 7
+    explicit(true) S(char) // # 8
+    explicit(b) S(S) // # 9
+  };
+  S(int) -&gt; S&lt;true&gt; // #5
+  explicit S(double) -&gt; S&lt;false&gt; // #6
+cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 and 
#9, but not #1 or #2.
+cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or 
#4.
+cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match #5 
or #6.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html";>FunctionDecl</a>&gt;</td><td
 class="name" onclick="toggle('hasParameter0')"><a 
name="hasParameter0Anchor">hasParameter</a></td><td>unsigned N, Matcher&lt;<a 
href="https://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html";>ParmVarDecl</a>&gt;
 InnerMatcher</td></tr>  <tr><td colspan="4" class="doc" 
id="hasParameter0"><pre>Matches the n'th parameter of a function or an ObjC 
method  declaration or a block.

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=363855&r1=363854&r2=363855&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Jun 19 11:27:56 2019
@@ -2033,6 +2033,9 @@ public:
   // if the given declaration has no explicit. the returned explicit specifier
   // is defaulted. .isSpecified() will be false.
   static ExplicitSpecifier getFromDecl(FunctionDecl *Function);
+  static const ExplicitSpecifier getFromDecl(const FunctionDecl *Function) {
+    return getFromDecl(const_cast<FunctionDecl *>(Function));  }
   static ExplicitSpecifier Invalid() {
     return ExplicitSpecifier(nullptr, ExplicitSpecKind::Unresolved);
   }

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=363855&r1=363854&r2=363855&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed Jun 19 
+++ 11:27:56 2019
@@ -1138,6 +1138,17 @@ extern const internal::VariadicDynCastAl  extern const 
internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
     cxxConversionDecl;
 
+/// Matches user-defined and implicitly generated deduction guide.
+///
+/// Example matches the deduction guide.
+/// \code
+///   template<typename T>
+///   class X { X(int) };
+///   X(int) -> X<int>;
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
+    cxxDeductionGuideDecl;
+
 /// Matches variable declarations.
 ///
 /// Note: this does not match declarations of member variables, which are @@ 
-6154,29 +6165,63 @@ AST_MATCHER(CXXConstructorDecl, isDelega
   return Node.isDelegatingConstructor();  }
 
-/// Matches constructor and conversion declarations that are marked with -/// 
the explicit keyword.
+/// Matches constructor, conversion function, and deduction guide 
+declarations /// that have an explicit specifier if this explicit 
+specifier is resolved to /// true.
 ///
 /// Given
 /// \code
+///   template<bool b>
 ///   struct S {
 ///     S(int); // #1
 ///     explicit S(double); // #2
 ///     operator int(); // #3
 ///     explicit operator bool(); // #4
+///     explicit(false) S(bool) // # 7
+///     explicit(true) S(char) // # 8
+///     explicit(b) S(S) // # 9
 ///   };
+///   S(int) -> S<true> // #5
+///   explicit S(double) -> S<false> // #6
 /// \endcode
-/// cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+/// cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or 
#9.
 /// cxxConversionDecl(isExplicit()) will match #4, but not #3.
-AST_POLYMORPHIC_MATCHER(isExplicit,
-                        AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl,
-                                                        CXXConversionDecl)) {
-  // FIXME : it's not clear whether this should match a dependent
-  //         explicit(....). this matcher should also be able to match
-  //         CXXDeductionGuideDecl with explicit specifier.
+/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
+AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES(
+                                        CXXConstructorDecl, CXXConversionDecl,
+                                        CXXDeductionGuideDecl)) {
   return Node.isExplicit();
 }
 
+/// Matches the expression in an explicit specifier if present in the 
+given /// declaration.
+///
+/// Given
+/// \code
+///   template<bool b>
+///   struct S {
+///     S(int); // #1
+///     explicit S(double); // #2
+///     operator int(); // #3
+///     explicit operator bool(); // #4
+///     explicit(false) S(bool) // # 7
+///     explicit(true) S(char) // # 8
+///     explicit(b) S(S) // # 9
+///   };
+///   S(int) -> S<true> // #5
+///   explicit S(double) -> S<false> // #6
+/// \endcode
+/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 
and #9, but not #1 or #2.
+/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 
or #4.
+/// cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match 
#5 or #6.
+AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>,
+              InnerMatcher) {
+  ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node);
+  if (!ES.getExpr())
+    return false;
+  return InnerMatcher.matches(*ES.getExpr(), Finder, Builder); }
+
 /// Matches function and namespace declarations that are marked with  /// the 
inline keyword.
 ///

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=363855&r1=363854&r2=363855&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Wed Jun 19 11:27:56 
+++ 2019
@@ -169,6 +169,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(cxxConstructorDecl);
   REGISTER_MATCHER(cxxConversionDecl);
   REGISTER_MATCHER(cxxCtorInitializer);
+  REGISTER_MATCHER(cxxDeductionGuideDecl);
   REGISTER_MATCHER(cxxDefaultArgExpr);
   REGISTER_MATCHER(cxxDeleteExpr);
   REGISTER_MATCHER(cxxDependentScopeMemberExpr);
@@ -267,6 +268,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(hasEitherOperand);
   REGISTER_MATCHER(hasElementType);
   REGISTER_MATCHER(hasElse);
+  REGISTER_MATCHER(hasExplicitSpecifier);
   REGISTER_MATCHER(hasExternalFormalLinkage);
   REGISTER_MATCHER(hasFalseExpression);
   REGISTER_MATCHER(hasGlobalStorage);

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=363855&r1=363854&r2=363855&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Wed Jun 
+++ 19 11:27:56 2019
@@ -878,6 +878,15 @@ TEST(ConversionDeclaration, IsExplicit)
                       cxxConversionDecl(isExplicit())));
   EXPECT_TRUE(notMatches("struct S { operator int(); };",
                          cxxConversionDecl(isExplicit())));
+  EXPECT_TRUE(matchesConditionally(
+      "template<bool b> struct S { explicit(b) operator int(); };",
+      cxxConversionDecl(isExplicit()), false, "-std=c++2a"));  
+ EXPECT_TRUE(matchesConditionally(
+      "struct S { explicit(true) operator int(); };",
+      cxxConversionDecl(isExplicit()), true, "-std=c++2a"));  
+ EXPECT_TRUE(matchesConditionally(
+      "struct S { explicit(false) operator int(); };",
+      cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
 }
 
 TEST(Matcher, ArgumentCount) {
@@ -1197,6 +1206,38 @@ TEST(ConstructorDeclaration, IsExplicit)
                       cxxConstructorDecl(isExplicit())));
   EXPECT_TRUE(notMatches("struct S { S(int); };",
                          cxxConstructorDecl(isExplicit())));
+  EXPECT_TRUE(matchesConditionally(
+      "template<bool b> struct S { explicit(b) S(int);};",
+      cxxConstructorDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(true) S(int);};",
+                                   cxxConstructorDecl(isExplicit()), true,
+                                   "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(false) S(int);};",
+                                   cxxConstructorDecl(isExplicit()), false,
+                                   "-std=c++2a")); }
+
+TEST(DeductionGuideDeclaration, IsExplicit) {
+  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
+                                   "S(int) -> S<int>;",
+                                   cxxDeductionGuideDecl(isExplicit()), false,
+                                   "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
+                                   "explicit S(int) -> S<int>;",
+                                   cxxDeductionGuideDecl(isExplicit()), true,
+                                   "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
+                                   "explicit(true) S(int) -> S<int>;",
+                                   cxxDeductionGuideDecl(isExplicit()), true,
+                                   "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
+                                   "explicit(false) S(int) -> S<int>;",
+                                   cxxDeductionGuideDecl(isExplicit()), false,
+                                   "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "template<typename T> struct S { S(int);};"
+      "template<bool b = true> explicit(b) S(int) -> S<int>;",
+      cxxDeductionGuideDecl(isExplicit()), false, "-std=c++2a"));
 }
 
 TEST(ConstructorDeclaration, Kinds) {

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=363855&r1=363854&r2=363855&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Wed Jun 
+++ 19 11:27:56 2019
@@ -1735,6 +1735,56 @@ TEST(SwitchCase, MatchesEachCase) {
     llvm::make_unique<VerifyIdIsBoundTo<CaseStmt>>("x", 3)));  }
 
+TEST(Declaration, HasExplicitSpecifier) {
+  EXPECT_TRUE(matchesConditionally(
+      "void f();", functionDecl(hasExplicitSpecifier(constantExpr())), false,
+      "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "template<bool b> struct S { explicit operator int(); };",
+      
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "template<bool b> struct S { explicit(b) operator int(); };",
+      
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "struct S { explicit(true) operator int(); };",
+      
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "struct S { explicit(false) operator int(); };",
+      
cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "template<bool b> struct S { explicit(b) S(int); };",
+      
cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "struct S { explicit(true) S(int); };",
+      
cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "struct S { explicit(false) S(int); };",
+      
cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+      "template<typename T> struct S { S(int); };"
+      "template<bool b = true> explicit(b) S(int) -> S<int>;",
+      cxxDeductionGuideDecl(
+          hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+      false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int); };"
+                                   "explicit(true) S(int) -> S<int>;",
+                                   cxxDeductionGuideDecl(hasExplicitSpecifier(
+                                       constantExpr(has(cxxBoolLiteral())))),
+                                   true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int); };"
+                                   "explicit(false) S(int) -> S<int>;",
+                                   cxxDeductionGuideDecl(hasExplicitSpecifier(
+                                       constantExpr(has(cxxBoolLiteral())))),
+                                   true, "-std=c++2a")); }
+
 TEST(ForEachConstructorInitializer, MatchesInitializers) {
   EXPECT_TRUE(matches(
     "struct X { X() : i(42), j(42) {} int i, j; };",


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

Reply via email to