FunctionProtoType is changed during include expansion

Hi,

I am puzzling with the following phenomenon:
When I compile a source file normally (i.e. -c) then a given lambda’s signature is operator() 'int_type (long) const' where int_type is a TypeAlias. I.e. the return type is a TypedefType.
Now, when I compile the same source file with -E, then the signature is changed to the canonical type: operator() 'long (long) const'. I.e. the return type is no longer a TypedefType.
This happens also when I use -E -frewrite-includes.

Do you guys have any insights on this? What happens during include expansion so that the parser changes some internal state?

Thanks,
Gabor

Why this is a problem to me? Because I can’t write tests that are self-contained, the problematic AST with the TypedefType return type comes up only when we include some files.

For your interest, if you want to reproduce it, you can do that on llvm-project/master:

  1. Enable libcxx, libcxxabi
  2. ninja cxx
  3. ninja -v projects/libcxx/src/CMakeFiles/cxx_static.dir/filesystem/directory_iterator.cpp.o
  • grab the output and attach -E (and -frewrite-includes)
  1. ./bin/clang-check -p . libcxx/src/filesystem/directory_iterator.cpp -ast-dump -ast-dump-filter “posix_utimes” | ag “CXXMethodDecl.*int_type”
  • gives -CXXMethodDecl 0x3007ec0 <col:30, line:400:3> line:396:18 used operator() ‘int_type (long) const’ inline
  1. ./bin/clang -x c++ directory_iterator.cpp.E -fsyntax-only -Xclang -ast-dump -Xclang -ast-dump-filter -Xclang posix_utimes | ag “CXXMethodDecl.*operator”
  2. -CXXMethodDecl 0x31c6ad0 <col:30, line:400:3> line:396:18 used operator() ‘long (long) const’ inline

perhaps a smaller reproducer would be useful for this discussion? (so we could see the specific code, rather than a description of it or the entire libc++ test, etc)

This is a catch 22, because to get a smaller reproducer I should be able to work on the preprocessed file (only that’s what works considerably well with creduce).
However, the AST piece in question is about this source code:

auto Convert = [](long nsec) {
using int_type = decltype(std::declval< ::timeval>().tv_usec);
auto dur = duration_cast(nanoseconds(nsec)).count();
return static_cast<int_type>(dur);
};

This is a catch 22, because to get a smaller reproducer I should be able to work on the preprocessed file (only that’s what works considerably well with creduce).

creduce I think has a multi-file mode (Or perhaps multidelta?), but hand reduction is possible/may be necessary