Skip to content

AST Matcher parmVarDecl() parent lambdaExpr() not reachable #36977

@steveire

Description

@steveire
Bugzilla Link 37629
Version trunk
OS Windows NT
CC @DougGregor

Extended Description

C:\dev\src\clang-tools-extra\scripttests>type testit.cpp
void foo(const char* match)
{

}

typedef bool(*functionType)(const char* desc);

functionType g_testReportFunction;

int main(int argc, char**argv)
{
    g_testReportFunction = [](const char* doNotMatch) -> bool
    {
        return false;
    };

    auto l = [](const char* doNotMatch)
    {

    };

    auto l2 = [&argc](const char* doNotMatch)
    {

    };

    return 0;
}
C:\dev\src\clang-tools-extra\scripttests>C:\dev\src\llvm\build\releaseprefix\bin\clang-query.exe testit.cpp
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "testit.cpp"
No compilation database found in C:\dev\src\clang-tools-extra\scripttests or any parent directory
fixed-compilation-database: Error while opening fixed database: no such file or directory
json-compilation-database: Error while opening JSON database: no such file or directory
Running without flags.
testit.cpp


# NOTE: This should also match the g_testReportFunction  lambda


clang-query> m parmVarDecl(hasType(pointerType(pointee(isAnyCharacter()))), hasParent(lambdaExpr().bind("e")))

Match #1:

C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14: note: "e" binds here
    auto l = [](const char* doNotMatch)
             ^~~~~~~~~~~~~~~~~~~~~~~~~~
C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:17: note: "root" binds here
    auto l = [](const char* doNotMatch)
                ^~~~~~~~~~~~~~~~~~~~~~

Match #2:

C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15: note: "e" binds here
    auto l2 = [&argc](const char* doNotMatch)
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:23: note: "root" binds here
    auto l2 = [&argc](const char* doNotMatch)
                      ^~~~~~~~~~~~~~~~~~~~~~
2 matches.


# NOTE: This should also match the g_testReportFunction  lambda, or at least show something for it.


clang-query> m parmVarDecl(hasType(pointerType(pointee(isAnyCharacter()))), hasParent(expr().bind("e")))

Match #1:

C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14: note: "e" binds here
    auto l = [](const char* doNotMatch)
             ^~~~~~~~~~~~~~~~~~~~~~~~~~
C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:17: note: "root" binds here
    auto l = [](const char* doNotMatch)
                ^~~~~~~~~~~~~~~~~~~~~~

Match #2:

C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15: note: "e" binds here
    auto l2 = [&argc](const char* doNotMatch)
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:23: note: "root" binds here
    auto l2 = [&argc](const char* doNotMatch)
                      ^~~~~~~~~~~~~~~~~~~~~~
2 matches.
clang-query>


Dumping main shows the expected AST structure:

clang-query> m functionDecl(hasName("main"))                                                                                                                                                                                                                                                                                                          Match #1:                                                                                                                                                                                                                                                                                                                                             Binding for "root":                                                                                                                                                        FunctionDecl 0x155d40e1678 <C:\dev\src\clang-tools-extra\scripttests\testit.cpp:11:1, line:29:1> line:11:5 main 'int (int, char **)'                                       |-ParmVarDecl 0x155d40e14f8 <col:10, col:14> col:14 used argc 'int'                                                                                                        |-ParmVarDecl 0x155d40e15a0 <col:20, col:26> col:26 argv 'char **'                                                                                                         `-CompoundStmt 0x155d40ea4b8 <line:12:1, line:29:1>                                                                                                                          |-BinaryOperator 0x155d40e2128 <line:13:5, line:16:5> 'functionType':'bool (*)(const char *)' lvalue '='                                                                   | |-DeclRefExpr 0x155d40e1728 <line:13:5> 'functionType':'bool (*)(const char *)' lvalue Var 0x155d40e1480 'g_testReportFunction' 'functionType':'bool (*)(const char *)'                                                                                                                                                                             | `-ImplicitCastExpr 0x155d40e2110 <col:28, line:16:5> 'auto (*)(const char *) -> bool' <UserDefinedConversion>                                                            |   `-CXXMemberCallExpr 0x155d40e20e8 <line:13:28, line:16:5> 'auto (*)(const char *) -> bool'                                                                             |     `-MemberExpr 0x155d40e2030 <line:13:28, line:16:5> '<bound member function type>' .operator bool (*)(const char *) 0x155d40e1ca0                                     |       `-ImplicitCastExpr 0x155d40e2018 <line:13:28, line:16:5> 'const (lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:13:28)' <NoOp>                      |         `-LambdaExpr 0x155d40e1e10 <line:13:28, line:16:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:13:28)'                                       |           |-CXXRecordDecl 0x155d40e18a0 <line:13:28> col:28 implicit class definition                                                                                    |           | |-DefinitionData lambda pass_in_registers empty standard_layout trivially_copyable can_const_default_init                                                    |           | | |-DefaultConstructor defaulted_is_constexpr                                                                                                                |           | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param                                                                   |           | | |-MoveConstructor exists simple trivial needs_implicit                                                                                                     |           | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param                                                                           |           | | |-MoveAssignment                                                                                                                                           |           | | `-Destructor simple irrelevant trivial                                                                                                                     |           | |-CXXMethodDecl 0x155d40e19e0 <col:58, line:16:5> line:13:28 used operator() 'auto (const char *) const -> bool' inline                                      |           | | |-ParmVarDecl 0x155d40e1768 <col:31, col:43> col:43 doNotMatch 'const char *'                                                                              |           | | `-CompoundStmt 0x155d40e1ac8 <line:14:5, line:16:5>                                                                                                        |           | |   `-ReturnStmt 0x155d40e1ab0 <line:15:9, col:16>                                                                                                           |           | |     `-CXXBoolLiteralExpr 0x155d40e1a98 <col:16> 'bool' false                                                                                               |           | |-CXXConversionDecl 0x155d40e1ca0 <line:13:28> col:28 implicit used operator bool (*)(const char *) 'auto (*() const)(const char *) -> bool' inline          |           | | `-CompoundStmt 0x155d40e20d0 <col:28>                                                                                                                      |           | |   `-ReturnStmt 0x155d40e20b8 <col:28>                                                                                                                      |           | |     `-ImplicitCastExpr 0x155d40e20a0 <col:28> 'auto (*)(const char *) -> bool' <FunctionToPointerDecay>                                                    |           | |       `-DeclRefExpr 0x155d40e2078 <col:28> 'auto (const char *) -> bool' lvalue CXXMethod 0x155d40e1d48 '__invoke' 'auto (const char *) -> bool'           |           | |-CXXMethodDecl 0x155d40e1d48 <col:28> col:28 implicit used __invoke 'auto (const char *) -> bool' static inline                                             |           | | |-ParmVarDecl 0x155d40e1c40 <col:31, col:43> col:43 doNotMatch 'const char *'                                                                              |           | | `-CompoundStmt 0x155d40e2068 <col:28>                                                                                                                      |           | `-CXXDestructorDecl 0x155d40e1e40 <col:28> col:28 implicit referenced ~ 'void () noexcept' inline default trivial                                            |           `-CompoundStmt 0x155d40e1ac8 <line:14:5, line:16:5>                                                                                                            |             `-ReturnStmt 0x155d40e1ab0 <line:15:9, col:16>                                                                                                               |               `-CXXBoolLiteralExpr 0x155d40e1a98 <col:16> 'bool' false                                                                                                   |-DeclStmt 0x155d40ec8a8 <line:18:5, line:21:6>                                                                                                                            | `-VarDecl 0x155d40ebae0 <line:18:5, line:21:5> line:18:10 l '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)':'(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)' cinit                                                                                                                                   |   `-ExprWithCleanups 0x155d40ec890 <col:14, line:21:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)':'(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)'                                                                                                                                              |     `-CXXConstructExpr 0x155d40ec858 <line:18:14, line:21:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)':'(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)' 'void ((lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14) &&) noexcept' elidable                                    |       `-MaterializeTemporaryExpr 0x155d40ec7f8 <line:18:14, line:21:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)' xvalue                    |         `-LambdaExpr 0x155d40ec250 <line:18:14, line:21:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14)'                                       |           |-CXXRecordDecl 0x155d40ebc20 <line:18:14> col:14 implicit class definition                                                                                    |           | |-DefinitionData lambda pass_in_registers empty standard_layout trivially_copyable can_const_default_init                                                    |           | | |-DefaultConstructor defaulted_is_constexpr                                                                                                                |           | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param                                                                                  |           | | |-MoveConstructor exists simple trivial                                                                                                                    |           | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param                                                                           |           | | |-MoveAssignment                                                                                                                                           |           | | `-Destructor simple irrelevant trivial                                                                                                                     |           | |-CXXMethodDecl 0x155d40ebd60 <col:39, line:21:5> line:18:14 operator() 'void (const char *) const' inline                                                   |           | | |-ParmVarDecl 0x155d40ebb58 <col:17, col:29> col:29 doNotMatch 'const char *'                                                                              |           | | `-CompoundStmt 0x155d40ebe18 <line:19:5, line:21:5>                                                                                                        |           | |-CXXConversionDecl 0x155d40ec0e0 <line:18:14, line:21:5> line:18:14 implicit operator void (*)(const char *) 'void (*() const)(const char *)' inline        |           | |-CXXMethodDecl 0x155d40ec188 <col:14, line:21:5> line:18:14 implicit __invoke 'void (const char *)' static inline                                           |           | | `-ParmVarDecl 0x155d40ec080 <col:17, col:29> col:29 doNotMatch 'const char *'                                                                              |           | |-CXXDestructorDecl 0x155d40ec280 <col:14> col:14 implicit referenced ~ 'void () noexcept' inline default trivial                                            |           | |-CXXConstructorDecl 0x155d40ec488 <col:14> col:14 implicit constexpr  'void (const (lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14) &)' inline default trivial noexcept-unevaluated 0x155d40ec488                                                                                                                 |           | | `-ParmVarDecl 0x155d40ec5c0 <col:14> col:14 'const (lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14) &'                                |           | `-CXXConstructorDecl 0x155d40ec658 <col:14> col:14 implicit used constexpr  'void ((lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14) &&) noexcept' inline default trivial                                                                                                                                           |           |   |-ParmVarDecl 0x155d40ec790 <col:14> col:14 '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:18:14) &&'                                     |           |   `-CompoundStmt 0x155d40ec848 <col:14>                                                                                                                      |           `-CompoundStmt 0x155d40ebe18 <line:19:5, line:21:5>                                                                                                            |-DeclStmt 0x155d40ea460 <line:23:5, line:26:6>                                                                                                                            | `-VarDecl 0x155d40ec8d0 <line:23:5, line:26:5> line:23:10 l2 '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)':'(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)' cinit                                                                                                                                  |   `-ExprWithCleanups 0x155d40ea448 <col:15, line:26:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)':'(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)'                                                                                                                                              |     `-CXXConstructExpr 0x155d40ea410 <line:23:15, line:26:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)':'(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)' 'void ((lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &&) noexcept' elidable                                    |       `-MaterializeTemporaryExpr 0x155d40ea2c8 <line:23:15, line:26:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)' xvalue                    |         `-LambdaExpr 0x155d40e9d38 <line:23:15, line:26:5> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)'                                       |           |-CXXRecordDecl 0x155d40ec9d0 <line:23:15> col:15 implicit class definition                                                                                    |           | |-DefinitionData lambda pass_in_registers trivially_copyable can_const_default_init                                                                          |           | | |-DefaultConstructor                                                                                                                                       |           | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param                                                                                  |           | | |-MoveConstructor exists simple trivial                                                                                                                    |           | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param                                                                           |           | | |-MoveAssignment                                                                                                                                           |           | | `-Destructor simple irrelevant trivial                                                                                                                     |           | |-FieldDecl 0x155d40e9c70 <col:17> col:17 implicit referenced 'int &'                                                                                        |           | |-CXXMethodDecl 0x155d40e9b70 <col:45, line:26:5> line:23:15 operator() 'void (const char *) const' inline                                                   |           | | |-ParmVarDecl 0x155d40ec948 <col:23, col:35> col:35 doNotMatch 'const char *'                                                                              |           | | `-CompoundStmt 0x155d40e9cc0 <line:24:5, line:26:5>                                                                                                        |           | |-CXXDestructorDecl 0x155d40e9d80 <line:23:15> col:15 implicit referenced ~ 'void () noexcept' inline default trivial                                        |           | |-CXXConstructorDecl 0x155d40e9f58 <col:15> col:15 implicit constexpr  'void (const (lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &)' inline default trivial noexcept-unevaluated 0x155d40e9f58                                                                                                                 |           | | `-ParmVarDecl 0x155d40ea090 <col:15> col:15 'const (lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &'                                |           | `-CXXConstructorDecl 0x155d40ea128 <col:15> col:15 implicit used constexpr  'void ((lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &&) noexcept' inline default trivial                                                                                                                                           |           |   |-ParmVarDecl 0x155d40ea260 <col:15> col:15 used '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &&'                                |           |   |-CXXCtorInitializer Field 0x155d40e9c70 '' 'int &'                                                                                                        |           |   | `-MemberExpr 0x155d40ea380 <col:15> 'int' lvalue . 0x155d40e9c70                                                                                         |           |   |   `-CXXStaticCastExpr 0x155d40ea350 <col:15> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)' xvalue static_cast<class (lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &&> <NoOp>                                                                                                      |           |   |     `-DeclRefExpr 0x155d40ea318 <col:15> '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15)' lvalue ParmVar 0x155d40ea260 '' '(lambda at C:\dev\src\clang-tools-extra\scripttests\testit.cpp:23:15) &&'                                                                                                         |           |   `-CompoundStmt 0x155d40ea400 <col:15>                                                                                                                      |           |-DeclRefExpr 0x155d40e9cf0 <col:17> 'int' lvalue ParmVar 0x155d40e14f8 'argc' 'int'                                                                           |           `-CompoundStmt 0x155d40e9cc0 <line:24:5, line:26:5>                                                                                                            `-ReturnStmt 0x155d40ea4a0 <line:28:5, col:12>                                                                                                                               `-IntegerLiteral 0x155d40ea478 <col:12> 'int' 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillac++clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions