ci: Add IWYU job #33810

pull hebasto wants to merge 6 commits into bitcoin:master from hebasto:251106-force-iwyu-ci changing 12 files +653 −12
  1. hebasto commented at 11:27 pm on November 6, 2025: member

    This PR separates the IWYU checks into its own CI job to provide faster feedback to developers. No other changes are made to the treatment of IWYU warnings. The existing “tidy” CI job will no longer run IWYU.

    See also the discussion of #33779, specifically this comment:

    Maybe a better approach would be to run the enforced sections in a separate, faster job? Some of the linters are already a bit annoying to invoke locally, so I usually just run the lint job. Doing the same for the includes seems fine to me.

    Based on ideas from #32953.

  2. hebasto added the label Tests on Nov 6, 2025
  3. DrahtBot commented at 11:28 pm on November 6, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33810.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK maflcko, sedited
    Concept ACK w0xlt, stickies-v

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #31425 (RFC: Riscv bare metal CI job by sedited)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  4. w0xlt commented at 0:00 am on November 7, 2025: contributor
    Concept ACK
  5. in src/crypto/hex_base.cpp:11 in f72b2f7f58 outdated
     7@@ -8,7 +8,6 @@
     8 #include <cassert>
     9 #include <cstring>
    10 #include <string>
    11-#include <tuple>
    


    maflcko commented at 10:49 am on November 7, 2025:

    I think both CI tasks should use the same config (debian:trixie). Otherwise, if someone tries to reproduce the CI config, they two configs will contradict each other, which doesn’t seem helpful?

    Also, I find it confusing that one CI task is printing the iwyu errors and the other is printing the warnings. What is the goal here? It seems clearer to just print the errors and warnings in one task, like it was done before.

    As mentioned previously, iwyu takes 9 minutes (https://github.com/bitcoin/bitcoin/pull/33779#issuecomment-3491592008) and in this pull it takes 30 seconds and you claim that it is faster. However, if the goal is to eventually run it on more stuff, it will take 9 minutes again. So I’d say we should also combine iwyu errors and warnings into one task, to be honest and accurate about the expected long-term runtime of the task.


    hebasto commented at 11:37 am on November 7, 2025:
    Reworked into a single job.
  6. fanquake commented at 11:14 am on November 7, 2025: member

    providing convenient feedback to developers.

    How can we improve the quality of the feedback (https://github.com/bitcoin/bitcoin/pull/33779#issuecomment-3496969502)? Getting it faster is nice, but if it can’t be taken and applied directly without fixing the sorting, and the formatting, and in the worse case, changing headers entirely for modernize-deprecated-headers, then it doesn’t seem that much more useful.

  7. hebasto commented at 11:26 am on November 7, 2025: member

    but if it can’t be taken and applied directly without fixing the sorting, and the formatting, and in the worse case, changing headers entirely for modernize-deprecated-headers, then it doesn’t seem that much more useful.

    I disagree. In practice, when a developer works on changes that modify includes, the diff in the includes would typically be just a few lines. Using the diff from the CI job as a hint seems entirely reasonable. I don’t see a strong need to increase the script’s complexity just to produce a diff that can be immediately applied.

  8. hebasto force-pushed on Nov 7, 2025
  9. in ci/test/03_test_script.sh:44 in 9bb013d8e5
    43@@ -44,7 +44,7 @@ echo "=== END env ==="
    44 # Don't apply patches in the tidy job, because it relies on the `git diff`
    


    maflcko commented at 11:55 am on November 7, 2025:
    0# Don't apply patches in the iwyu job, because it relies on the `git diff`
    

    nit, if you re-touch


    hebasto commented at 12:11 pm on November 7, 2025:
    Thanks! Fixed.
  10. maflcko approved
  11. maflcko commented at 12:01 pm on November 7, 2025: member
    lgtm. Seems fine
  12. hebasto renamed this:
    ci: Add fast IWYU job
    ci: Add IWYU job
    on Nov 7, 2025
  13. hebasto force-pushed on Nov 7, 2025
  14. DrahtBot added the label CI failed on Nov 7, 2025
  15. fanquake commented at 12:12 pm on November 7, 2025: member

    just to produce a diff that can be immediately applied.

    The diff can’t be applied at all, how wrong it is varies, and there are no instructions for devs on how to fix it.

  16. maflcko commented at 12:23 pm on November 7, 2025: member

    instructions

    Some basic instructions could be added after the echo "^^^ ⚠️ Failure generated from IWYU", if needed.

  17. hebasto commented at 12:32 pm on November 7, 2025: member

    instructions

    Some basic instructions could be added after the echo "^^^ ⚠️ Failure generated from IWYU", if needed.

    Happy to add them once someone suggests good wording.

  18. DrahtBot removed the label CI failed on Nov 7, 2025
  19. hebasto force-pushed on Nov 7, 2025
  20. hebasto commented at 3:36 pm on November 7, 2025: member
    Rebased on top of the merged bitcoin/bitcoin#33818.
  21. DrahtBot added the label CI failed on Nov 7, 2025
  22. hebasto force-pushed on Nov 7, 2025
  23. fanquake commented at 5:01 pm on November 7, 2025: member
    The TSAN failure is #33318.
  24. in ci/test/03_test_script.sh:214 in bd48a101f9 outdated
    216@@ -213,7 +217,9 @@ if [ "${RUN_TIDY}" = "true" ]; then
    217     echo "^^^ ⚠️ Failure generated from clang-tidy"
    218     false
    219   fi
    220+fi
    221 
    222+if [ "${RUN_IWYU}" == "true" ]; then
    223   # TODO: Consider enforcing IWYU across the entire codebase.
    


    maflcko commented at 5:42 pm on November 7, 2025:

    Maybe:

    0echo "^^^ ⚠️ Failure generated from IWYU"
    1echo
    2echo "Some adjustments to the diff may be needed:"
    3echo
    4echo "* Use the C++ headers: E.g. <cerrno> over <errno.h>"
    5echo '* Use #include <__.h> over #include "__.h" for all headers'
    6echo "* Sort the headers, so that they are in the right pre-existing section, if"
    7echo "  there are any."
    

    hebasto commented at 5:52 pm on November 7, 2025:
    Thanks! Added.
  25. hebasto force-pushed on Nov 7, 2025
  26. maflcko approved
  27. maflcko commented at 6:11 pm on November 7, 2025: member
    lgtm
  28. DrahtBot removed the label CI failed on Nov 7, 2025
  29. stickies-v commented at 12:52 pm on November 17, 2025: contributor

    Concept ACK, but a little more information in the PR description would be helpful, it’s hard to parse what expected behaviour is - both from the CI, as well as from developers. Does passing iwyu become mandatory for CI? Are we duplicating CI runs or moving it to a separate iwyu job? Should developers change anything in their workflow? Linking the previous discussion is helpful, but doesn’t necessarily describe what’s adopted in this PR.

    Also, style preferences wrt includes should be added to developer-notes.md imo.

  30. DrahtBot added the label Needs rebase on Nov 20, 2025
  31. hebasto force-pushed on Nov 20, 2025
  32. hebasto commented at 5:45 pm on November 20, 2025: member

    Concept ACK, but a little more information in the PR description would be helpful, it’s hard to parse what expected behaviour is - both from the CI, as well as from developers.

    The PR description has been updated.

    Does passing iwyu become mandatory for CI? Are we duplicating CI runs or moving it to a separate iwyu job?

    That isn’t the goal of this PR. Other PRs are dedicated to such changes: #33725 and #33779.

  33. hebasto commented at 5:46 pm on November 20, 2025: member
    Rebased.
  34. DrahtBot removed the label Needs rebase on Nov 20, 2025
  35. in ci/test/03_test_script.sh:247 in 3ead7ab320
    239@@ -234,6 +240,13 @@ if [ "${RUN_TIDY}" = "true" ]; then
    240   run_iwyu "compile_commands_iwyu_errors.json"
    241   if ! ( git --no-pager diff --exit-code ); then
    242     echo "^^^ ⚠️ Failure generated from IWYU"
    243+    echo
    244+    echo "Some adjustments to the diff may be needed:"
    245+    echo
    246+    echo "* Use the C++ headers: E.g. <cerrno> over <errno.h>"
    247+    echo '* Use #include <__.h> over #include "__.h" for all headers'
    


    fanquake commented at 4:57 pm on November 21, 2025:
    I’m wondering, given we are building IWYU from source, can we just patch it, so the output is correct (uses <>); avoiding the need for this fixup.

    hebasto commented at 5:51 pm on December 4, 2025:
    Thanks! Reworked.
  36. hebasto force-pushed on Dec 4, 2025
  37. hebasto commented at 5:51 pm on December 4, 2025: member
    The feedback from @fanquake has been addressed.
  38. in ci/test/03_test_script.sh:237 in 2d54366bd0
    230@@ -225,6 +231,12 @@ if [ "${RUN_TIDY}" = "true" ]; then
    231   run_iwyu "compile_commands_iwyu_errors.json"
    232   if ! ( git --no-pager diff --exit-code ); then
    233     echo "^^^ ⚠️ Failure generated from IWYU"
    234+    echo
    235+    echo "Some adjustments to the diff may be needed:"
    236+    echo
    237+    echo "* Use the C++ headers: E.g. <cerrno> over <errno.h>"
    


    maflcko commented at 9:18 am on December 5, 2025:

    nit: Looking at the output, I think this is already done correctly?

    If so, sorting can be done as well via:

     0diff --git a/src/.clang-format b/src/.clang-format
     1index c5fcd0b48c..4a1692a4bb 100644
     2--- a/src/.clang-format
     3+++ b/src/.clang-format
     4@@ -97,7 +97,7 @@ ForEachMacros:
     5   - BOOST_FOREACH
     6 IfMacros:
     7   - KJ_IF_MAYBE
     8-IncludeBlocks:   Preserve
     9+IncludeBlocks:   Regroup
    10 IncludeCategories:
    11   - Regex:           '^<bitcoin-build-config\.h>'
    12     Priority:        -1
    

    and then running:

    0git diff -U0 | ./contrib/devtools/clang-format-diff.py -p1 -i -v
    

    hebasto commented at 12:23 pm on December 5, 2025:

    nit: Looking at the output, I think this is already done correctly?

    I don’t think so. The generated diffs still suggest the C headers:

    0+#include <errno.h>
    

    maflcko commented at 1:23 pm on December 5, 2025:

    I see. I guess they could also be fixed. Either with a patch in iwyu, since it is already patched, or with modernize-deprecated-headers clang-tidy-diff, or with a stand-alone mapping script: ./ci/test/modernize-deprecated-headers.py $( git diff --name-only )

    For ref, the mapping is probably:

     0<assert.h>:<cassert>
     1<ctype.h>:<cctype>
     2<errno.h>:<cerrno>
     3<float.h>:<cfloat>
     4<limits.h>:<climits>
     5<locale.h>:<clocale>
     6<math.h>:<cmath>
     7<setjmp.h>:<csetjmp>
     8<signal.h>:<csignal>
     9<stdarg.h>:<cstdarg>
    10<stddef.h>:<cstddef>
    11<stdio.h>:<cstdio>
    12<stdlib.h>:<cstdlib>
    13<string.h>:<cstring>
    14<time.h>:<ctime>
    15<wchar.h>:<cwchar>
    16<wctype.h>:<cwctype>
    17<uchar.h>:<cuchar>
    18<inttypes.h>:<cinttypes>
    19<stdint.h>:<cstdint>
    
  39. hebasto force-pushed on Dec 5, 2025
  40. hebasto commented at 3:48 pm on December 5, 2025: member

    @maflcko

    Your suggestions have been taken. Thank you!

  41. in ci/test/01_base_install.sh:101 in 5bd57a7259
     95@@ -96,6 +96,34 @@ if [[ "${RUN_TIDY}" == "true" ]]; then
     96    }
     97    return "\"" + include_name + "\"";
     98 EOF
     99+  # Prefer C++ headers over C counterparts.
    100+  # See: https://github.com/include-what-you-use/include-what-you-use/blob/clang_21/iwyu_include_picker.cc#L587-L629.
    101+  sed -i "s|\"<assert.h>\", kPublic|\"<assert.h>\", kPrivate|g" /include-what-you-use/iwyu_include_picker.cc
    


    maflcko commented at 11:47 am on December 16, 2025:
    nit: may be easier to review and maintain by making this a patch?

    hebasto commented at 11:57 am on December 16, 2025:
    I’ve been thinking about this as well and decided to leave this decision for follow-ups, as maintaining consistency would require the same change in other patches.

    maflcko commented at 12:00 pm on December 16, 2025:

    Which patches? The only other patch around AddQuotes in the lines above should be independent and touches a file different from iwyu_include_picker.cc

    edit: The full patch would be:

      0diff --git a/iwyu_include_picker.cc b/iwyu_include_picker.cc
      1index a42aac5..1057694 100644
      2--- a/iwyu_include_picker.cc
      3+++ b/iwyu_include_picker.cc
      4@@ -100,20 +100,20 @@ const IncludeMapEntry libc_symbol_map[] = {
      5   // equal.  The visibility on the symbol-name is ignored; by convention
      6   // we always set it to kPrivate.
      7   { "_POSIX_VDISABLE", kPrivate, "<unistd.h>", kPublic },
      8-  { "abort", kPrivate, "<stdlib.h>", kPublic },
      9+  { "abort", kPrivate, "<stdlib.h>", kPrivate },
     10   { "aiocb", kPrivate, "<aio.h>", kPublic },
     11   { "blkcnt_t", kPrivate, "<sys/types.h>", kPublic },
     12   { "blksize_t", kPrivate, "<sys/types.h>", kPublic },
     13   { "cc_t", kPrivate, "<termios.h>", kPublic },
     14-  { "clock_t", kPrivate, "<time.h>", kPublic },
     15+  { "clock_t", kPrivate, "<time.h>", kPrivate },
     16   { "clock_t", kPrivate, "<sys/types.h>", kPublic },
     17   { "clockid_t", kPrivate, "<sys/types.h>", kPublic },
     18-  { "ctermid", kPrivate, "<stdio.h>", kPublic },
     19+  { "ctermid", kPrivate, "<stdio.h>", kPrivate },
     20   { "daddr_t", kPrivate, "<sys/types.h>", kPublic },
     21   { "dev_t", kPrivate, "<sys/types.h>", kPublic },
     22-  { "div_t", kPrivate, "<stdlib.h>", kPublic },
     23-  { "double_t", kPrivate, "<math.h>", kPublic },
     24-  { "error_t", kPrivate, "<errno.h>", kPublic },
     25+  { "div_t", kPrivate, "<stdlib.h>", kPrivate },
     26+  { "double_t", kPrivate, "<math.h>", kPrivate },
     27+  { "error_t", kPrivate, "<errno.h>", kPrivate },
     28   { "error_t", kPrivate, "<argp.h>", kPublic },
     29   { "error_t", kPrivate, "<argz.h>", kPublic },
     30   { "FD_CLR", kPrivate, "<sys/select.h>", kPublic },
     31@@ -122,10 +122,10 @@ const IncludeMapEntry libc_symbol_map[] = {
     32   { "fd_set", kPrivate, "<sys/select.h>", kPublic },
     33   { "FD_SETSIZE", kPrivate, "<sys/select.h>", kPublic },
     34   { "FD_ZERO", kPrivate, "<sys/select.h>", kPublic },
     35-  { "fenv_t", kPrivate, "<fenv.h>", kPublic },
     36-  { "fexcept_t", kPrivate, "<fenv.h>", kPublic },
     37-  { "FILE", kPrivate, "<stdio.h>", kPublic },
     38-  { "float_t", kPrivate, "<math.h>", kPublic },
     39+  { "fenv_t", kPrivate, "<fenv.h>", kPrivate },
     40+  { "fexcept_t", kPrivate, "<fenv.h>", kPrivate },
     41+  { "FILE", kPrivate, "<stdio.h>", kPrivate },
     42+  { "float_t", kPrivate, "<math.h>", kPrivate },
     43   { "fsblkcnt_t", kPrivate, "<sys/types.h>", kPublic },
     44   { "fsfilcnt_t", kPrivate, "<sys/types.h>", kPublic },
     45   { "getopt", kPrivate, "<unistd.h>", kPublic },
     46@@ -135,31 +135,31 @@ const IncludeMapEntry libc_symbol_map[] = {
     47   { "in_addr_t", kPrivate, "<netinet/in.h>", kPublic },
     48   { "in_port_t", kPrivate, "<netinet/in.h>", kPublic },
     49   { "id_t", kPrivate, "<sys/types.h>", kPublic },
     50-  { "imaxdiv_t", kPrivate, "<inttypes.h>", kPublic },
     51-  { "intmax_t", kPrivate, "<stdint.h>", kPublic },
     52-  { "uintmax_t", kPrivate, "<stdint.h>", kPublic },
     53+  { "imaxdiv_t", kPrivate, "<inttypes.h>", kPrivate },
     54+  { "intmax_t", kPrivate, "<stdint.h>", kPrivate },
     55+  { "uintmax_t", kPrivate, "<stdint.h>", kPrivate },
     56   { "ino64_t", kPrivate, "<sys/types.h>", kPublic },
     57   { "ino_t", kPrivate, "<sys/types.h>", kPublic },
     58-  { "int8_t", kPrivate, "<stdint.h>", kPublic },
     59-  { "int16_t", kPrivate, "<stdint.h>", kPublic },
     60-  { "int32_t", kPrivate, "<stdint.h>", kPublic },
     61-  { "int64_t", kPrivate, "<stdint.h>", kPublic },
     62-  { "uint8_t", kPrivate, "<stdint.h>", kPublic },
     63-  { "uint16_t", kPrivate, "<stdint.h>", kPublic },
     64-  { "uint32_t", kPrivate, "<stdint.h>", kPublic },
     65-  { "uint64_t", kPrivate, "<stdint.h>", kPublic },
     66-  { "intptr_t", kPrivate, "<stdint.h>", kPublic },
     67-  { "uintptr_t", kPrivate, "<stdint.h>", kPublic },
     68+  { "int8_t", kPrivate, "<stdint.h>", kPrivate },
     69+  { "int16_t", kPrivate, "<stdint.h>", kPrivate },
     70+  { "int32_t", kPrivate, "<stdint.h>", kPrivate },
     71+  { "int64_t", kPrivate, "<stdint.h>", kPrivate },
     72+  { "uint8_t", kPrivate, "<stdint.h>", kPrivate },
     73+  { "uint16_t", kPrivate, "<stdint.h>", kPrivate },
     74+  { "uint32_t", kPrivate, "<stdint.h>", kPrivate },
     75+  { "uint64_t", kPrivate, "<stdint.h>", kPrivate },
     76+  { "intptr_t", kPrivate, "<stdint.h>", kPrivate },
     77+  { "uintptr_t", kPrivate, "<stdint.h>", kPrivate },
     78   { "iovec", kPrivate, "<sys/uio.h>", kPublic },
     79-  { "itimerspec", kPrivate, "<time.h>", kPublic },
     80+  { "itimerspec", kPrivate, "<time.h>", kPrivate },
     81   { "key_t", kPrivate, "<sys/types.h>", kPublic },
     82-  { "L_ctermid", kPrivate, "<stdio.h>", kPublic },
     83-  { "lconv", kPrivate, "<locale.h>", kPublic },
     84-  { "ldiv_t", kPrivate, "<stdlib.h>", kPublic },
     85-  { "lldiv_t", kPrivate, "<stdlib.h>", kPublic },
     86-  { "locale_t", kPrivate, "<locale.h>", kPublic },
     87-  { "max_align_t", kPrivate, "<stddef.h>", kPublic },
     88-  { "mbstate_t", kPrivate, "<wchar.h>", kPublic },
     89+  { "L_ctermid", kPrivate, "<stdio.h>", kPrivate },
     90+  { "lconv", kPrivate, "<locale.h>", kPrivate },
     91+  { "ldiv_t", kPrivate, "<stdlib.h>", kPrivate },
     92+  { "lldiv_t", kPrivate, "<stdlib.h>", kPrivate },
     93+  { "locale_t", kPrivate, "<locale.h>", kPrivate },
     94+  { "max_align_t", kPrivate, "<stddef.h>", kPrivate },
     95+  { "mbstate_t", kPrivate, "<wchar.h>", kPrivate },
     96   { "mcontext_t", kPrivate, "<ucontext.h>", kPublic },
     97   { "mode_t", kPrivate, "<sys/types.h>", kPublic },
     98   { "nl_item", kPrivate, "<nl_types.h>", kPublic },
     99@@ -175,8 +175,8 @@ const IncludeMapEntry libc_symbol_map[] = {
    100   { "optind", kPrivate, "<unistd.h>", kPublic },
    101   { "optopt", kPrivate, "<unistd.h>", kPublic },
    102   { "pid_t", kPrivate, "<sys/types.h>", kPublic },
    103-  { "posix_memalign", kPrivate, "<stdlib.h>", kPublic },
    104-  { "printf", kPrivate, "<stdio.h>", kPublic },
    105+  { "posix_memalign", kPrivate, "<stdlib.h>", kPrivate },
    106+  { "printf", kPrivate, "<stdio.h>", kPrivate },
    107   { "pthread_attr_t", kPrivate, "<pthread.h>", kPublic },
    108   { "pthread_cond_t", kPrivate, "<pthread.h>", kPublic },
    109   { "pthread_condattr_t", kPrivate, "<pthread.h>", kPublic },
    110@@ -187,7 +187,7 @@ const IncludeMapEntry libc_symbol_map[] = {
    111   { "pthread_rwlock_t", kPrivate, "<pthread.h>", kPublic },
    112   { "pthread_rwlockattr_t", kPrivate, "<pthread.h>", kPublic },
    113   { "pthread_t", kPrivate, "<pthread.h>", kPublic },
    114-  { "ptrdiff_t", kPrivate, "<stddef.h>", kPublic },
    115+  { "ptrdiff_t", kPrivate, "<stddef.h>", kPrivate },
    116   { "regex_t", kPrivate, "<regex.h>", kPublic },
    117   { "regmatch_t", kPrivate, "<regex.h>", kPublic },
    118   { "regoff_t", kPrivate, "<regex.h>", kPublic },
    119@@ -218,51 +218,51 @@ const IncludeMapEntry libc_symbol_map[] = {
    120   { "SCHED_FIFO", kPrivate, "<sched.h>", kPublic },
    121   { "SCHED_OTHER", kPrivate, "<sched.h>", kPublic },
    122   { "SCHED_RR", kPrivate, "<sched.h>", kPublic },
    123-  { "SEEK_CUR", kPrivate, "<stdio.h>", kPublic },
    124-  { "SEEK_END", kPrivate, "<stdio.h>", kPublic },
    125-  { "SEEK_SET", kPrivate, "<stdio.h>", kPublic },
    126-  { "sig_atomic_t", kPrivate, "<signal.h>", kPublic },
    127-  { "sigevent", kPrivate, "<signal.h>", kPublic },
    128-  { "siginfo_t", kPrivate, "<signal.h>", kPublic },
    129-  { "sigset_t", kPrivate, "<signal.h>", kPublic },
    130-  { "sigval", kPrivate, "<signal.h>", kPublic },
    131+  { "SEEK_CUR", kPrivate, "<stdio.h>", kPrivate },
    132+  { "SEEK_END", kPrivate, "<stdio.h>", kPrivate },
    133+  { "SEEK_SET", kPrivate, "<stdio.h>", kPrivate },
    134+  { "sig_atomic_t", kPrivate, "<signal.h>", kPrivate },
    135+  { "sigevent", kPrivate, "<signal.h>", kPrivate },
    136+  { "siginfo_t", kPrivate, "<signal.h>", kPrivate },
    137+  { "sigset_t", kPrivate, "<signal.h>", kPrivate },
    138+  { "sigval", kPrivate, "<signal.h>", kPrivate },
    139   { "sockaddr", kPrivate, "<sys/socket.h>", kPublic },
    140   { "socklen_t", kPrivate, "<sys/socket.h>", kPublic },
    141   { "ssize_t", kPrivate, "<sys/types.h>", kPublic },
    142-  { "stack_t", kPrivate, "<signal.h>", kPublic },
    143+  { "stack_t", kPrivate, "<signal.h>", kPrivate },
    144   { "stat", kPrivate, "<sys/stat.h>", kPublic },
    145   { "suseconds_t", kPrivate, "<sys/types.h>", kPublic },
    146-  { "time_t", kPrivate, "<time.h>", kPublic },
    147+  { "time_t", kPrivate, "<time.h>", kPrivate },
    148   { "time_t", kPrivate, "<sys/types.h>", kPublic },
    149   { "timer_t", kPrivate, "<sys/types.h>", kPublic },
    150-  { "timespec", kPrivate, "<time.h>", kPublic },
    151+  { "timespec", kPrivate, "<time.h>", kPrivate },
    152   { "timeval", kPrivate, "<sys/time.h>", kPublic },
    153-  { "tm", kPrivate, "<time.h>", kPublic },
    154+  { "tm", kPrivate, "<time.h>", kPrivate },
    155   { "u_char", kPrivate, "<sys/types.h>", kPublic },
    156   { "ucontext_t", kPrivate, "<ucontext.h>", kPublic },
    157   { "uid_t", kPrivate, "<sys/types.h>", kPublic },
    158   { "useconds_t", kPrivate, "<sys/types.h>", kPublic },
    159-  { "wchar_t", kPrivate, "<stddef.h>", kPublic },
    160-  { "wctrans_t", kPrivate, "<wctype.h>", kPublic },
    161-  { "wctype_t", kPrivate, "<wctype.h>", kPublic },
    162+  { "wchar_t", kPrivate, "<stddef.h>", kPrivate },
    163+  { "wctrans_t", kPrivate, "<wctype.h>", kPrivate },
    164+  { "wctype_t", kPrivate, "<wctype.h>", kPrivate },
    165   { "winsize", kPrivate, "<termios.h>", kPublic },
    166-  { "wint_t", kPrivate, "<wchar.h>", kPublic },
    167+  { "wint_t", kPrivate, "<wchar.h>", kPrivate },
    168   // It is unspecified if the cname headers provide ::size_t.
    169   // <locale.h> is the one header which defines NULL but not size_t.
    170-  { "size_t", kPrivate, "<stddef.h>", kPublic },  // 'canonical' location for size_t
    171-  { "size_t", kPrivate, "<signal.h>", kPublic },
    172-  { "size_t", kPrivate, "<stdio.h>", kPublic },
    173-  { "size_t", kPrivate, "<stdlib.h>", kPublic },
    174-  { "size_t", kPrivate, "<string.h>", kPublic },
    175-  { "size_t", kPrivate, "<time.h>", kPublic },
    176-  { "size_t", kPrivate, "<uchar.h>", kPublic },
    177-  { "size_t", kPrivate, "<wchar.h>", kPublic },
    178+  { "size_t", kPrivate, "<stddef.h>", kPrivate },  // 'canonical' location for size_t
    179+  { "size_t", kPrivate, "<signal.h>", kPrivate },
    180+  { "size_t", kPrivate, "<stdio.h>", kPrivate },
    181+  { "size_t", kPrivate, "<stdlib.h>", kPrivate },
    182+  { "size_t", kPrivate, "<string.h>", kPrivate },
    183+  { "size_t", kPrivate, "<time.h>", kPrivate },
    184+  { "size_t", kPrivate, "<uchar.h>", kPrivate },
    185+  { "size_t", kPrivate, "<wchar.h>", kPrivate },
    186   // Macros that can be defined in more than one file, don't have the
    187   // same __foo_defined guard that other types do, so the grep above
    188   // doesn't discover them.  Until I figure out a better way, I just
    189   // add them in by hand as I discover them.
    190-  { "EOF", kPrivate, "<stdio.h>", kPublic },
    191-  { "FILE", kPrivate, "<stdio.h>", kPublic },
    192+  { "EOF", kPrivate, "<stdio.h>", kPrivate },
    193+  { "FILE", kPrivate, "<stdio.h>", kPrivate },
    194   { "IBSHIFT", kPrivate, "<asm/termbits.h>", kPublic },
    195   { "MAP_POPULATE", kPrivate, "<sys/mman.h>", kPublic },
    196   { "MAP_POPULATE", kPrivate, "<linux/mman.h>", kPublic },
    197@@ -270,22 +270,22 @@ const IncludeMapEntry libc_symbol_map[] = {
    198   { "MAP_STACK", kPrivate, "<linux/mman.h>", kPublic },
    199   { "MAXHOSTNAMELEN", kPrivate, "<sys/param.h>", kPublic },
    200   { "MAXHOSTNAMELEN", kPrivate, "<protocols/timed.h>", kPublic },
    201-  { "SIGABRT", kPrivate, "<signal.h>", kPublic },
    202-  { "SIGCHLD", kPrivate, "<signal.h>", kPublic },
    203-  { "va_arg", kPrivate, "<stdarg.h>", kPublic },
    204-  { "va_copy", kPrivate, "<stdarg.h>", kPublic },
    205-  { "va_end", kPrivate, "<stdarg.h>", kPublic },
    206-  { "va_list", kPrivate, "<stdarg.h>", kPublic },
    207-  { "va_start", kPrivate, "<stdarg.h>", kPublic },
    208-  { "WEOF", kPrivate, "<wchar.h>", kPublic },
    209+  { "SIGABRT", kPrivate, "<signal.h>", kPrivate },
    210+  { "SIGCHLD", kPrivate, "<signal.h>", kPrivate },
    211+  { "va_arg", kPrivate, "<stdarg.h>", kPrivate },
    212+  { "va_copy", kPrivate, "<stdarg.h>", kPrivate },
    213+  { "va_end", kPrivate, "<stdarg.h>", kPrivate },
    214+  { "va_list", kPrivate, "<stdarg.h>", kPrivate },
    215+  { "va_start", kPrivate, "<stdarg.h>", kPrivate },
    216+  { "WEOF", kPrivate, "<wchar.h>", kPrivate },
    217   // These are symbols that could be defined in either stdlib.h or
    218   // malloc.h, but we always want the stdlib location.
    219-  { "malloc", kPrivate, "<stdlib.h>", kPublic },
    220-  { "calloc", kPrivate, "<stdlib.h>", kPublic },
    221-  { "realloc", kPrivate, "<stdlib.h>", kPublic },
    222-  { "free", kPrivate, "<stdlib.h>", kPublic },
    223+  { "malloc", kPrivate, "<stdlib.h>", kPrivate },
    224+  { "calloc", kPrivate, "<stdlib.h>", kPrivate },
    225+  { "realloc", kPrivate, "<stdlib.h>", kPrivate },
    226+  { "free", kPrivate, "<stdlib.h>", kPrivate },
    227   // Entries for NULL
    228-  { "NULL", kPrivate, "<stddef.h>", kPublic },  // 'canonical' location for NULL
    229+  { "NULL", kPrivate, "<stddef.h>", kPrivate },  // 'canonical' location for NULL
    230   { "NULL", kPrivate, "<clocale>", kPublic },
    231   { "NULL", kPrivate, "<cstddef>", kPublic },
    232   { "NULL", kPrivate, "<cstdio>", kPublic },
    233@@ -293,13 +293,13 @@ const IncludeMapEntry libc_symbol_map[] = {
    234   { "NULL", kPrivate, "<cstring>", kPublic },
    235   { "NULL", kPrivate, "<ctime>", kPublic },
    236   { "NULL", kPrivate, "<cwchar>", kPublic },
    237-  { "NULL", kPrivate, "<locale.h>", kPublic },
    238-  { "NULL", kPrivate, "<stdio.h>", kPublic },
    239-  { "NULL", kPrivate, "<stdlib.h>", kPublic },
    240-  { "NULL", kPrivate, "<string.h>", kPublic },
    241-  { "NULL", kPrivate, "<time.h>", kPublic },
    242-  { "NULL", kPrivate, "<wchar.h>", kPublic },
    243-  { "offsetof", kPrivate, "<stddef.h>", kPublic },
    244+  { "NULL", kPrivate, "<locale.h>", kPrivate },
    245+  { "NULL", kPrivate, "<stdio.h>", kPrivate },
    246+  { "NULL", kPrivate, "<stdlib.h>", kPrivate },
    247+  { "NULL", kPrivate, "<string.h>", kPrivate },
    248+  { "NULL", kPrivate, "<time.h>", kPrivate },
    249+  { "NULL", kPrivate, "<wchar.h>", kPrivate },
    250+  { "offsetof", kPrivate, "<stddef.h>", kPrivate },
    251 };
    252 
    253 // Common kludges for C++ standard libraries
    254@@ -357,7 +357,7 @@ const IncludeMapEntry libc_include_map[] = {
    255   { "<bits/a.out.h>", kPrivate, "<a.out.h>", kPublic },
    256   { "<bits/auxv.h>", kPrivate, "<sys/auxv.h>", kPublic },
    257   { "<bits/byteswap.h>", kPrivate, "<byteswap.h>", kPublic },
    258-  { "<bits/cmathcalls.h>", kPrivate, "<complex.h>", kPublic },
    259+  { "<bits/cmathcalls.h>", kPrivate, "<complex.h>", kPrivate },
    260   { "<bits/confname.h>", kPrivate, "<unistd.h>", kPublic },
    261   { "<bits/dirent.h>", kPrivate, "<dirent.h>", kPublic },
    262   { "<bits/dlfcn.h>", kPrivate, "<dlfcn.h>", kPublic },
    263@@ -365,18 +365,18 @@ const IncludeMapEntry libc_include_map[] = {
    264   { "<bits/endian.h>", kPrivate, "<endian.h>", kPublic },
    265   { "<bits/environments.h>", kPrivate, "<unistd.h>", kPublic },
    266   { "<bits/epoll.h>", kPrivate, "<sys/epoll.h>", kPublic },
    267-  { "<bits/errno.h>", kPrivate, "<errno.h>", kPublic },
    268+  { "<bits/errno.h>", kPrivate, "<errno.h>", kPrivate },
    269   { "<bits/error.h>", kPrivate, "<error.h>", kPublic },
    270   { "<bits/eventfd.h>", kPrivate, "<sys/eventfd.h>", kPublic },
    271   { "<bits/fcntl.h>", kPrivate, "<fcntl.h>", kPublic },
    272   { "<bits/fcntl2.h>", kPrivate, "<fcntl.h>", kPublic },
    273-  { "<bits/fenv.h>", kPrivate, "<fenv.h>", kPublic },
    274-  { "<bits/fenvinline.h>", kPrivate, "<fenv.h>", kPublic },
    275-  { "<bits/huge_val.h>", kPrivate, "<math.h>", kPublic },
    276-  { "<bits/huge_valf.h>", kPrivate, "<math.h>", kPublic },
    277-  { "<bits/huge_vall.h>", kPrivate, "<math.h>", kPublic },
    278+  { "<bits/fenv.h>", kPrivate, "<fenv.h>", kPrivate },
    279+  { "<bits/fenvinline.h>", kPrivate, "<fenv.h>", kPrivate },
    280+  { "<bits/huge_val.h>", kPrivate, "<math.h>", kPrivate },
    281+  { "<bits/huge_valf.h>", kPrivate, "<math.h>", kPrivate },
    282+  { "<bits/huge_vall.h>", kPrivate, "<math.h>", kPrivate },
    283   { "<bits/hwcap.h>", kPrivate, "<sys/auxv.h>", kPublic },
    284-  { "<bits/inf.h>", kPrivate, "<math.h>", kPublic },
    285+  { "<bits/inf.h>", kPrivate, "<math.h>", kPrivate },
    286   { "<bits/inotify.h>", kPrivate, "<sys/inotify.h>", kPublic },
    287   { "<bits/ioctl-types.h>", kPrivate, "<sys/ioctl.h>", kPublic },
    288   { "<bits/ioctls.h>", kPrivate, "<sys/ioctl.h>", kPublic },
    289@@ -384,24 +384,24 @@ const IncludeMapEntry libc_include_map[] = {
    290   { "<bits/ipctypes.h>", kPrivate, "<sys/ipc.h>", kPublic },
    291   { "<bits/libio-ldbl.h>", kPrivate, "<libio.h>", kPublic },
    292   { "<bits/link.h>", kPrivate, "<link.h>", kPublic },
    293-  { "<bits/locale.h>", kPrivate, "<locale.h>", kPublic },
    294-  { "<bits/math-finite.h>", kPrivate, "<math.h>", kPublic },
    295-  { "<bits/mathcalls.h>", kPrivate, "<math.h>", kPublic },
    296-  { "<bits/mathdef.h>", kPrivate, "<math.h>", kPublic },
    297-  { "<bits/mathinline.h>", kPrivate, "<math.h>", kPublic },
    298+  { "<bits/locale.h>", kPrivate, "<locale.h>", kPrivate },
    299+  { "<bits/math-finite.h>", kPrivate, "<math.h>", kPrivate },
    300+  { "<bits/mathcalls.h>", kPrivate, "<math.h>", kPrivate },
    301+  { "<bits/mathdef.h>", kPrivate, "<math.h>", kPrivate },
    302+  { "<bits/mathinline.h>", kPrivate, "<math.h>", kPrivate },
    303   { "<bits/mman.h>", kPrivate, "<sys/mman.h>", kPublic },
    304   { "<bits/mman-shared.h>", kPrivate, "<sys/mman.h>", kPublic },
    305   { "<bits/monetary-ldbl.h>", kPrivate, "<monetary.h>", kPublic },
    306   { "<bits/mqueue.h>", kPrivate, "<mqueue.h>", kPublic },
    307   { "<bits/mqueue2.h>", kPrivate, "<mqueue.h>", kPublic },
    308   { "<bits/msq.h>", kPrivate, "<sys/msg.h>", kPublic },
    309-  { "<bits/nan.h>", kPrivate, "<math.h>", kPublic },
    310+  { "<bits/nan.h>", kPrivate, "<math.h>", kPrivate },
    311   { "<bits/netdb.h>", kPrivate, "<netdb.h>", kPublic },
    312   { "<bits/param.h>", kPrivate, "<sys/param.h>", kPublic },
    313   { "<bits/poll.h>", kPrivate, "<sys/poll.h>", kPrivate },
    314   { "<bits/poll2.h>", kPrivate, "<sys/poll.h>", kPrivate },
    315-  { "<bits/posix1_lim.h>", kPrivate, "<limits.h>", kPublic },
    316-  { "<bits/posix2_lim.h>", kPrivate, "<limits.h>", kPublic },
    317+  { "<bits/posix1_lim.h>", kPrivate, "<limits.h>", kPrivate },
    318+  { "<bits/posix2_lim.h>", kPrivate, "<limits.h>", kPrivate },
    319   { "<bits/posix_opt.h>", kPrivate, "<unistd.h>", kPublic },
    320   { "<bits/printf-ldbl.h>", kPrivate, "<printf.h>", kPublic },
    321   { "<bits/pthreadtypes.h>", kPrivate, "<pthread.h>", kPublic },
    322@@ -411,17 +411,17 @@ const IncludeMapEntry libc_include_map[] = {
    323   { "<bits/select2.h>", kPrivate, "<sys/select.h>", kPublic },
    324   { "<bits/sem.h>", kPrivate, "<sys/sem.h>", kPublic },
    325   { "<bits/semaphore.h>", kPrivate, "<semaphore.h>", kPublic },
    326-  { "<bits/setjmp.h>", kPrivate, "<setjmp.h>", kPublic },
    327-  { "<bits/setjmp2.h>", kPrivate, "<setjmp.h>", kPublic },
    328+  { "<bits/setjmp.h>", kPrivate, "<setjmp.h>", kPrivate },
    329+  { "<bits/setjmp2.h>", kPrivate, "<setjmp.h>", kPrivate },
    330   { "<bits/shm.h>", kPrivate, "<sys/shm.h>", kPublic },
    331-  { "<bits/sigaction.h>", kPrivate, "<signal.h>", kPublic },
    332-  { "<bits/sigcontext.h>", kPrivate, "<signal.h>", kPublic },
    333-  { "<bits/siginfo.h>", kPrivate, "<signal.h>", kPublic },
    334-  { "<bits/signum.h>", kPrivate, "<signal.h>", kPublic },
    335-  { "<bits/signum-arch.h>", kPrivate, "<signal.h>", kPublic },
    336-  { "<bits/sigset.h>", kPrivate, "<signal.h>", kPublic },
    337-  { "<bits/sigstack.h>", kPrivate, "<signal.h>", kPublic },
    338-  { "<bits/sigthread.h>", kPrivate, "<signal.h>", kPublic },
    339+  { "<bits/sigaction.h>", kPrivate, "<signal.h>", kPrivate },
    340+  { "<bits/sigcontext.h>", kPrivate, "<signal.h>", kPrivate },
    341+  { "<bits/siginfo.h>", kPrivate, "<signal.h>", kPrivate },
    342+  { "<bits/signum.h>", kPrivate, "<signal.h>", kPrivate },
    343+  { "<bits/signum-arch.h>", kPrivate, "<signal.h>", kPrivate },
    344+  { "<bits/sigset.h>", kPrivate, "<signal.h>", kPrivate },
    345+  { "<bits/sigstack.h>", kPrivate, "<signal.h>", kPrivate },
    346+  { "<bits/sigthread.h>", kPrivate, "<signal.h>", kPrivate },
    347   { "<bits/sockaddr.h>", kPrivate, "<sys/un.h>", kPublic },
    348   { "<bits/socket.h>", kPrivate, "<sys/socket.h>", kPublic },
    349   { "<bits/socket2.h>", kPrivate, "<sys/socket.h>", kPublic },
    350@@ -431,22 +431,22 @@ const IncludeMapEntry libc_include_map[] = {
    351   { "<bits/statfs.h>", kPrivate, "<sys/statfs.h>", kPublic },
    352   { "<bits/statvfs.h>", kPrivate, "<sys/statvfs.h>", kPublic },
    353   { "<bits/statx-generic.h>", kPrivate, "<sys/stat.h>", kPublic },
    354-  { "<bits/stdio-ldbl.h>", kPrivate, "<stdio.h>", kPublic },
    355+  { "<bits/stdio-ldbl.h>", kPrivate, "<stdio.h>", kPrivate },
    356   { "<bits/stdio-lock.h>", kPrivate, "<libio.h>", kPublic },
    357-  { "<bits/stdio.h>", kPrivate, "<stdio.h>", kPublic },
    358-  { "<bits/stdio2.h>", kPrivate, "<stdio.h>", kPublic },
    359-  { "<bits/stdio_lim.h>", kPrivate, "<stdio.h>", kPublic },
    360-  { "<bits/stdlib-bsearch.h>", kPrivate, "<stdlib.h>", kPublic },
    361-  { "<bits/stdlib-float.h>", kPrivate, "<stdlib.h>", kPublic },
    362-  { "<bits/stdlib-ldbl.h>", kPrivate, "<stdlib.h>", kPublic },
    363-  { "<bits/stdlib.h>", kPrivate, "<stdlib.h>", kPublic },
    364-  { "<bits/string.h>", kPrivate, "<string.h>", kPublic },
    365-  { "<bits/string2.h>", kPrivate, "<string.h>", kPublic },
    366-  { "<bits/string3.h>", kPrivate, "<string.h>", kPublic },
    367+  { "<bits/stdio.h>", kPrivate, "<stdio.h>", kPrivate },
    368+  { "<bits/stdio2.h>", kPrivate, "<stdio.h>", kPrivate },
    369+  { "<bits/stdio_lim.h>", kPrivate, "<stdio.h>", kPrivate },
    370+  { "<bits/stdlib-bsearch.h>", kPrivate, "<stdlib.h>", kPrivate },
    371+  { "<bits/stdlib-float.h>", kPrivate, "<stdlib.h>", kPrivate },
    372+  { "<bits/stdlib-ldbl.h>", kPrivate, "<stdlib.h>", kPrivate },
    373+  { "<bits/stdlib.h>", kPrivate, "<stdlib.h>", kPrivate },
    374+  { "<bits/string.h>", kPrivate, "<string.h>", kPrivate },
    375+  { "<bits/string2.h>", kPrivate, "<string.h>", kPrivate },
    376+  { "<bits/string3.h>", kPrivate, "<string.h>", kPrivate },
    377   { "<bits/stropts.h>", kPrivate, "<stropts.h>", kPublic },
    378   { "<bits/struct_stat.h>", kPrivate, "<sys/stat.h>", kPublic },
    379   { "<bits/struct_stat.h>", kPrivate, "<ftw.h>", kPublic },
    380-  { "<bits/sys_errlist.h>", kPrivate, "<stdio.h>", kPublic },
    381+  { "<bits/sys_errlist.h>", kPrivate, "<stdio.h>", kPrivate },
    382   { "<bits/syscall.h>", kPrivate, "<sys/syscall.h>", kPublic },
    383   { "<bits/sysctl.h>", kPrivate, "<sys/sysctl.h>", kPublic },
    384   { "<bits/syslog-ldbl.h>", kPrivate, "<sys/syslog.h>", kPrivate },
    385@@ -461,12 +461,12 @@ const IncludeMapEntry libc_include_map[] = {
    386   { "<bits/termios-struct.h>", kPrivate, "<termios.h>", kPublic },
    387   { "<bits/termios-tcflow.h>", kPrivate, "<termios.h>", kPublic },
    388   { "<bits/termios.h>", kPrivate, "<termios.h>", kPublic },
    389-  { "<bits/time.h>", kPrivate, "<time.h>", kPublic },
    390+  { "<bits/time.h>", kPrivate, "<time.h>", kPrivate },
    391   { "<bits/time.h>", kPrivate, "<sys/time.h>", kPublic },
    392   { "<bits/timerfd.h>", kPrivate, "<sys/timerfd.h>", kPublic },
    393   { "<bits/timex.h>", kPrivate, "<sys/timex.h>", kPublic },
    394   { "<bits/types.h>", kPrivate, "<sys/types.h>", kPublic },
    395-  { "<bits/types/siginfo_t.h>", kPrivate, "<signal.h>", kPublic },
    396+  { "<bits/types/siginfo_t.h>", kPrivate, "<signal.h>", kPrivate },
    397   { "<bits/types/siginfo_t.h>", kPrivate, "<sys/wait.h>", kPublic },
    398   { "<bits/uio.h>", kPrivate, "<sys/uio.h>", kPublic },
    399   { "<bits/unistd.h>", kPrivate, "<unistd.h>", kPublic },
    400@@ -476,11 +476,11 @@ const IncludeMapEntry libc_include_map[] = {
    401   { "<bits/utsname.h>", kPrivate, "<sys/utsname.h>", kPublic },
    402   { "<bits/waitflags.h>", kPrivate, "<sys/wait.h>", kPublic },
    403   { "<bits/waitstatus.h>", kPrivate, "<sys/wait.h>", kPublic },
    404-  { "<bits/wchar-ldbl.h>", kPrivate, "<wchar.h>", kPublic },
    405-  { "<bits/wchar.h>", kPrivate, "<wchar.h>", kPublic },
    406-  { "<bits/wchar2.h>", kPrivate, "<wchar.h>", kPublic },
    407-  { "<bits/wordsize.h>", kPrivate, "<limits.h>", kPublic },
    408-  { "<bits/xopen_lim.h>", kPrivate, "<limits.h>", kPublic },
    409+  { "<bits/wchar-ldbl.h>", kPrivate, "<wchar.h>", kPrivate },
    410+  { "<bits/wchar.h>", kPrivate, "<wchar.h>", kPrivate },
    411+  { "<bits/wchar2.h>", kPrivate, "<wchar.h>", kPrivate },
    412+  { "<bits/wordsize.h>", kPrivate, "<limits.h>", kPrivate },
    413+  { "<bits/xopen_lim.h>", kPrivate, "<limits.h>", kPrivate },
    414   { "<bits/xtitypes.h>", kPrivate, "<stropts.h>", kPublic },
    415   // Sometimes libc tells you what mapping to do via an '#error':
    416   // # error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
    417@@ -490,7 +490,7 @@ const IncludeMapEntry libc_include_map[] = {
    418   { "<bits/a.out.h>", kPrivate, "<a.out.h>", kPublic },
    419   { "<bits/byteswap-16.h>", kPrivate, "<byteswap.h>", kPublic },
    420   { "<bits/byteswap.h>", kPrivate, "<byteswap.h>", kPublic },
    421-  { "<bits/cmathcalls.h>", kPrivate, "<complex.h>", kPublic },
    422+  { "<bits/cmathcalls.h>", kPrivate, "<complex.h>", kPrivate },
    423   { "<bits/confname.h>", kPrivate, "<unistd.h>", kPublic },
    424   { "<bits/dirent.h>", kPrivate, "<dirent.h>", kPublic },
    425   { "<bits/dlfcn.h>", kPrivate, "<dlfcn.h>", kPublic },
    426@@ -500,38 +500,38 @@ const IncludeMapEntry libc_include_map[] = {
    427   { "<bits/eventfd.h>", kPrivate, "<sys/eventfd.h>", kPublic },
    428   { "<bits/fcntl-linux.h>", kPrivate, "<fcntl.h>", kPublic },
    429   { "<bits/fcntl.h>", kPrivate, "<fcntl.h>", kPublic },
    430-  { "<bits/fenv.h>", kPrivate, "<fenv.h>", kPublic },
    431-  { "<bits/huge_val.h>", kPrivate, "<math.h>", kPublic },
    432-  { "<bits/huge_valf.h>", kPrivate, "<math.h>", kPublic },
    433-  { "<bits/huge_vall.h>", kPrivate, "<math.h>", kPublic },
    434+  { "<bits/fenv.h>", kPrivate, "<fenv.h>", kPrivate },
    435+  { "<bits/huge_val.h>", kPrivate, "<math.h>", kPrivate },
    436+  { "<bits/huge_valf.h>", kPrivate, "<math.h>", kPrivate },
    437+  { "<bits/huge_vall.h>", kPrivate, "<math.h>", kPrivate },
    438   { "<bits/in.h>", kPrivate, "<netinet/in.h>", kPublic },
    439-  { "<bits/inf.h>", kPrivate, "<math.h>", kPublic },
    440+  { "<bits/inf.h>", kPrivate, "<math.h>", kPrivate },
    441   { "<bits/inotify.h>", kPrivate, "<sys/inotify.h>", kPublic },
    442   { "<bits/ioctl-types.h>", kPrivate, "<sys/ioctl.h>", kPublic },
    443   { "<bits/ioctls.h>", kPrivate, "<sys/ioctl.h>", kPublic },
    444   { "<bits/ipc.h>", kPrivate, "<sys/ipc.h>", kPublic },
    445   { "<bits/ipctypes.h>", kPrivate, "<sys/ipc.h>", kPublic },
    446-  { "<bits/locale.h>", kPrivate, "<locale.h>", kPublic },
    447-  { "<bits/math-finite.h>", kPrivate, "<math.h>", kPublic },
    448-  { "<bits/mathdef.h>", kPrivate, "<math.h>", kPublic },
    449-  { "<bits/mathinline.h>", kPrivate, "<math.h>", kPublic },
    450+  { "<bits/locale.h>", kPrivate, "<locale.h>", kPrivate },
    451+  { "<bits/math-finite.h>", kPrivate, "<math.h>", kPrivate },
    452+  { "<bits/mathdef.h>", kPrivate, "<math.h>", kPrivate },
    453+  { "<bits/mathinline.h>", kPrivate, "<math.h>", kPrivate },
    454   { "<bits/mman-linux.h>", kPrivate, "<sys/mman.h>", kPublic },
    455   { "<bits/mman.h>", kPrivate, "<sys/mman.h>", kPublic },
    456   { "<bits/mqueue.h>", kPrivate, "<mqueue.h>", kPublic },
    457   { "<bits/msq.h>", kPrivate, "<sys/msg.h>", kPublic },
    458-  { "<bits/nan.h>", kPrivate, "<math.h>", kPublic },
    459+  { "<bits/nan.h>", kPrivate, "<math.h>", kPrivate },
    460   { "<bits/param.h>", kPrivate, "<sys/param.h>", kPublic },
    461   { "<bits/poll.h>", kPrivate, "<sys/poll.h>", kPrivate },
    462   { "<bits/predefs.h>", kPrivate, "<features.h>", kPublic },
    463   { "<bits/resource.h>", kPrivate, "<sys/resource.h>", kPublic },
    464   { "<bits/select.h>", kPrivate, "<sys/select.h>", kPublic },
    465   { "<bits/semaphore.h>", kPrivate, "<semaphore.h>", kPublic },
    466-  { "<bits/sigcontext.h>", kPrivate, "<signal.h>", kPublic },
    467+  { "<bits/sigcontext.h>", kPrivate, "<signal.h>", kPrivate },
    468   { "<bits/signalfd.h>", kPrivate, "<sys/signalfd.h>", kPublic },
    469-  { "<bits/stdlib-float.h>", kPrivate, "<stdlib.h>", kPublic },
    470-  { "<bits/string.h>", kPrivate, "<string.h>", kPublic },
    471-  { "<bits/string2.h>", kPrivate, "<string.h>", kPublic },
    472-  { "<bits/string3.h>", kPrivate, "<string.h>", kPublic },
    473+  { "<bits/stdlib-float.h>", kPrivate, "<stdlib.h>", kPrivate },
    474+  { "<bits/string.h>", kPrivate, "<string.h>", kPrivate },
    475+  { "<bits/string2.h>", kPrivate, "<string.h>", kPrivate },
    476+  { "<bits/string3.h>", kPrivate, "<string.h>", kPrivate },
    477   { "<bits/timerfd.h>", kPrivate, "<sys/timerfd.h>", kPublic },
    478   { "<bits/typesizes.h>", kPrivate, "<sys/types.h>", kPublic },
    479   // Top-level #includes that just forward to another file:
    480@@ -543,13 +543,13 @@ const IncludeMapEntry libc_include_map[] = {
    481   // on the POSIX.1-2024 list, I just choose the top-level one.
    482   { "<sys/aio.h>", kPrivate, "<aio.h>", kPublic },
    483   { "<sys/dirent.h>", kPrivate, "<dirent.h>", kPublic },
    484-  { "<sys/errno.h>", kPrivate, "<errno.h>", kPublic },
    485+  { "<sys/errno.h>", kPrivate, "<errno.h>", kPrivate },
    486   { "<sys/fcntl.h>", kPrivate, "<fcntl.h>", kPublic },
    487   { "<sys/poll.h>", kPrivate, "<poll.h>", kPublic },
    488   { "<sys/semaphore.h>", kPrivate, "<semaphore.h>", kPublic },
    489-  { "<sys/signal.h>", kPrivate, "<signal.h>", kPublic },
    490+  { "<sys/signal.h>", kPrivate, "<signal.h>", kPrivate },
    491   { "<sys/spawn.h>", kPrivate, "<spawn.h>", kPublic },
    492-  { "<sys/stdio.h>", kPrivate, "<stdio.h>", kPublic },
    493+  { "<sys/stdio.h>", kPrivate, "<stdio.h>", kPrivate },
    494   { "<sys/syslog.h>", kPrivate, "<syslog.h>", kPublic },
    495   { "<sys/termios.h>", kPrivate, "<termios.h>", kPublic },
    496   { "<sys/unistd.h>", kPrivate, "<unistd.h>", kPublic },
    497@@ -569,21 +569,21 @@ const IncludeMapEntry libc_include_map[] = {
    498   { "<asm/unistd_64.h>", kPrivate, "<asm/unistd.h>", kPrivate },
    499   // I don't know what grep would have found these.  I found them
    500   // via user report.
    501-  { "<asm/errno.h>", kPrivate, "<errno.h>", kPublic },
    502-  { "<asm/errno-base.h>", kPrivate, "<errno.h>", kPublic },
    503+  { "<asm/errno.h>", kPrivate, "<errno.h>", kPrivate },
    504+  { "<asm/errno-base.h>", kPrivate, "<errno.h>", kPrivate },
    505   { "<asm/ptrace-abi.h>", kPrivate, "<asm/ptrace.h>", kPublic },
    506   { "<asm/unistd.h>", kPrivate, "<sys/syscall.h>", kPublic },
    507-  { "<linux/limits.h>", kPrivate, "<limits.h>", kPublic },   // PATH_MAX
    508+  { "<linux/limits.h>", kPrivate, "<limits.h>", kPrivate },   // PATH_MAX
    509   { "<linux/prctl.h>", kPrivate, "<sys/prctl.h>", kPublic },
    510   { "<sys/ucontext.h>", kPrivate, "<ucontext.h>", kPublic },
    511   // System headers available on AIX, BSD, Solaris and other Unix systems
    512   { "<sys/dtrace.h>", kPrivate, "<dtrace.h>", kPublic },
    513   { "<sys/paths.h>", kPrivate, "<paths.h>", kPublic },
    514-  { "<sys/syslimits.h>", kPrivate, "<limits.h>", kPublic },
    515+  { "<sys/syslimits.h>", kPrivate, "<limits.h>", kPrivate },
    516   { "<sys/ttycom.h>", kPrivate, "<sys/ioctl.h>", kPublic },
    517   { "<sys/ustat.h>", kPrivate, "<ustat.h>", kPublic },
    518   // Exports guaranteed by the C standard
    519-  { "<stdint.h>", kPublic, "<inttypes.h>", kPublic },
    520+  { "<stdint.h>", kPrivate, "<inttypes.h>", kPrivate },
    521 };
    522 
    523 const IncludeMapEntry stdlib_c_include_map[] = {
    524@@ -603,31 +603,31 @@ const IncludeMapEntry stdlib_c_include_map[] = {
    525   //
    526   // $ curl -s -N https://raw.githubusercontent.com/cplusplus/draft/c%2B%2B20/source/lib-intro.tex | sed -n '/begin{multicolfloattable}.*{headers.cpp.c}/,/end{multicolfloattable}/p' | grep tcode | perl -nle 'm/tcode{<c(.*)>}/ && print qq@  { "<$1.h>", kPublic, "<c$1>", kPublic },@' | sort
    527   { "<assert.h>", kPublic, "<cassert>", kPublic },
    528-  { "<complex.h>", kPublic, "<ccomplex>", kPublic },
    529-  { "<ctype.h>", kPublic, "<cctype>", kPublic },
    530-  { "<errno.h>", kPublic, "<cerrno>", kPublic },
    531-  { "<fenv.h>", kPublic, "<cfenv>", kPublic },
    532-  { "<float.h>", kPublic, "<cfloat>", kPublic },
    533-  { "<inttypes.h>", kPublic, "<cinttypes>", kPublic },
    534-  { "<iso646.h>", kPublic, "<ciso646>", kPublic },
    535-  { "<limits.h>", kPublic, "<climits>", kPublic },
    536-  { "<locale.h>", kPublic, "<clocale>", kPublic },
    537-  { "<math.h>", kPublic, "<cmath>", kPublic },
    538-  { "<setjmp.h>", kPublic, "<csetjmp>", kPublic },
    539-  { "<signal.h>", kPublic, "<csignal>", kPublic },
    540-  { "<stdalign.h>", kPublic, "<cstdalign>", kPublic },
    541-  { "<stdarg.h>", kPublic, "<cstdarg>", kPublic },
    542-  { "<stdbool.h>", kPublic, "<cstdbool>", kPublic },
    543-  { "<stddef.h>", kPublic, "<cstddef>", kPublic },
    544-  { "<stdint.h>", kPublic, "<cstdint>", kPublic },
    545-  { "<stdio.h>", kPublic, "<cstdio>", kPublic },
    546-  { "<stdlib.h>", kPublic, "<cstdlib>", kPublic },
    547-  { "<string.h>", kPublic, "<cstring>", kPublic },
    548-  { "<tgmath.h>", kPublic, "<ctgmath>", kPublic },
    549-  { "<time.h>", kPublic, "<ctime>", kPublic },
    550-  { "<uchar.h>", kPublic, "<cuchar>", kPublic },
    551-  { "<wchar.h>", kPublic, "<cwchar>", kPublic },
    552-  { "<wctype.h>", kPublic, "<cwctype>", kPublic },
    553+  { "<complex.h>", kPrivate, "<ccomplex>", kPublic },
    554+  { "<ctype.h>", kPrivate, "<cctype>", kPublic },
    555+  { "<errno.h>", kPrivate, "<cerrno>", kPublic },
    556+  { "<fenv.h>", kPrivate, "<cfenv>", kPublic },
    557+  { "<float.h>", kPrivate, "<cfloat>", kPublic },
    558+  { "<inttypes.h>", kPrivate, "<cinttypes>", kPublic },
    559+  { "<iso646.h>", kPrivate, "<ciso646>", kPublic },
    560+  { "<limits.h>", kPrivate, "<climits>", kPublic },
    561+  { "<locale.h>", kPrivate, "<clocale>", kPublic },
    562+  { "<math.h>", kPrivate, "<cmath>", kPublic },
    563+  { "<setjmp.h>", kPrivate, "<csetjmp>", kPublic },
    564+  { "<signal.h>", kPrivate, "<csignal>", kPublic },
    565+  { "<stdalign.h>", kPrivate, "<cstdalign>", kPublic },
    566+  { "<stdarg.h>", kPrivate, "<cstdarg>", kPublic },
    567+  { "<stdbool.h>", kPrivate, "<cstdbool>", kPublic },
    568+  { "<stddef.h>", kPrivate, "<cstddef>", kPublic },
    569+  { "<stdint.h>", kPrivate, "<cstdint>", kPublic },
    570+  { "<stdio.h>", kPrivate, "<cstdio>", kPublic },
    571+  { "<stdlib.h>", kPrivate, "<cstdlib>", kPublic },
    572+  { "<string.h>", kPrivate, "<cstring>", kPublic },
    573+  { "<tgmath.h>", kPrivate, "<ctgmath>", kPublic },
    574+  { "<time.h>", kPrivate, "<ctime>", kPublic },
    575+  { "<uchar.h>", kPrivate, "<cuchar>", kPublic },
    576+  { "<wchar.h>", kPrivate, "<cwchar>", kPublic },
    577+  { "<wctype.h>", kPrivate, "<cwctype>", kPublic },
    578 };
    579 
    580 const char* stdlib_cpp_public_headers[] = {
    

    hebasto commented at 8:38 pm on December 17, 2025:

    edit: The full patch would be:

    Taken.

  42. in ci/test/00_setup_env_native_iwyu.sh:22 in f85e96fe89 outdated
    17+export RUN_FUZZ_TESTS=false
    18+export RUN_CHECK_DEPS=false
    19+export RUN_IWYU=true
    20+export GOAL="codegen"
    21+export BITCOIN_CONFIG="\
    22+ --preset dev-mode -DBUILD_GUI=OFF \
    


    maflcko commented at 11:50 am on December 16, 2025:
    any reason to exclude the gui?

    hebasto commented at 12:00 pm on December 16, 2025:
    Yes. The codegen target doesn’t work well for Qt moc compiler for now. See #32951.
  43. maflcko commented at 11:52 am on December 16, 2025: member
    lgtm
  44. maflcko commented at 6:05 pm on December 17, 2025: member

    review ACK 73439910a02c2c07de94ad3a78ac3421ba7218d9 💣

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: review ACK 73439910a02c2c07de94ad3a78ac3421ba7218d9 💣
    3PFE0MXlQDERuLW7wBsykme9L5AeWZS925eSdxV7Izq+OJxtpt5xAMKk8uh/6CsYBai+qxn1q2NB9oowhf4qPAw==
    
  45. DrahtBot requested review from w0xlt on Dec 17, 2025
  46. DrahtBot requested review from stickies-v on Dec 17, 2025
  47. iwyu: Add patch to prefer angled brackets over quotes for includes 7a65437e23
  48. iwyu: Add patch to prefer C++ headers over C counterparts 73f7844cdb
  49. cmake: Make `codegen` target dependent on `generate_build_info` 0f81e00519
  50. cmake: Fix target name
    The executable target run by ctest is `mptest`.
    
    This change removes unnecessary steps when building the `codegen`
    target.
    94e4f04d7c
  51. ci: Add IWYU job
    The change in `src/crypto/hex_base.cpp` is because GCC 14 is not
    affected by an IWYU bug.
    See: https://github.com/include-what-you-use/include-what-you-use/issues/1763.
    2c78814e0e
  52. iwyu, clang-format: Sort includes 56750c4f87
  53. hebasto force-pushed on Dec 17, 2025
  54. hebasto commented at 8:38 pm on December 17, 2025: member

    @maflcko

    Thank you for the review. The PR has been reworked per your feedback.

  55. maflcko commented at 6:56 am on December 18, 2025: member

    Only change is replacing the sed commands with a large patch.

    review ACK 56750c4f87d089c6a3f093eb2bf2edd07170d4a8 🌄

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: review ACK 56750c4f87d089c6a3f093eb2bf2edd07170d4a8 🌄
    3Xa/HJod6nR3+9bZFBU0zofE9PFyrRUFTjEk24LOKmdHtq/8KRknE4YKBRw4ac5u4m9HCwWeM+3iD8x2R8tfPCw==
    
  56. in ci/test/01_iwyu.patch:21 in 73f7844cdb outdated
    16+
    17+Prefer C++ headers over C counterparts.
    18+See: https://github.com/include-what-you-use/include-what-you-use/blob/clang_21/iwyu_include_picker.cc#L587-L629.
    19+
    20+--- a/iwyu_include_picker.cc
    21++++ b/iwyu_include_picker.cc
    


    sedited commented at 3:44 pm on December 22, 2025:
    Just a note: I don’t think this patch will be particularly stable, but it seems like the easiest way to get this working correctly. Also seems reasonably straight forward to implement again if required.
  57. sedited approved
  58. sedited commented at 5:32 pm on December 22, 2025: contributor
    ACK 56750c4f87d089c6a3f093eb2bf2edd07170d4a8
  59. hebasto merged this on Dec 22, 2025
  60. hebasto closed this on Dec 22, 2025

  61. hebasto deleted the branch on Dec 22, 2025

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-02 03:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me