Tyker updated this revision to Diff 205602. Tyker added a comment. i was confuse because the log seemed like an error and it was happening in python2.7 and python3.7 but the actual error that was preventing generating the documentation only occurs in 3.7.
it works in python2.7. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D61552/new/ https://reviews.llvm.org/D61552 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/AST/DeclCXX.h clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1735,6 +1735,56 @@ 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; };", Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -878,6 +878,15 @@ 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 @@ 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) { Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -169,6 +169,7 @@ 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 @@ REGISTER_MATCHER(hasEitherOperand); REGISTER_MATCHER(hasElementType); REGISTER_MATCHER(hasElse); + REGISTER_MATCHER(hasExplicitSpecifier); REGISTER_MATCHER(hasExternalFormalLinkage); REGISTER_MATCHER(hasFalseExpression); REGISTER_MATCHER(hasGlobalStorage); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1138,6 +1138,17 @@ 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,64 @@ 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. /// 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. +/// cxxConstructorDecl(isExplicit()) will match #8, but not #7 or #9. +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. /// Index: clang/include/clang/AST/DeclCXX.h =================================================================== --- clang/include/clang/AST/DeclCXX.h +++ clang/include/clang/AST/DeclCXX.h @@ -2033,6 +2033,9 @@ // 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); } Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -194,6 +194,16 @@ </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('cxxDeductionGuideDecl0')"><a name="cxxDeductionGuideDecl0Anchor">cxxDeductionGuideDecl</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXDeductionGuideDecl.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,27 @@ <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 + 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, but not #1. cxxConversionDecl(isExplicit()) will match #4, but not #3. +cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5. +cxxConstructorDecl(isExplicit()) will match #8, but not #7 or #9. </pre></td></tr> @@ -2251,18 +2270,27 @@ <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 + 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, but not #1. cxxConversionDecl(isExplicit()) will match #4, but not #3. +cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5. +cxxConstructorDecl(isExplicit()) will match #8, but not #7 or #9. </pre></td></tr> @@ -2317,6 +2345,31 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXDeductionGuideDecl.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, but not #1. +cxxConversionDecl(isExplicit()) will match #4, but not #3. +cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5. +cxxConstructorDecl(isExplicit()) will match #8, but not #7 or #9. +</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 +6060,29 @@ </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('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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits