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<<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<<a +href="https://clang.llvm.org/doxygen/classclang_1_1CXXDeductionGuideDec +l.html">CXXDeductionGuideDecl</a>>...</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<typename T> + class X { X(int) }; + X(int) -> X<int>; +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('cxxDestructorDecl0')"><a name="cxxDestructorDecl0Anchor">cxxDestructorDecl</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXDestructorDecl.html">CXXDestructorDecl</a>>...</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<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></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<bool b> 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) -> S<true> // #5 + explicit S(double) -> S<false> // #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<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html">CXXConversionDecl</a>></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<bool b> 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) -> S<true> // #5 + explicit S(double) -> S<false> // #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<<a +href="https://clang.llvm.org/doxygen/classclang_1_1CXXDeductionGuideDec +l.html">CXXDeductionGuideDecl</a>></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<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 +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<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html">CXXDependentScopeMemberExpr</a>></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 '->' as opposed to '.'. @@ -6007,6 +6057,29 @@ with compoundStmt() </pre></td></tr> +<tr><td>Matcher<<a +href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">F +unctionDecl</a>></td><td class="name" onclick="toggle('hasExplicitSpecifier0')"><a name="hasExplicitSpecifier0Anchor">hasExplicitSpecifier</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> 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<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 +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<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasParameter0')"><a name="hasParameter0Anchor">hasParameter</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> 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