diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -96,6 +96,337 @@
+ +The default mode of operation of AST Matchers visits all nodes in the AST, +even if they are not spelled in the source. This is AsIs mode. This mode is +hard to use correctly and requires more development iteration because it means +that the user must write AST Matchers to explicitly traverse or ignore nodes +which are not visible.
+ +In addition, because template instantations are matched in the default mode, +transformations can be accidentally made to template declarations. Finally, +because implicit nodes are matched by default, transformations can be made on +entirely incorrect places in the code.
+ +For these reasons, it is possible to ignore AST nodes which are not spelled in +the source using the IgnoreUnlessSpelledInSource mode. This is likely to be far +less error-prone for users who are not already very familiar with the AST. It is +also likely to be less error-prone for experienced AST users, as difficult cases +do not need to be encountered and matcher expressions adjusted for these +cases.
+ +In clang-query, the mode can be changed with +
+set traversal IgnoreUnlessSpelledInSource ++ +This affects both matchers and AST dump output in results. + +
When using the C++ API such as in clang-tidy checks, the traverse() matcher +is used to set the mode: +
+Finder->addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, + returnStmt(hasReturnArgument(integerLiteral(equals(0)))) + ), this); ++ +
The following table compares the AsIs mode with the IgnoreUnlessSpelledInSource +mode:
+ + + +AsIs | IgnoreUnlessSpelledInSource | +|
---|---|---|
AST dump of func1:
++struct B +{ + B(int); +}; + +B func1() { + return 42; +} ++ + |
+
+C++98 dialect:
++FunctionDecl +`-CompoundStmt + `-ReturnStmt + `-ExprWithCleanups + `-CXXConstructExpr + `-MaterializeTemporaryExpr + `-ImplicitCastExpr + `-ImplicitCastExpr + `-CXXConstructExpr + `-IntegerLiteral 'int' 42 ++C++11, C++14 dialect: + +FunctionDecl +`-CompoundStmt + `-ReturnStmt + `-ExprWithCleanups + `-CXXConstructExpr + `-MaterializeTemporaryExpr + `-ImplicitCastExpr + `-CXXConstructExpr + `-IntegerLiteral 'int' 42 ++C++17, C++20 dialect: + +FunctionDecl +`-CompoundStmt + `-ReturnStmt + `-ImplicitCastExpr + `-CXXConstructExpr + `-IntegerLiteral 'int' 42 ++ |
+
+All dialects:
+ +FunctionDecl +`-CompoundStmt + `-ReturnStmt + `-IntegerLiteral 'int' 42 + |
+
Matcher for returned '42':
++struct B +{ + B(int); +}; + +B func1() { + return 42; +} ++ + |
+
+All dialects:
++returnStmt(hasReturnValue( + ignoringImplicit( + ignoringElidableConstructorCall( + ignoringImplicit( + cxxConstructExpr(hasArgument(0, + ignoringImplicit( + integerLiteral().bind("returnVal") + ) + )) + ) + ) + ) + )) + |
+
+All dialects:
++returnStmt(hasReturnValue( + integerLiteral().bind("returnVal") +)) + |
+
Match result for
+implicitCastExpr()+given: + +struct B +{ + B(int); +}; + +B func1() { + return 42; +} ++ + |
++Match found. | ++No match. | +
Match result for:
++cxxConstructorDecl( + isCopyConstructor() + ).bind("prepend_explicit") ++given: + +struct Other { +}; +struct Copyable { + Other m_o; + Copyable(); +}; ++ |
+
+Match found! Insertion produces incorrect output:
++struct Other { +}; +struct explicit Copyable { + Other m_o; + Copyable(); +}; ++ |
++No match found. Incorrect replacement not possible. + | +
Replacement of `begin()` with `cbegin()`:
++cxxMemberCallExpr( + on(ConstContainerExpr), + callee(cxxMethodDecl(hasName("begin"))) + ).bind("replace_with_cbegin") ++given: + +void foo() +{ + const Container c; + c.begin(); + + for (auto i : c) + { + + } +} ++ |
+
+2 matches found! Replacement produces incorrect output:
++void foo() +{ + const Container c; + c.cbegin(); + + for (auto i :.cbegin() c) + { + + } +} ++ |
+
+1 match found! Replacement produces correct output:
++void foo() +{ + const Container c; + c.cbegin(); + + for (auto i : c) + { + + } +} ++ |
+
Replacement of int member with safe_int:
++fieldDecl( + hasType(asString("int")) + ).bind("use_safe_int") ++given: + +struct S { + int m_i; +}; + +template<typename T> +struct TemplStruct { + TemplStruct() {} + ~TemplStruct() {} + +private: + T m_t; +}; + +void instantiate() +{ + TemplStruct<int> ti; +} ++ |
+
+2 matches found! Replacement produces incorrect output:
++struct S { + safe_int m_i; +}; + +template<typename T> +struct TemplStruct { + TemplStruct() {} + ~TemplStruct() {} + +private: + safe_int m_t; +}; + +void instantiate() +{ + TemplStruct<int> ti; +} ++ |
+
+1 match found! Replacement produces correct output:
++struct S { + safe_int m_i; +}; + +template<typename T> +struct TemplStruct { + TemplStruct() {} + ~TemplStruct() {} + +private: + T m_t; +}; + +void instantiate() +{ + TemplStruct<int> ti; +} ++ |
+
Return type | Name | Parameters |
---|