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,471 @@
+ +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; +} ++ |
+
Add prefix to member initializer
++cxxCtorInitializer( + forField(fieldDecl()) + ).bind("add_prefix") ++given: + +struct Simple { +}; + +struct Record { + Record() : i(42) {} +private: + int i; + Simple s; +}; ++ |
+
+2 matches found! Replacement produces incorrect output:
++struct Simple { +}; + +struct Record { + m_Record() : m_i(42) {} +private: + int i; + Simple s; +}; ++ |
+
+1 match found! Replacement produces correct output:
++struct Simple { +}; + +struct Record { + Record() : m_i(42) {} +private: + int i; + Simple s; +}; ++ |
+
Ignored default arguments
++callExpr( + callee(functionDecl( + hasName("hasDefaultArg") + )), + argumentCountIs(1) + ).bind("add_prefix") ++given: + +void hasDefaultArg(int i, int j = 0) +{ +} +void callDefaultArg() +{ + hasDefaultArg(42); +} ++ |
++No match! + | ++1 match found! + | +
Lambda fields
++fieldDecl( + hasType(asString("int")) + ).bind("make_safe") ++given: + +struct S +{ + int m_i; +}; + +void func() { + int a = 0; + int c = 0; + + auto l = [a, b = c](int d) { int e = d; }; + l(43); +} ++ |
+
+2 matches found! Replacement produces incorrect output:
++struct S +{ + safe_int m_i; +}; + +void func() { + int a = 0; + int c = 0; + + auto l = [safe_a, safe_b = c](int d) { int e = d; }; + l(43); +}+ |
+
+1 match found! Replacement produces correct output:
++struct S +{ + safe_int m_i; +}; + +void func() { + int a = 0; + int c = 0; + + auto l = [a, b = c](int d) { int e = d; }; + l(43); +}+ |
+
+
Return type | Name | Parameters |
---|