Unexpected TypeLoc match for captured variable in lambda

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Unexpected TypeLoc match for captured variable in lambda

Bakhvalov, Denis via cfe-dev
Hi,

In the following example, the captured variable `fn` is matched as a TypeLoc of Foo; `fn` outside of the lambda is not matched.
```
// test.cc
class Foo {};                              
  
template <typename T> struct Fn { T t; };  

void f(Fn<Foo> &fn) {
  [&](const Foo &foo) {
    fn;  // <--------- *** This is matched as a TypeLoc of Foo ***
  }; 
}
```

clang-query> m typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))))
...
Match #2:
test.cc:7:5: note: "root" binds here
    fn;
    ^~
...

Is this a bug? If not, is there a way to filter this out? 

Thanks,
Eric


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected TypeLoc match for captured variable in lambda

Bakhvalov, Denis via cfe-dev
I think there was some work recently that changed how we represented lambdas, but not sure whether that affected this behavior.
Here, the FieldDecl of the CXXRecordDecl has a const Foo & type and it has the 'fn' as the TypeLoc - I assume the location is a bug.

I got there through clang-query by adding hasParent() and guessing the types, iterating between output dump, print and diag.

Note that the output of the class in the second query is a red herring - the first one shows that we end up there via a FieldDecl (Binding for "3").

clang-query> m typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))), hasParent(typeLoc(hasParent(typeLoc(hasParent(decl(hasParent(decl().bind("4"))).bind("3"))).bind("2"))).bind("1"))) 

Match #1:

Binding for "1":
Unable to dump values of type TypeLoc

Binding for "2":
Unable to dump values of type TypeLoc

Binding for "3":
FieldDecl 0x7f51ffd91ee0 </tmp/t.cc:7:5> col:5 implicit 'Fn<Foo> &'

Binding for "4":
CXXRecordDecl 0x7f51ffd91c88 </tmp/t.cc:6:3> col:3 implicit class definition
|-DefinitionData lambda pass_in_registers trivially_copyable can_const_default_init
| |-DefaultConstructor
| |-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
|-FieldDecl 0x7f51ffd91ee0 <line:7:5> col:5 implicit 'Fn<Foo> &'
|-CXXMethodDecl 0x7f51ffd91dc0 <line:6:21, line:8:3> line:6:3 operator() 'void (const Foo &) const' inline
| |-ParmVarDecl 0x7f51ffd91ba8 <col:7, col:18> col:18 foo 'const Foo &'
| `-CompoundStmt 0x7f51ffd91f30 <col:23, line:8:3>
|   `-DeclRefExpr 0x7f51ffd91e78 <line:7:5> 'Fn<Foo>':'Fn<Foo>' lvalue ParmVar 0x7f51ffd91980 'fn' 'Fn<Foo> &'
`-CXXDestructorDecl 0x7f51ffdc3080 <line:6:3> col:3 implicit referenced ~ 'void () noexcept' inline default trivial

Binding for "root":
Unable to dump values of type TypeLoc

clang-query> set output print 

clang-query> m typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))), hasParent(typeLoc(hasParent(typeLoc(hasParent(decl(hasParent(decl().bind("4"))).bind("3"))).bind("2"))).bind("1")))

Match #1:

Binding for "1":
Fn<Foo>
Binding for "2":
Fn<Foo> &
Binding for "3":
Fn<Foo> &
Binding for "4":
class {
   inline void operator()(const Foo &foo) const     {
       fn;
   }
}
Binding for "root":
Foo
1 match.


On Thu, Feb 14, 2019 at 3:13 PM Eric Liu via cfe-dev <[hidden email]> wrote:
Hi,

In the following example, the captured variable `fn` is matched as a TypeLoc of Foo; `fn` outside of the lambda is not matched.
```
// test.cc
class Foo {};                              
  
template <typename T> struct Fn { T t; };  

void f(Fn<Foo> &fn) {
  [&](const Foo &foo) {
    fn;  // <--------- *** This is matched as a TypeLoc of Foo ***
  }; 
}
```

clang-query> m typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))))
...
Match #2:
test.cc:7:5: note: "root" binds here
    fn;
    ^~
...

Is this a bug? If not, is there a way to filter this out? 

Thanks,
Eric

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected TypeLoc match for captured variable in lambda

Bakhvalov, Denis via cfe-dev
On 25/03/2019 08:59, Manuel Klimek via cfe-dev wrote:
> I think there was some work recently that changed how we represented
> lambdas, but not sure whether that affected this behavior.
> Here, the FieldDecl of the CXXRecordDecl has a const Foo & type and it
> has the 'fn' as the TypeLoc - I assume the location is a bug.

I don't know if it is a bug, but from the FieldDecl the matched typeloc
seems to be:

 
getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getArgLoc(0).getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()


  http://ce.steveire.com/z/Iw8YiQ


>
> I got there through clang-query by adding hasParent() and guessing the
> types, iterating between output dump, print and diag.

You might already know this, but you don't have to iterate between them
anymore. You can just enable all three:

  enable output detailed-ast
  enable output print
  enable output diag # On by default, so this line is not needed


Thanks,

Stephen.

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev