libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

iwyu-0.16-u3.patch (92422B)


      1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
      2 index 1f06014..dce8632 100644
      3 --- a/.github/workflows/ci.yml
      4 +++ b/.github/workflows/ci.yml
      5 @@ -15,7 +15,7 @@ jobs:
      6        fail-fast: false
      7  
      8      env:
      9 -      LLVM_TAG: -12
     10 +      LLVM_TAG:
     11  
     12      steps:
     13        - name: Install prerequisites
     14 @@ -33,6 +33,10 @@ jobs:
     15            sudo apt install -y libclang$LLVM_TAG-dev
     16            sudo apt install -y clang$LLVM_TAG
     17  
     18 +      - name: Broken packaging workaround
     19 +        run: |
     20 +          sudo touch /usr/lib/llvm-14/lib/libclang-14.so.14.0.0
     21 +
     22        - name: Check out default branch
     23          uses: actions/checkout@v2
     24  
     25 diff --git a/CMakeLists.txt b/CMakeLists.txt
     26 index 923b4d9..0a0d683 100644
     27 --- a/CMakeLists.txt
     28 +++ b/CMakeLists.txt
     29 @@ -68,9 +68,9 @@ endif()
     30  set(LLVM_LINK_COMPONENTS
     31    Option
     32    Support
     33 -  X86AsmParser
     34 -  X86Desc
     35 -  X86Info
     36 +  AllTargetsAsmParsers
     37 +  AllTargetsDescs
     38 +  AllTargetsInfos
     39    )
     40  
     41  add_llvm_executable(include-what-you-use
     42 @@ -110,8 +110,8 @@ if (MSVC)
     43      -D_HAS_EXCEPTIONS=0
     44      )
     45  
     46 -  # Enable bigobj support and sane C++ exception semantics.
     47 -  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /EHsc")
     48 +  # Enable bigobj support
     49 +  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
     50  endif()
     51  
     52  # Link dynamically or statically depending on user preference.
     53 diff --git a/README.md b/README.md
     54 index 58abdc7..0ef3082 100644
     55 --- a/README.md
     56 +++ b/README.md
     57 @@ -40,6 +40,7 @@ We assume you already have compiled LLVM and Clang libraries on your system, eit
     58  | 9     | 0.13         | `clang_9.0`    |
     59  | 10    | 0.14         | `clang_10`     |
     60  | 11    | 0.15         | `clang_11`     |
     61 +| 12    | 0.16         | `clang_12`     |
     62  | ...   | ...          | ...            |
     63  | main  |              | `master`       |
     64  
     65 @@ -142,7 +143,7 @@ Note that with Microsoft's Visual C++ compiler, IWYU needs the `--driver-mode=cl
     66  
     67  #### Using with a compilation database ####
     68  
     69 -The `iwyu_tool.py` script predates the native CMake support, and works off the [compilation database format](https://clang.llvm.org/docs/JSONCompilationDatabase.html). For example, CMake generates such a database named `compile_commands.json` with the `CMAKE_EXPORT_COMPILE_COMMANDS` option enabled.
     70 +The `iwyu_tool.py` script pre-dates the native CMake support, and works off the [compilation database format](https://clang.llvm.org/docs/JSONCompilationDatabase.html). For example, CMake generates such a database named `compile_commands.json` with the `CMAKE_EXPORT_COMPILE_COMMANDS` option enabled.
     71  
     72  The script's command-line syntax is designed to mimic Clang's LibTooling, but they are otherwise unrelated. It can be used like this:
     73  
     74 diff --git a/fix_includes.py b/fix_includes.py
     75 index 7600361..8de5775 100755
     76 --- a/fix_includes.py
     77 +++ b/fix_includes.py
     78 @@ -2309,11 +2309,12 @@ def ProcessIWYUOutput(f, files_to_process, flags, cwd):
     79    # seen for them.  (We have to wait until we're all done, since a .h
     80    # file may have a contentful change when #included from one .cc
     81    # file, but not another, and we need to have merged them above.)
     82 -  for filename in iwyu_output_records:
     83 -    if not iwyu_output_records[filename].HasContentfulChanges():
     84 -      print('(skipping %s: iwyu reports no contentful changes)' % filename)
     85 -      # Mark that we're skipping this file by setting the record to None
     86 -      iwyu_output_records[filename] = None
     87 +  if not flags.update_comments:
     88 +    for filename in iwyu_output_records:
     89 +      if not iwyu_output_records[filename].HasContentfulChanges():
     90 +        print('(skipping %s: iwyu reports no contentful changes)' % filename)
     91 +        # Mark that we're skipping this file by setting the record to None
     92 +        iwyu_output_records[filename] = None
     93  
     94    # Now do all the fixing, and return the number of files modified
     95    contentful_records = [ior for ior in iwyu_output_records.values() if ior]
     96 @@ -2373,6 +2374,12 @@ def main(argv):
     97                      help='Put comments after the #include lines')
     98    parser.add_option('--nocomments', action='store_false', dest='comments')
     99  
    100 +  parser.add_option('--update_comments', action='store_true', default=False,
    101 +                    help=('Update #include comments, even if no #include lines'
    102 +                          ' are added or removed'))
    103 +  parser.add_option('--noupdate_comments', action='store_false',
    104 +                    dest='update_comments')
    105 +
    106    parser.add_option('--safe_headers', action='store_true', default=True,
    107                      help=('Do not remove unused #includes/fwd-declares from'
    108                            ' header files; just add new ones [default]'))
    109 @@ -2440,6 +2447,9 @@ def main(argv):
    110        not flags.separate_project_includes.endswith('/')):
    111      flags.separate_project_includes += os.path.sep
    112  
    113 +  if flags.update_comments:
    114 +    flags.comments = True
    115 +
    116    if flags.sort_only:
    117      if not files_to_modify:
    118        sys.exit('FATAL ERROR: -s flag requires a list of filenames')
    119 diff --git a/fix_includes_test.py b/fix_includes_test.py
    120 index 380da54..07bd78d 100755
    121 --- a/fix_includes_test.py
    122 +++ b/fix_includes_test.py
    123 @@ -34,6 +34,7 @@ class FakeFlags(object):
    124    def __init__(self):
    125      self.blank_lines = False
    126      self.comments = True
    127 +    self.update_comments = False
    128      self.dry_run = False
    129      self.ignore_re = None
    130      self.only_re = None
    131 @@ -1916,6 +1917,54 @@ The full include-list for subdir/include_comments.cc:
    132      self.RegisterFileContents({'subdir/include_comments.cc': infile})
    133      self.ProcessAndTest(iwyu_output)
    134  
    135 +  def testUpdateCommentsFlag(self):
    136 +    """Tests we update comments with --update_comments."""
    137 +    self.flags.update_comments = True
    138 +    infile = """\
    139 +#include "must_keep.h"  // IWYU pragma: keep
    140 +#include "used.h"       // for SomethingElse  ///-
    141 +///+#include "used.h"       // for Used
    142 +
    143 +Used used;
    144 +int main() { return 0; }
    145 +"""
    146 +    iwyu_output = """\
    147 +subdir/include_comments.cc should add these lines:
    148 +
    149 +subdir/include_comments.cc should remove these lines:
    150 +
    151 +The full include-list for subdir/include_comments.cc:
    152 +#include "must_keep.h"
    153 +#include "used.h"       // for Used
    154 +---
    155 +"""
    156 +    self.RegisterFileContents({'subdir/include_comments.cc': infile})
    157 +    self.ProcessAndTest(iwyu_output)
    158 +
    159 +  def testNoUpdateCommentsFlag(self):
    160 +    """Tests we don't update comments with --noupdate_comments."""
    161 +    self.flags.update_comments = False
    162 +    infile = """\
    163 +#include "must_keep.h"  // IWYU pragma: keep
    164 +#include "used.h"       // for SomethingElse
    165 +
    166 +Used used;
    167 +int main() { return 0; }
    168 +"""
    169 +    iwyu_output = """\
    170 +subdir/include_comments.cc should add these lines:
    171 +
    172 +subdir/include_comments.cc should remove these lines:
    173 +
    174 +The full include-list for subdir/include_comments.cc:
    175 +#include "must_keep.h"
    176 +#include "used.h"       // for Used
    177 +---
    178 +"""
    179 +    self.RegisterFileContents({'subdir/include_comments.cc': infile})
    180 +    self.ProcessAndTest(iwyu_output,
    181 +                        unedited_files=['subdir/include_comments.cc'])
    182 +
    183    def testFixingTwoFiles(self):
    184      """Make sure data for one fix doesn't overlap with a second."""
    185      file_a = """\
    186 diff --git a/gcc.symbols.imp b/gcc.symbols.imp
    187 index 5ecf219..de38147 100644
    188 --- a/gcc.symbols.imp
    189 +++ b/gcc.symbols.imp
    190 @@ -9,22 +9,36 @@
    191  # equivalents.
    192  # In each case, I ordered them so <sys/types.h> was first, if it was
    193  # an option for this type.  That's the preferred #include all else
    194 -# equal.  The visibility on the symbol-name is ignored; by convention
    195 -# we always set it to private.
    196 +# equal.  The same goes for <stdint.h>.  The visibility on the
    197 +# symbol-name is ignored; by convention we always set it to private.
    198  [
    199 -  { symbol: [ "blksize_t", private, "<sys/types.h>", public ] },
    200 -  { symbol: [ "blkcnt_t", private, "<sys/stat.h>", public ] },
    201 +  { symbol: [ "aiocb", private, "<aio.h>", public ] },
    202    { symbol: [ "blkcnt_t", private, "<sys/types.h>", public ] },
    203 +  { symbol: [ "blkcnt_t", private, "<sys/stat.h>", public ] },
    204 +  { symbol: [ "blksize_t", private, "<sys/types.h>", public ] },
    205    { symbol: [ "blksize_t", private, "<sys/stat.h>", public ] },
    206 +  { symbol: [ "cc_t", private, "<termios.h>", public ] },
    207    { symbol: [ "clock_t", private, "<sys/types.h>", public ] },
    208 +  { symbol: [ "clock_t", private, "<sys/time.h>", public ] },
    209    { symbol: [ "clock_t", private, "<time.h>", public ] },
    210 +  { symbol: [ "clockid_t", private, "<sys/types.h>", public ] },
    211 +  { symbol: [ "clockid_t", private, "<time.h>", public ] },
    212    { symbol: [ "daddr_t", private, "<sys/types.h>", public ] },
    213    { symbol: [ "daddr_t", private, "<rpc/types.h>", public ] },
    214    { symbol: [ "dev_t", private, "<sys/types.h>", public ] },
    215    { symbol: [ "dev_t", private, "<sys/stat.h>", public ] },
    216 +  { symbol: [ "div_t", private, "<stdlib.h>", public ] },
    217 +  { symbol: [ "double_t", private, "<math.h>", public ] },
    218    { symbol: [ "error_t", private, "<errno.h>", public ] },
    219    { symbol: [ "error_t", private, "<argp.h>", public ] },
    220    { symbol: [ "error_t", private, "<argz.h>", public ] },
    221 +  { symbol: [ "fd_set", private, "<sys/select.h>", public ] },
    222 +  { symbol: [ "fd_set", private, "<sys/time.h>", public ] },
    223 +  { symbol: [ "fenv_t", private, "<fenv.h>", public ] },
    224 +  { symbol: [ "fexcept_t", private, "<fenv.h>", public ] },
    225 +  { symbol: [ "FILE", private, "<stdio.h>", public ] },
    226 +  { symbol: [ "FILE", private, "<wchar.h>", public ] },
    227 +  { symbol: [ "float_t", private, "<math.h>", public ] },
    228    { symbol: [ "fsblkcnt_t", private, "<sys/types.h>", public ] },
    229    { symbol: [ "fsblkcnt_t", private, "<sys/statvfs.h>", public ] },
    230    { symbol: [ "fsfilcnt_t", private, "<sys/types.h>", public ] },
    231 @@ -32,91 +46,173 @@
    232    { symbol: [ "gid_t", private, "<sys/types.h>", public ] },
    233    { symbol: [ "gid_t", private, "<grp.h>", public ] },
    234    { symbol: [ "gid_t", private, "<pwd.h>", public ] },
    235 +  { symbol: [ "gid_t", private, "<signal.h>", public ] },
    236    { symbol: [ "gid_t", private, "<stropts.h>", public ] },
    237    { symbol: [ "gid_t", private, "<sys/ipc.h>", public ] },
    238    { symbol: [ "gid_t", private, "<sys/stat.h>", public ] },
    239    { symbol: [ "gid_t", private, "<unistd.h>", public ] },
    240    { symbol: [ "id_t", private, "<sys/types.h>", public ] },
    241    { symbol: [ "id_t", private, "<sys/resource.h>", public ] },
    242 +  { symbol: [ "imaxdiv_t", private, "<inttypes.h>", public ] },
    243 +  { symbol: [ "intmax_t", private, "<stdint.h>", public ] },
    244 +  { symbol: [ "intmax_t", private, "<inttypes.h>", public ] },
    245 +  { symbol: [ "uintmax_t", private, "<stdint.h>", public ] },
    246 +  { symbol: [ "uintmax_t", private, "<inttypes.h>", public ] },
    247    { symbol: [ "ino64_t", private, "<sys/types.h>", public ] },
    248    { symbol: [ "ino64_t", private, "<dirent.h>", public ] },
    249    { symbol: [ "ino_t", private, "<sys/types.h>", public ] },
    250    { symbol: [ "ino_t", private, "<dirent.h>", public ] },
    251    { symbol: [ "ino_t", private, "<sys/stat.h>", public ] },
    252 -  { symbol: [ "int8_t", private, "<sys/types.h>", public ] },
    253    { symbol: [ "int8_t", private, "<stdint.h>", public ] },
    254 +  { symbol: [ "int8_t", private, "<inttypes.h>", public ] },
    255    { symbol: [ "int16_t", private, "<stdint.h>", public ] },
    256 +  { symbol: [ "int16_t", private, "<inttypes.h>", public ] },
    257    { symbol: [ "int32_t", private, "<stdint.h>", public ] },
    258 +  { symbol: [ "int32_t", private, "<inttypes.h>", public ] },
    259    { symbol: [ "int64_t", private, "<stdint.h>", public ] },
    260 +  { symbol: [ "int64_t", private, "<inttypes.h>", public ] },
    261    { symbol: [ "uint8_t", private, "<stdint.h>", public ] },
    262 +  { symbol: [ "uint8_t", private, "<inttypes.h>", public ] },
    263    { symbol: [ "uint16_t", private, "<stdint.h>", public ] },
    264 +  { symbol: [ "uint16_t", private, "<inttypes.h>", public ] },
    265    { symbol: [ "uint32_t", private, "<stdint.h>", public ] },
    266 +  { symbol: [ "uint32_t", private, "<inttypes.h>", public ] },
    267    { symbol: [ "uint64_t", private, "<stdint.h>", public ] },
    268 +  { symbol: [ "uint64_t", private, "<inttypes.h>", public ] },
    269    { symbol: [ "intptr_t", private, "<stdint.h>", public ] },
    270 +  { symbol: [ "intptr_t", private, "<inttypes.h>", public ] },
    271    { symbol: [ "uintptr_t", private, "<stdint.h>", public ] },
    272 -  { symbol: [ "intptr_t", private, "<unistd.h>", public ] },
    273 +  { symbol: [ "uintptr_t", private, "<inttypes.h>", public ] },
    274    { symbol: [ "key_t", private, "<sys/types.h>", public ] },
    275    { symbol: [ "key_t", private, "<sys/ipc.h>", public ] },
    276 +  { symbol: [ "lconv", private, "<locale.h>", public ] },
    277 +  { symbol: [ "ldiv_t", private, "<stdlib.h>", public ] },
    278 +  { symbol: [ "lldiv_t", private, "<stdlib.h>", public ] },
    279    { symbol: [ "max_align_t", private, "<stddef.h>", public ] },
    280    { symbol: [ "mode_t", private, "<sys/types.h>", public ] },
    281 -  { symbol: [ "mode_t", private, "<sys/stat.h>", public ] },
    282 +  { symbol: [ "mode_t", private, "<fcntl.h>", public ] },
    283 +  { symbol: [ "mode_t", private, "<ndbm.h>", public ] },
    284 +  { symbol: [ "mode_t", private, "<spawn.h>", public ] },
    285    { symbol: [ "mode_t", private, "<sys/ipc.h>", public ] },
    286    { symbol: [ "mode_t", private, "<sys/mman.h>", public ] },
    287 +  { symbol: [ "mode_t", private, "<sys/stat.h>", public ] },
    288    { symbol: [ "nlink_t", private, "<sys/types.h>", public ] },
    289    { symbol: [ "nlink_t", private, "<sys/stat.h>", public ] },
    290    { symbol: [ "off64_t", private, "<sys/types.h>", public ] },
    291    { symbol: [ "off64_t", private, "<unistd.h>", public ] },
    292    { symbol: [ "off_t", private, "<sys/types.h>", public ] },
    293 -  { symbol: [ "off_t", private, "<unistd.h>", public ] },
    294 -  { symbol: [ "off_t", private, "<sys/stat.h>", public ] },
    295 +  { symbol: [ "off_t", private, "<aio.h>", public ] },
    296 +  { symbol: [ "off_t", private, "<fcntl.h>", public ] },
    297 +  { symbol: [ "off_t", private, "<stdio.h>", public ] },
    298    { symbol: [ "off_t", private, "<sys/mman.h>", public ] },
    299 +  { symbol: [ "off_t", private, "<sys/stat.h>", public ] },
    300 +  { symbol: [ "off_t", private, "<unistd.h>", public ] },
    301    { symbol: [ "pid_t", private, "<sys/types.h>", public ] },
    302 -  { symbol: [ "pid_t", private, "<unistd.h>", public ] },
    303 +  { symbol: [ "pid_t", private, "<fcntl.h>", public ] },
    304 +  { symbol: [ "pid_t", private, "<sched.h>", public ] },
    305    { symbol: [ "pid_t", private, "<signal.h>", public ] },
    306 +  { symbol: [ "pid_t", private, "<spawn.h>", public ] },
    307    { symbol: [ "pid_t", private, "<sys/msg.h>", public ] },
    308 +  { symbol: [ "pid_t", private, "<sys/sem.h>", public ] },
    309    { symbol: [ "pid_t", private, "<sys/shm.h>", public ] },
    310 +  { symbol: [ "pid_t", private, "<sys/wait.h>", public ] },
    311    { symbol: [ "pid_t", private, "<termios.h>", public ] },
    312    { symbol: [ "pid_t", private, "<time.h>", public ] },
    313 +  { symbol: [ "pid_t", private, "<unistd.h>", public ] },
    314    { symbol: [ "pid_t", private, "<utmpx.h>", public ] },
    315    { symbol: [ "ptrdiff_t", private, "<stddef.h>", public ] },
    316 +  { symbol: [ "regex_t", private, "<regex.h>", public ] },
    317 +  { symbol: [ "regmatch_t", private, "<regex.h>", public ] },
    318 +  { symbol: [ "regoff_t", private, "<regex.h>", public ] },
    319 +  { symbol: [ "sigevent", private, "<signal.h>", public ] },
    320 +  { symbol: [ "sigevent", private, "<aio.h>", public ] },
    321 +  { symbol: [ "sigevent", private, "<mqueue.h>", public ] },
    322 +  { symbol: [ "sigevent", private, "<time.h>", public ] },
    323 +  { symbol: [ "siginfo_t", private, "<signal.h>", public ] },
    324 +  { symbol: [ "siginfo_t", private, "<sys/wait.h>", public ] },
    325    { symbol: [ "sigset_t", private, "<signal.h>", public ] },
    326 -  { symbol: [ "sigset_t", private, "<sys/epoll.h>", public ] },
    327 +  { symbol: [ "sigset_t", private, "<spawn.h>", public ] },
    328    { symbol: [ "sigset_t", private, "<sys/select.h>", public ] },
    329 -  { symbol: [ "socklen_t", private, "<bits/socket.h>", private ] },
    330 -  { symbol: [ "socklen_t", private, "<unistd.h>", public ] },
    331 -  { symbol: [ "socklen_t", private, "<arpa/inet.h>", public ] },
    332 +  { symbol: [ "sigval", private, "<signal.h>", public ] },
    333 +  { symbol: [ "sockaddr", private, "<sys/socket.h>", public ] },
    334 +  { symbol: [ "socklen_t", private, "<sys/socket.h>", public ] },
    335 +  { symbol: [ "socklen_t", private, "<netdb.h>", public ] },
    336    { symbol: [ "ssize_t", private, "<sys/types.h>", public ] },
    337 -  { symbol: [ "ssize_t", private, "<unistd.h>", public ] },
    338 +  { symbol: [ "ssize_t", private, "<aio.h>", public ] },
    339    { symbol: [ "ssize_t", private, "<monetary.h>", public ] },
    340 +  { symbol: [ "ssize_t", private, "<mqueue.h>", public ] },
    341 +  { symbol: [ "ssize_t", private, "<stdio.h>", public ] },
    342    { symbol: [ "ssize_t", private, "<sys/msg.h>", public ] },
    343 +  { symbol: [ "ssize_t", private, "<sys/socket.h>", public ] },
    344 +  { symbol: [ "ssize_t", private, "<sys/uio.h>", public ] },
    345 +  { symbol: [ "ssize_t", private, "<unistd.h>", public ] },
    346    { symbol: [ "suseconds_t", private, "<sys/types.h>", public ] },
    347 -  { symbol: [ "suseconds_t", private, "<sys/time.h>", public ] },
    348    { symbol: [ "suseconds_t", private, "<sys/select.h>", public ] },
    349 -  { symbol: [ "time_t", private, "<sys/types.h>", public ] },
    350 +  { symbol: [ "suseconds_t", private, "<sys/time.h>", public ] },
    351    { symbol: [ "time_t", private, "<time.h>", public ] },
    352 +  { symbol: [ "time_t", private, "<sched.h>", public ] },
    353 +  { symbol: [ "time_t", private, "<sys/msg.h>", public ] },
    354 +  { symbol: [ "time_t", private, "<sys/select.h>", public ] },
    355 +  { symbol: [ "time_t", private, "<sys/sem.h>", public ] },
    356 +  { symbol: [ "time_t", private, "<sys/shm.h>", public ] },
    357 +  { symbol: [ "time_t", private, "<sys/stat.h>", public ] },
    358 +  { symbol: [ "time_t", private, "<sys/time.h>", public ] },
    359 +  { symbol: [ "time_t", private, "<sys/types.h>", public ] },
    360 +  { symbol: [ "time_t", private, "<utime.h>", public ] },
    361 +  { symbol: [ "timer_t", private, "<sys/types.h>", public ] },
    362 +  { symbol: [ "timer_t", private, "<time.h>", public ] },
    363    { symbol: [ "timespec", private, "<time.h>", public ] },
    364 +  { symbol: [ "timespec", private, "<aio.h>", public ] },
    365 +  { symbol: [ "timespec", private, "<mqueue.h>", public ] },
    366 +  { symbol: [ "timespec", private, "<sched.h>", public ] },
    367 +  { symbol: [ "timespec", private, "<signal.h>", public ] },
    368 +  { symbol: [ "timespec", private, "<sys/select.h>", public ] },
    369 +  { symbol: [ "timespec", private, "<sys/stat.h>", public ] },
    370    { symbol: [ "timeval", private, "<sys/time.h>", public ] },
    371 +  { symbol: [ "timeval", private, "<sys/resource.h>", public ] },
    372 +  { symbol: [ "timeval", private, "<sys/select.h>", public ] },
    373 +  { symbol: [ "timeval", private, "<utmpx.h>", public ] },
    374    { symbol: [ "u_char", private, "<sys/types.h>", public ] },
    375    { symbol: [ "u_char", private, "<rpc/types.h>", public ] },
    376    { symbol: [ "uid_t", private, "<sys/types.h>", public ] },
    377 -  { symbol: [ "uid_t", private, "<unistd.h>", public ] },
    378    { symbol: [ "uid_t", private, "<pwd.h>", public ] },
    379    { symbol: [ "uid_t", private, "<signal.h>", public ] },
    380    { symbol: [ "uid_t", private, "<stropts.h>", public ] },
    381    { symbol: [ "uid_t", private, "<sys/ipc.h>", public ] },
    382    { symbol: [ "uid_t", private, "<sys/stat.h>", public ] },
    383 +  { symbol: [ "uid_t", private, "<unistd.h>", public ] },
    384    { symbol: [ "useconds_t", private, "<sys/types.h>", public ] },
    385    { symbol: [ "useconds_t", private, "<unistd.h>", public ] },
    386    { symbol: [ "wchar_t", private, "<stddef.h>", public ] },
    387    { symbol: [ "wchar_t", private, "<stdlib.h>", public ] },
    388 -  # glob.h seems to define size_t if necessary, but it should come from stddef.
    389    { symbol: [ "size_t", private, "<stddef.h>", public ] },
    390 +  { symbol: [ "size_t", private, "<aio.h>", public ] },
    391 +  { symbol: [ "size_t", private, "<glob.h>", public ] },
    392 +  { symbol: [ "size_t", private, "<grp.h>", public ] },
    393 +  { symbol: [ "size_t", private, "<iconv.h>", public ] },
    394 +  { symbol: [ "size_t", private, "<monetary.h>", public ] },
    395 +  { symbol: [ "size_t", private, "<mqueue.h>", public ] },
    396 +  { symbol: [ "size_t", private, "<ndbm.h>", public ] },
    397 +  { symbol: [ "size_t", private, "<pwd.h>", public ] },
    398 +  { symbol: [ "size_t", private, "<regex.h>", public ] },
    399 +  { symbol: [ "size_t", private, "<search.h>", public ] },
    400 +  { symbol: [ "size_t", private, "<signal.h>", public ] },
    401    { symbol: [ "size_t", private, "<stdio.h>", public ] },
    402    { symbol: [ "size_t", private, "<stdlib.h>", public ] },
    403    { symbol: [ "size_t", private, "<string.h>", public ] },
    404 +  { symbol: [ "size_t", private, "<strings.h>", public ] },
    405 +  { symbol: [ "size_t", private, "<sys/mman.h>", public ] },
    406 +  { symbol: [ "size_t", private, "<sys/msg.h>", public ] },
    407 +  { symbol: [ "size_t", private, "<sys/sem.h>", public ] },
    408 +  { symbol: [ "size_t", private, "<sys/shm.h>", public ] },
    409 +  { symbol: [ "size_t", private, "<sys/socket.h>", public ] },
    410 +  { symbol: [ "size_t", private, "<sys/types.h>", public ] },
    411 +  { symbol: [ "size_t", private, "<sys/uio.h>", public ] },
    412    { symbol: [ "size_t", private, "<time.h>", public ] },
    413    { symbol: [ "size_t", private, "<uchar.h>", public ] },
    414 +  { symbol: [ "size_t", private, "<unistd.h>", public ] },
    415    { symbol: [ "size_t", private, "<wchar.h>", public ] },
    416 +  { symbol: [ "size_t", private, "<wordexp.h>", public ] },
    417    # Macros that can be defined in more than one file, don't have the
    418    # same __foo_defined guard that other types do, so the grep above
    419    # doesn't discover them.  Until I figure out a better way, I just
    420 @@ -125,6 +221,8 @@
    421    { symbol: [ "EOF", private, "<libio.h>", public ] },
    422    { symbol: [ "FILE", private, "<stdio.h>", public ] },
    423    { symbol: [ "va_list", private, "<stdarg.h>", public ] },
    424 +  { symbol: [ "va_list", private, "<stdio.h>", public ] },
    425 +  { symbol: [ "va_list", private, "<wchar.h>", public ] },
    426    # These are symbols that could be defined in either stdlib.h or
    427    # malloc.h, but we always want the stdlib location.
    428    { symbol: [ "malloc", private, "<stdlib.h>", public ] },
    429 diff --git a/iwyu.cc b/iwyu.cc
    430 index 355e793..61350ca 100644
    431 --- a/iwyu.cc
    432 +++ b/iwyu.cc
    433 @@ -167,6 +167,7 @@ using clang::ConstructorUsingShadowDecl;
    434  using clang::Decl;
    435  using clang::DeclContext;
    436  using clang::DeclRefExpr;
    437 +using clang::DeducedTemplateSpecializationType;
    438  using clang::EnumType;
    439  using clang::Expr;
    440  using clang::FileEntry;
    441 @@ -191,6 +192,7 @@ using clang::QualifiedTypeLoc;
    442  using clang::RecordDecl;
    443  using clang::RecursiveASTVisitor;
    444  using clang::ReferenceType;
    445 +using clang::Sema;
    446  using clang::SourceLocation;
    447  using clang::Stmt;
    448  using clang::SubstTemplateTypeParmType;
    449 @@ -532,17 +534,10 @@ class BaseAstVisitor : public RecursiveASTVisitor<Derived> {
    450  
    451    //------------------------------------------------------------
    452    // (4) Add implicit text.
    453 -
    454 -  // When we see an object that has implicit text that iwyu
    455 -  // wants to look at, we make callbacks as if that text had
    456 -  // been explicitly written.  Here's text we consider:
    457    //
    458 -  //    * CXXDestructorDecl: a destructor call for each non-POD field
    459 -  //      in the dtor's class, and each base type of that class.
    460 -  //    * CXXRecordDecl: a CXXConstructorDecl for each implicit
    461 -  //      constructor (zero-arg and copy).  A CXXDestructor decl
    462 -  //      if the destructor is implicit.  A CXXOperatorCallDecl if
    463 -  //      operator= is explicit.
    464 +  // This simulates a call to the destructor of every non-POD field and base
    465 +  // class in all classes with destructors, to mark them as used by virtue of
    466 +  // being class members.
    467    bool TraverseCXXDestructorDecl(clang::CXXDestructorDecl* decl) {
    468      if (!Base::TraverseCXXDestructorDecl(decl))  return false;
    469      if (CanIgnoreCurrentASTNode())  return true;
    470 @@ -575,69 +570,12 @@ class BaseAstVisitor : public RecursiveASTVisitor<Derived> {
    471      return true;
    472    }
    473  
    474 -  // clang lazily constructs the implicit methods of a C++ class (the
    475 -  // default constructor and destructor, etc) -- it only bothers to
    476 -  // create a CXXMethodDecl if someone actually calls these classes.
    477 -  // But we need to be non-lazy: iwyu depends on analyzing what future
    478 -  // code *may* call in a class, not what current code *does*.  So we
    479 -  // force all the lazy evaluation to happen here.  This will
    480 -  // (possibly) add a bunch of MethodDecls to the AST, as children of
    481 -  // decl.  We're hoping it will always be safe to modify the AST
    482 -  // while it's being traversed!
    483 -  void InstantiateImplicitMethods(CXXRecordDecl* decl) {
    484 -    if (decl->isDependentType())   // only instantiate if class is instantiated
    485 -      return;
    486 -
    487 -    clang::Sema& sema = compiler()->getSema();
    488 -    DeclContext::lookup_result ctors = sema.LookupConstructors(decl);
    489 -    for (NamedDecl* ctor_lookup : ctors) {
    490 -      // Ignore templated or inheriting constructors.
    491 -      if (isa<FunctionTemplateDecl>(ctor_lookup) ||
    492 -          isa<UsingDecl>(ctor_lookup) ||
    493 -          isa<ConstructorUsingShadowDecl>(ctor_lookup))
    494 -        continue;
    495 -      CXXConstructorDecl* ctor = cast<CXXConstructorDecl>(ctor_lookup);
    496 -      if (!ctor->hasBody() && !ctor->isDeleted() && ctor->isImplicit()) {
    497 -        if (sema.getSpecialMember(ctor) == clang::Sema::CXXDefaultConstructor) {
    498 -          sema.DefineImplicitDefaultConstructor(CurrentLoc(), ctor);
    499 -        } else {
    500 -          // TODO(nlewycky): enable this!
    501 -          //sema.DefineImplicitCopyConstructor(CurrentLoc(), ctor);
    502 -        }
    503 -      }
    504 -      // Unreferenced template constructors stay uninstantiated on purpose.
    505 -    }
    506 -
    507 -    if (CXXDestructorDecl* dtor = sema.LookupDestructor(decl)) {
    508 -      if (!dtor->isDeleted()) {
    509 -        if (!dtor->hasBody() && dtor->isImplicit())
    510 -          sema.DefineImplicitDestructor(CurrentLoc(), dtor);
    511 -        if (!dtor->isDefined() && dtor->getTemplateInstantiationPattern())
    512 -          sema.PendingInstantiations.emplace_back(dtor, CurrentLoc());
    513 -      }
    514 -    }
    515 -
    516 -    // TODO(nlewycky): copy assignment operator
    517 -
    518 -    // clang queues up method instantiations.  We need to process them now.
    519 -    sema.PerformPendingInstantiations();
    520 -  }
    521 -
    522 -  // Handle implicit methods that otherwise wouldn't be seen by RAV.
    523 -  bool TraverseCXXRecordDecl(clang::CXXRecordDecl* decl) {
    524 -    if (CanIgnoreCurrentASTNode()) return true;
    525 -    // We only care about classes that are actually defined.
    526 -    if (decl && decl->isThisDeclarationADefinition()) {
    527 -      InstantiateImplicitMethods(decl);
    528 -    }
    529 -
    530 -    return Base::TraverseCXXRecordDecl(decl);
    531 -  }
    532 -
    533 +  // Class template specialization are similar to regular C++ classes,
    534 +  // particularly they need the same custom handling of implicit destructors.
    535    bool TraverseClassTemplateSpecializationDecl(
    536        clang::ClassTemplateSpecializationDecl* decl) {
    537      if (!Base::TraverseClassTemplateSpecializationDecl(decl)) return false;
    538 -    return TraverseCXXRecordDecl(decl);
    539 +    return Base::TraverseCXXRecordDecl(decl);
    540    }
    541  
    542    //------------------------------------------------------------
    543 @@ -1322,7 +1260,26 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    544      for (const NamedDecl* redecl : GetClassRedecls(decl)) {
    545        if (GetFileEntry(redecl) == macro_def_file && IsForwardDecl(redecl)) {
    546          fwd_decl = redecl;
    547 +        break;
    548 +      }
    549 +    }
    550  
    551 +    if (!fwd_decl) {
    552 +      if (const auto* func_decl = dyn_cast<FunctionDecl>(decl)) {
    553 +        if (const FunctionTemplateDecl* ft_decl =
    554 +            func_decl->getPrimaryTemplate()) {
    555 +          VERRS(5) << "No fwd-decl found, looking for function template decl\n";
    556 +          for (const NamedDecl* redecl : ft_decl->redecls()) {
    557 +            if (GetFileEntry(redecl) == macro_def_file) {
    558 +              fwd_decl = redecl;
    559 +              break;
    560 +            }
    561 +          }
    562 +        }
    563 +      }
    564 +    }
    565 +
    566 +    if (fwd_decl) {
    567          // Make sure we keep that forward-declaration, even if it's probably
    568          // unused in this file.
    569          IwyuFileInfo* file_info =
    570 @@ -1330,8 +1287,6 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    571          file_info->ReportForwardDeclareUse(
    572              spelling_loc, fwd_decl,
    573              ComputeUseFlags(current_ast_node()), nullptr);
    574 -        break;
    575 -      }
    576      }
    577  
    578      // Resolve the best use location based on our current knowledge.
    579 @@ -1460,12 +1415,12 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    580    }
    581  
    582    set<const Type*> GetCallerResponsibleTypesForTypedef(
    583 -      const TypedefDecl* decl) {
    584 +      const TypedefNameDecl* decl) {
    585      set<const Type*> retval;
    586      const Type* underlying_type = decl->getUnderlyingType().getTypePtr();
    587      // If the underlying type is itself a typedef, we recurse.
    588      if (const TypedefType* underlying_typedef = DynCastFrom(underlying_type)) {
    589 -      if (const TypedefDecl* underlying_typedef_decl
    590 +      if (const TypedefNameDecl* underlying_typedef_decl
    591            = DynCastFrom(TypeToDeclAsWritten(underlying_typedef))) {
    592          // TODO(csilvers): if one of the intermediate typedefs
    593          // #includes the necessary definition of the 'final'
    594 @@ -1610,12 +1565,12 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    595      // anywhere.  ('autocast' is similar, but is handled in
    596      // VisitCastExpr; 'fn-return-type' is also similar and is
    597      // handled in HandleFunctionCall.)
    598 -    if (const TypedefDecl* typedef_decl = DynCastFrom(target_decl)) {
    599 +    if (const TypedefNameDecl* typedef_decl = DynCastFrom(target_decl)) {
    600        // One exception: if this TypedefType is being used in another
    601        // typedef (that is, 'typedef MyTypedef OtherTypdef'), then the
    602        // user -- the other typedef -- is never responsible for the
    603        // underlying type.  Instead, users of that typedef are.
    604 -      if (!current_ast_node()->template ParentIsA<TypedefDecl>()) {
    605 +      if (!current_ast_node()->template ParentIsA<TypedefNameDecl>()) {
    606          const set<const Type*>& underlying_types
    607              = GetCallerResponsibleTypesForTypedef(typedef_decl);
    608          if (!underlying_types.empty()) {
    609 @@ -1757,7 +1712,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    610    // iwyu will demand the full type of pair, but not of its template
    611    // arguments.  This is handled not here, but below, in
    612    // VisitSubstTemplateTypeParmType.
    613 -  bool VisitTypedefDecl(clang::TypedefDecl* decl) {
    614 +  bool VisitTypedefNameDecl(clang::TypedefNameDecl* decl) {
    615      if (CanIgnoreCurrentASTNode())  return true;
    616      const Type* underlying_type = decl->getUnderlyingType().getTypePtr();
    617      const Type* deref_type
    618 @@ -1770,7 +1725,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    619        current_ast_node()->set_in_forward_declare_context(false);
    620      }
    621  
    622 -    return Base::VisitTypedefDecl(decl);
    623 +    return Base::VisitTypedefNameDecl(decl);
    624    }
    625  
    626    // If we're a declared (not defined) function, all our types --
    627 @@ -1977,8 +1932,6 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    628        case clang::CK_BooleanToSignedIntegral:
    629        case clang::CK_FixedPointCast:
    630        case clang::CK_FixedPointToBoolean:
    631 -      case clang::CK_FixedPointToFloating:
    632 -      case clang::CK_FixedPointToIntegral:
    633        case clang::CK_FloatingCast:
    634        case clang::CK_FloatingComplexCast:
    635        case clang::CK_FloatingComplexToBoolean:
    636 @@ -1986,7 +1939,6 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    637        case clang::CK_FloatingComplexToReal:
    638        case clang::CK_FloatingRealToComplex:
    639        case clang::CK_FloatingToBoolean:
    640 -      case clang::CK_FloatingToFixedPoint:
    641        case clang::CK_FloatingToIntegral:
    642        case clang::CK_FunctionToPointerDecay:
    643        case clang::CK_IntegralCast:
    644 @@ -1996,7 +1948,6 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    645        case clang::CK_IntegralComplexToReal:
    646        case clang::CK_IntegralRealToComplex:
    647        case clang::CK_IntegralToBoolean:
    648 -      case clang::CK_IntegralToFixedPoint:
    649        case clang::CK_IntegralToFloating:
    650        case clang::CK_IntegralToPointer:
    651        case clang::CK_MemberPointerToBoolean:
    652 @@ -2025,7 +1976,6 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    653        // Kinds for reinterpret_cast and const_cast, which need no full types.
    654        case clang::CK_BitCast:                // used for reinterpret_cast
    655        case clang::CK_LValueBitCast:          // used for reinterpret_cast
    656 -      case clang::CK_LValueToRValueBitCast:  // used for reinterpret_cast
    657        case clang::CK_NoOp:                   // used for const_cast, etc
    658          break;
    659  
    660 @@ -2428,15 +2378,15 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    661          // contents don't matter that much.
    662          using clang::Optional;
    663          using clang::DirectoryLookup;
    664 -        using clang::FileEntryRef;
    665 +        using clang::FileEntry;
    666          const FileEntry* use_file = CurrentFileEntry();
    667          const DirectoryLookup* curdir = nullptr;
    668 -        Optional<FileEntryRef> file = compiler()->getPreprocessor().LookupFile(
    669 +        auto file = compiler()->getPreprocessor().LookupFile(
    670              CurrentLoc(), "new", true, nullptr, use_file, curdir, nullptr,
    671 -            nullptr, nullptr, nullptr, nullptr, false);
    672 +            nullptr, nullptr, nullptr, false);
    673          if (file) {
    674            preprocessor_info().FileInfoFor(use_file)->ReportFullSymbolUse(
    675 -              CurrentLoc(), *file, "operator new");
    676 +              CurrentLoc(), file, "operator new");
    677          }
    678        }
    679      }
    680 @@ -2591,7 +2541,7 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
    681      // If we're in a typedef, we don't want to forward-declare even if
    682      // we're a pointer.  ('typedef Foo* Bar; Bar x; x->a' needs full
    683      // type of Foo.)
    684 -    if (ast_node->ParentIsA<TypedefDecl>())
    685 +    if (ast_node->ParentIsA<TypedefNameDecl>())
    686        return false;
    687  
    688      // If we ourselves are a forward-decl -- that is, we're the type
    689 @@ -3656,11 +3606,31 @@ class IwyuAstConsumer
    690      const_cast<IwyuPreprocessorInfo*>(&preprocessor_info())->
    691          HandlePreprocessingDone();
    692  
    693 +    TranslationUnitDecl* tu_decl = context.getTranslationUnitDecl();
    694 +
    695 +    // Sema::TUScope is reset after parsing, but Sema::getCurScope still points
    696 +    // to the translation unit decl scope. TUScope is required for lookup in
    697 +    // some complex scenarios, so re-wire it before running IWYU AST passes.
    698 +    // Assert their expected state so we notice if these assumptions change.
    699 +    Sema& sema = compiler()->getSema();
    700 +    CHECK_(sema.TUScope == nullptr);
    701 +    CHECK_(sema.getCurScope() != nullptr);
    702 +    sema.TUScope = sema.getCurScope();
    703 +
    704      // We run a separate pass to force parsing of late-parsed function
    705      // templates.
    706 -    ParseFunctionTemplates(context.getTranslationUnitDecl());
    707 +    ParseFunctionTemplates(sema, tu_decl);
    708  
    709 -    TraverseDecl(context.getTranslationUnitDecl());
    710 +    // Clang lazily constructs the implicit methods of a C++ class (the
    711 +    // default constructor and destructor, etc) -- it only bothers to
    712 +    // create a CXXMethodDecl if someone actually calls these classes.
    713 +    // But we need to be non-lazy: IWYU depends on analyzing what future
    714 +    // code *may* call in a class, not what current code *does*.  So we
    715 +    // force all the lazy evaluation to happen here.
    716 +    InstantiateImplicitMethods(sema, tu_decl);
    717 +
    718 +    // Run IWYU analysis.
    719 +    TraverseDecl(tu_decl);
    720  
    721      // Check if any unrecoverable errors have occurred.
    722      // There is no point in continuing when the AST is in a bad state.
    723 @@ -3705,9 +3675,8 @@ class IwyuAstConsumer
    724      exit(EXIT_SUCCESS_OFFSET + num_edits);
    725    }
    726  
    727 -  void ParseFunctionTemplates(TranslationUnitDecl* decl) {
    728 -    set<FunctionDecl*> late_parsed_decls = GetLateParsedFunctionDecls(decl);
    729 -    clang::Sema& sema = compiler()->getSema();
    730 +  void ParseFunctionTemplates(Sema& sema, TranslationUnitDecl* tu_decl) {
    731 +    set<FunctionDecl*> late_parsed_decls = GetLateParsedFunctionDecls(tu_decl);
    732  
    733      // If we have any late-parsed functions, make sure the
    734      // -fdelayed-template-parsing flag is on. Otherwise we don't know where
    735 @@ -3730,6 +3699,55 @@ class IwyuAstConsumer
    736      }
    737    }
    738  
    739 +  void InstantiateImplicitMethods(Sema& sema, TranslationUnitDecl* tu_decl) {
    740 +    // Collect all implicit ctors/dtors that need to be instantiated.
    741 +    struct Visitor : public RecursiveASTVisitor<Visitor> {
    742 +      Visitor(Sema& sema) : sema(sema) {
    743 +      }
    744 +
    745 +      bool VisitCXXRecordDecl(CXXRecordDecl* decl) {
    746 +        if (CanIgnoreLocation(GetLocation(decl)))
    747 +          return true;
    748 +
    749 +        if (!decl->getDefinition() || decl->isDependentContext() ||
    750 +            decl->isBeingDefined()) {
    751 +          return true;
    752 +        }
    753 +
    754 +        if (CXXConstructorDecl* ctor = sema.LookupDefaultConstructor(decl)) {
    755 +          may_need_definition.insert(ctor);
    756 +        } else if (CXXDestructorDecl* dtor = sema.LookupDestructor(decl)) {
    757 +          may_need_definition.insert(dtor);
    758 +        }
    759 +
    760 +        return true;
    761 +      }
    762 +
    763 +      Sema& sema;
    764 +      std::set<CXXMethodDecl*> may_need_definition;
    765 +    };
    766 +
    767 +    // Run visitor to collect implicit methods.
    768 +    Visitor v(sema);
    769 +    v.TraverseDecl(tu_decl);
    770 +
    771 +    // For each method collected, let Sema define them.
    772 +    for (CXXMethodDecl* method : v.may_need_definition) {
    773 +      if (!method->isDefaulted() || method->isDeleted() || method->hasBody())
    774 +        continue;
    775 +
    776 +      SourceLocation loc = GetLocation(method->getParent());
    777 +      if (auto* ctor = dyn_cast<CXXConstructorDecl>(method)) {
    778 +        sema.DefineImplicitDefaultConstructor(loc, ctor);
    779 +      } else if (auto* dtor = dyn_cast<CXXDestructorDecl>(method)) {
    780 +        sema.DefineImplicitDestructor(loc, dtor);
    781 +      }
    782 +    }
    783 +
    784 +    // Clang queues up method instantiations. Process them now.
    785 +    sema.PerformPendingInstantiations();
    786 +  }
    787 +
    788    //------------------------------------------------------------
    789    // AST visitors.  We start by adding a visitor callback for
    790    // most of the subclasses of Decl/Stmt/Type listed in:
    791 @@ -3913,14 +3931,13 @@ class IwyuAstConsumer
    792    // TODO(csilvers): we can probably relax this rule in .cc files.
    793    // TODO(csilvers): this should really move into IwyuBaseASTVisitor
    794    // (that way we'll correctly identify need for hash<> in hash_set).
    795 -  // This is a Traverse*() because Visit*() can't call HandleFunctionCall().
    796 -  bool TraverseTypedefDecl(clang::TypedefDecl* decl) {
    797 -    // Before we go up the tree, make sure the parents know we don't
    798 -    // forward-declare the underlying type of a typedef decl.
    799 -    current_ast_node()->set_in_forward_declare_context(false);
    800 -    if (!Base::TraverseTypedefDecl(decl))
    801 -      return false;
    802 -    if (CanIgnoreCurrentASTNode())  return true;
    803 +  // This is called from Traverse*() because Visit*()
    804 +  // can't call HandleFunctionCall().
    805 +  bool HandleAliasedClassMethods(TypedefNameDecl* decl) {
    806 +    if (CanIgnoreCurrentASTNode())
    807 +      return true;
    808 +    if (current_ast_node()->in_forward_declare_context())
    809 +      return true;
    810  
    811      const Type* underlying_type = decl->getUnderlyingType().getTypePtr();
    812      const Decl* underlying_decl = TypeToDeclAsWritten(underlying_type);
    813 @@ -3947,6 +3964,20 @@ class IwyuAstConsumer
    814      return true;
    815    }
    816  
    817 +  bool TraverseTypedefDecl(clang::TypedefDecl* decl) {
    818 +    if (!Base::TraverseTypedefDecl(decl))
    819 +      return false;
    820 +
    821 +    return HandleAliasedClassMethods(decl);
    822 +  }
    823 +
    824 +  bool TraverseTypeAliasDecl(clang::TypeAliasDecl* decl) {
    825 +    if (!Base::TraverseTypeAliasDecl(decl))
    826 +      return false;
    827 +
    828 +    return HandleAliasedClassMethods(decl);
    829 +  }
    830 +
    831    // --- Visitors of types derived from clang::Stmt.
    832  
    833    // Called whenever a variable, function, enum, etc is used.
    834 @@ -4063,18 +4094,21 @@ class IwyuAstConsumer
    835    bool VisitTemplateName(TemplateName template_name) {
    836      if (CanIgnoreCurrentASTNode())  return true;
    837      if (!Base::VisitTemplateName(template_name))  return false;
    838 -    // The only time we can see a TemplateName not in the
    839 -    // context of a TemplateSpecializationType is when it's
    840 -    // the default argument of a template template arg:
    841 +    // We can see TemplateName not in the context of aTemplateSpecializationType
    842 +    // when it's either the default argument of a template template arg:
    843      //    template<template<class T> class A = TplNameWithoutTST> class Foo ...
    844 -    // So that's the only case we need to handle here.
    845 +    // or a deduced template specialization:
    846 +    //    std::pair x(10, 20); // type of x is really std::pair<int, int>
    847 +    // So that's the only cases we need to handle here.
    848      // TODO(csilvers): check if this is really forward-declarable or
    849      // not.  You *could* do something like: 'template<template<class
    850      // T> class A = Foo> class C { A<int>* x; };' and never
    851      // dereference x, but that's pretty unlikely.  So for now, we just
    852      // assume these default template template args always need full
    853      // type info.
    854 -    if (IsDefaultTemplateTemplateArg(current_ast_node())) {
    855 +    const ASTNode* ast_node = current_ast_node();
    856 +    if (ast_node->ParentIsA<DeducedTemplateSpecializationType>() ||
    857 +        IsDefaultTemplateTemplateArg(ast_node)) {
    858        current_ast_node()->set_in_forward_declare_context(false);
    859        ReportDeclUse(CurrentLoc(), template_name.getAsTemplateDecl());
    860      }
    861 @@ -4140,7 +4174,6 @@ class IwyuAction : public ASTFrontendAction {
    862  
    863  #include "iwyu_driver.h"
    864  #include "clang/Frontend/FrontendAction.h"
    865 -#include "llvm/Support/ManagedStatic.h"
    866  #include "llvm/Support/TargetSelect.h"
    867  
    868  using include_what_you_use::OptionsParser;
    869 @@ -4148,12 +4181,11 @@ using include_what_you_use::IwyuAction;
    870  using include_what_you_use::CreateCompilerInstance;
    871  
    872  int main(int argc, char **argv) {
    873 -  // Must initialize X86 target to be able to parse Microsoft inline
    874 -  // assembly. We do this unconditionally, because it allows an IWYU
    875 -  // built for non-X86 targets to parse MS inline asm without choking.
    876 -  LLVMInitializeX86TargetInfo();
    877 -  LLVMInitializeX86TargetMC();
    878 -  LLVMInitializeX86AsmParser();
    879 +  // X86 target is required to parse Microsoft inline assembly, so we hope it's
    880 +  // part of all targets. Clang parser will complain otherwise.
    881 +  llvm::InitializeAllTargetInfos();
    882 +  llvm::InitializeAllTargetMCs();
    883 +  llvm::InitializeAllAsmParsers();
    884  
    885    // The command line should look like
    886    //   path/to/iwyu -Xiwyu --verbose=4 [-Xiwyu --other_iwyu_flag]... CLANG_FLAGS... foo.cc
    887 diff --git a/iwyu_ast_util.cc b/iwyu_ast_util.cc
    888 index 9982145..50477eb 100644
    889 --- a/iwyu_ast_util.cc
    890 +++ b/iwyu_ast_util.cc
    891 @@ -25,7 +25,6 @@
    892  #include "llvm/Support/Casting.h"
    893  #include "llvm/Support/raw_ostream.h"
    894  #include "clang/AST/ASTContext.h"
    895 -#include "clang/AST/ASTDumper.h"
    896  #include "clang/AST/CanonicalType.h"
    897  #include "clang/AST/Decl.h"
    898  #include "clang/AST/DeclBase.h"
    899 @@ -47,7 +46,6 @@ namespace clang {
    900  class FileEntry;
    901  }  // namespace clang
    902  
    903 -using clang::ASTDumper;
    904  using clang::BlockPointerType;
    905  using clang::CXXConstructExpr;
    906  using clang::CXXConstructorDecl;
    907 @@ -446,14 +444,12 @@ string PrintableDecl(const Decl* decl, bool terse/*=true*/) {
    908  string PrintableStmt(const Stmt* stmt) {
    909    std::string buffer;
    910    raw_string_ostream ostream(buffer);
    911 -  ASTDumper dumper(ostream, /*ShowColors=*/false);
    912 -  dumper.Visit(stmt);
    913 +  stmt->dump(ostream, *GlobalSourceManager());
    914    return ostream.str();
    915  }
    916  
    917  void PrintStmt(const Stmt* stmt) {
    918 -  ASTDumper dumper(llvm::errs(), /*ShowColors=*/false);
    919 -  dumper.Visit(stmt);
    920 +  stmt->dump(*GlobalSourceManager());  // This prints to errs().
    921  }
    922  
    923  string PrintableType(const Type* type) {
    924 @@ -1095,11 +1091,14 @@ bool DeclsAreInSameClass(const Decl* decl1, const Decl* decl2) {
    925    return decl1->getDeclContext()->isRecord();
    926  }
    927  
    928 -bool IsBuiltinFunction(const clang::NamedDecl* decl,
    929 -                       const std::string& symbol_name) {
    930 +bool IsBuiltinFunction(const clang::NamedDecl* decl) {
    931    if (const clang::IdentifierInfo* iden = decl->getIdentifier()) {
    932 -    return iden->getBuiltinID() != 0 &&
    933 -           !clang::Builtin::Context::isBuiltinFunc(symbol_name.c_str());
    934 +    unsigned builtin_id = iden->getBuiltinID();
    935 +    if (builtin_id != 0) {
    936 +      const clang::Builtin::Context& ctx = decl->getASTContext().BuiltinInfo;
    937 +      return !ctx.isPredefinedLibFunction(builtin_id) &&
    938 +             !ctx.isHeaderDependentFunction(builtin_id);
    939 +    }
    940    }
    941    return false;
    942  }
    943 diff --git a/iwyu_ast_util.h b/iwyu_ast_util.h
    944 index 18ddf2d..28668f7 100644
    945 --- a/iwyu_ast_util.h
    946 +++ b/iwyu_ast_util.h
    947 @@ -652,8 +652,7 @@ const clang::NamedDecl* GetNonfriendClassRedecl(const clang::NamedDecl* decl);
    948  bool DeclsAreInSameClass(const clang::Decl* decl1, const clang::Decl* decl2);
    949  
    950  // Returns true if the given decl/name is a builtin function
    951 -bool IsBuiltinFunction(const clang::NamedDecl* decl,
    952 -                       const std::string& symbol_name);
    953 +bool IsBuiltinFunction(const clang::NamedDecl* decl);
    954  
    955  // --- Utilities for Type.
    956  
    957 diff --git a/iwyu_driver.cc b/iwyu_driver.cc
    958 index 42fea35..d9b96b7 100644
    959 --- a/iwyu_driver.cc
    960 +++ b/iwyu_driver.cc
    961 @@ -205,8 +205,11 @@ CompilerInstance* CreateCompilerInstance(int argc, const char **argv) {
    962  
    963    // Initialize a compiler invocation object from the clang (-cc1) arguments.
    964    const ArgStringList &cc_arguments = command.getArguments();
    965 +  const char** args_start = const_cast<const char**>(cc_arguments.data());
    966 +  const char** args_end = args_start + cc_arguments.size();
    967    std::shared_ptr<CompilerInvocation> invocation(new CompilerInvocation);
    968 -  CompilerInvocation::CreateFromArgs(*invocation, cc_arguments, diagnostics);
    969 +  CompilerInvocation::CreateFromArgs(*invocation,
    970 +                                     args_start, args_end, diagnostics);
    971    invocation->getFrontendOpts().DisableFree = false;
    972  
    973    // Use libc++ headers bundled with Xcode.app on macOS.
    974 diff --git a/iwyu_globals.cc b/iwyu_globals.cc
    975 index 36ac3ae..96b728c 100644
    976 --- a/iwyu_globals.cc
    977 +++ b/iwyu_globals.cc
    978 @@ -91,6 +91,8 @@ static void PrintHelp(const char* extra_msg) {
    979           "        the maximum line length can still be exceeded with long\n"
    980           "        file names (default: 80).\n"
    981           "   --no_comments: do not add 'why' comments.\n"
    982 +         "   --update_comments: always add 'why' comments, even if no\n"
    983 +         "        #include lines need to be added or removed.\n"
    984           "   --no_fwd_decls: do not use forward declarations.\n"
    985           "   --verbose=<level>: the higher the level, the more output.\n"
    986           "   --quoted_includes_first: when sorting includes, place quoted\n"
    987 @@ -163,6 +165,7 @@ CommandlineFlags::CommandlineFlags()
    988        prefix_header_include_policy(CommandlineFlags::kAdd),
    989        pch_in_code(false),
    990        no_comments(false),
    991 +      update_comments(false),
    992        no_fwd_decls(false),
    993        quoted_includes_first(false),
    994        cxx17ns(false) {
    995 @@ -182,6 +185,7 @@ int CommandlineFlags::ParseArgv(int argc, char** argv) {
    996      {"pch_in_code", no_argument, nullptr, 'h'},
    997      {"max_line_length", required_argument, nullptr, 'l'},
    998      {"no_comments", no_argument, nullptr, 'o'},
    999 +    {"update_comments", no_argument, nullptr, 'u'},
   1000      {"no_fwd_decls", no_argument, nullptr, 'f'},
   1001      {"quoted_includes_first", no_argument, nullptr, 'q' },
   1002      {"cxx17ns", no_argument, nullptr, 'C'},
   1003 @@ -197,6 +201,7 @@ int CommandlineFlags::ParseArgv(int argc, char** argv) {
   1004        case 'm': mapping_files.push_back(optarg); break;
   1005        case 'n': no_default_mappings = true; break;
   1006        case 'o': no_comments = true; break;
   1007 +      case 'u': update_comments = true; break;
   1008        case 'f': no_fwd_decls = true; break;
   1009        case 'x':
   1010          if (strcmp(optarg, "add") == 0) {
   1011 diff --git a/iwyu_globals.h b/iwyu_globals.h
   1012 index 242cdf6..eefb8ce 100644
   1013 --- a/iwyu_globals.h
   1014 +++ b/iwyu_globals.h
   1015 @@ -98,6 +98,7 @@ struct CommandlineFlags {
   1016    PrefixHeaderIncludePolicy prefix_header_include_policy;
   1017    bool pch_in_code;   // Treat the first seen include as a PCH. No short option.
   1018    bool no_comments;   // Disable 'why' comments. No short option.
   1019 +  bool update_comments; // Force 'why' comments. No short option.
   1020    bool no_fwd_decls;  // Disable forward declarations.
   1021    bool quoted_includes_first; // Place quoted includes first in sort order.
   1022    bool cxx17ns; // -C: C++17 nested namespace syntax
   1023 diff --git a/iwyu_include_picker.cc b/iwyu_include_picker.cc
   1024 index f5d2dbc..77928fa 100644
   1025 --- a/iwyu_include_picker.cc
   1026 +++ b/iwyu_include_picker.cc
   1027 @@ -16,6 +16,7 @@
   1028  // not hash_map: it's not as portable and needs hash<string>.
   1029  #include <map>                          // for map, map<>::mapped_type, etc
   1030  #include <memory>
   1031 +#include <regex>
   1032  #include <string>                       // for string, basic_string, etc
   1033  #include <system_error>                 // for error_code
   1034  #include <utility>                      // for pair, make_pair
   1035 @@ -33,7 +34,6 @@
   1036  #include "llvm/Support/ErrorOr.h"
   1037  #include "llvm/Support/FileSystem.h"
   1038  #include "llvm/Support/MemoryBuffer.h"
   1039 -#include "llvm/Support/Regex.h"
   1040  #include "llvm/Support/SourceMgr.h"
   1041  #include "llvm/Support/YAMLParser.h"
   1042  #include "clang/Basic/FileManager.h"
   1043 @@ -89,19 +89,33 @@ const IncludeMapEntry libc_symbol_map[] = {
   1044    // an option for this type.  That's the preferred #include all else
   1045    // equal.  The visibility on the symbol-name is ignored; by convention
   1046    // we always set it to kPrivate.
   1047 -  { "blksize_t", kPrivate, "<sys/types.h>", kPublic },
   1048 -  { "blkcnt_t", kPrivate, "<sys/stat.h>", kPublic },
   1049 +  { "aiocb", kPrivate, "<aio.h>", kPublic },
   1050    { "blkcnt_t", kPrivate, "<sys/types.h>", kPublic },
   1051 +  { "blkcnt_t", kPrivate, "<sys/stat.h>", kPublic },
   1052 +  { "blksize_t", kPrivate, "<sys/types.h>", kPublic },
   1053    { "blksize_t", kPrivate, "<sys/stat.h>", kPublic },
   1054 +  { "cc_t", kPrivate, "<termios.h>", kPublic },
   1055    { "clock_t", kPrivate, "<sys/types.h>", kPublic },
   1056 +  { "clock_t", kPrivate, "<sys/time.h>", kPublic },
   1057    { "clock_t", kPrivate, "<time.h>", kPublic },
   1058 +  { "clockid_t", kPrivate, "<sys/types.h>", kPublic },
   1059 +  { "clockid_t", kPrivate, "<time.h>", kPublic },
   1060    { "daddr_t", kPrivate, "<sys/types.h>", kPublic },
   1061    { "daddr_t", kPrivate, "<rpc/types.h>", kPublic },
   1062    { "dev_t", kPrivate, "<sys/types.h>", kPublic },
   1063    { "dev_t", kPrivate, "<sys/stat.h>", kPublic },
   1064 +  { "div_t", kPrivate, "<stdlib.h>", kPublic },
   1065 +  { "double_t", kPrivate, "<math.h>", kPublic },
   1066    { "error_t", kPrivate, "<errno.h>", kPublic },
   1067    { "error_t", kPrivate, "<argp.h>", kPublic },
   1068    { "error_t", kPrivate, "<argz.h>", kPublic },
   1069 +  { "fd_set", kPrivate, "<sys/select.h>", kPublic },
   1070 +  { "fd_set", kPrivate, "<sys/time.h>", kPublic },
   1071 +  { "fenv_t", kPrivate, "<fenv.h>", kPublic },
   1072 +  { "fexcept_t", kPrivate, "<fenv.h>", kPublic },
   1073 +  { "FILE", kPrivate, "<stdio.h>", kPublic },
   1074 +  { "FILE", kPrivate, "<wchar.h>", kPublic },
   1075 +  { "float_t", kPrivate, "<math.h>", kPublic },
   1076    { "fsblkcnt_t", kPrivate, "<sys/types.h>", kPublic },
   1077    { "fsblkcnt_t", kPrivate, "<sys/statvfs.h>", kPublic },
   1078    { "fsfilcnt_t", kPrivate, "<sys/types.h>", kPublic },
   1079 @@ -109,93 +123,175 @@ const IncludeMapEntry libc_symbol_map[] = {
   1080    { "gid_t", kPrivate, "<sys/types.h>", kPublic },
   1081    { "gid_t", kPrivate, "<grp.h>", kPublic },
   1082    { "gid_t", kPrivate, "<pwd.h>", kPublic },
   1083 +  { "gid_t", kPrivate, "<signal.h>", kPublic },
   1084    { "gid_t", kPrivate, "<stropts.h>", kPublic },
   1085    { "gid_t", kPrivate, "<sys/ipc.h>", kPublic },
   1086    { "gid_t", kPrivate, "<sys/stat.h>", kPublic },
   1087    { "gid_t", kPrivate, "<unistd.h>", kPublic },
   1088    { "id_t", kPrivate, "<sys/types.h>", kPublic },
   1089    { "id_t", kPrivate, "<sys/resource.h>", kPublic },
   1090 +  { "imaxdiv_t", kPrivate, "<inttypes.h>", kPublic },
   1091 +  { "intmax_t", kPrivate, "<stdint.h>", kPublic },
   1092 +  { "intmax_t", kPrivate, "<inttypes.h>", kPublic },
   1093 +  { "uintmax_t", kPrivate, "<stdint.h>", kPublic },
   1094 +  { "uintmax_t", kPrivate, "<inttypes.h>", kPublic },
   1095    { "ino64_t", kPrivate, "<sys/types.h>", kPublic },
   1096    { "ino64_t", kPrivate, "<dirent.h>", kPublic },
   1097    { "ino_t", kPrivate, "<sys/types.h>", kPublic },
   1098    { "ino_t", kPrivate, "<dirent.h>", kPublic },
   1099    { "ino_t", kPrivate, "<sys/stat.h>", kPublic },
   1100 -  { "int8_t", kPrivate, "<sys/types.h>", kPublic },
   1101    { "int8_t", kPrivate, "<stdint.h>", kPublic },
   1102 +  { "int8_t", kPrivate, "<inttypes.h>", kPublic },
   1103    { "int16_t", kPrivate, "<stdint.h>", kPublic },
   1104 +  { "int16_t", kPrivate, "<inttypes.h>", kPublic },
   1105    { "int32_t", kPrivate, "<stdint.h>", kPublic },
   1106 +  { "int32_t", kPrivate, "<inttypes.h>", kPublic },
   1107    { "int64_t", kPrivate, "<stdint.h>", kPublic },
   1108 +  { "int64_t", kPrivate, "<inttypes.h>", kPublic },
   1109    { "uint8_t", kPrivate, "<stdint.h>", kPublic },
   1110 +  { "uint8_t", kPrivate, "<inttypes.h>", kPublic },
   1111    { "uint16_t", kPrivate, "<stdint.h>", kPublic },
   1112 +  { "uint16_t", kPrivate, "<inttypes.h>", kPublic },
   1113    { "uint32_t", kPrivate, "<stdint.h>", kPublic },
   1114 +  { "uint32_t", kPrivate, "<inttypes.h>", kPublic },
   1115    { "uint64_t", kPrivate, "<stdint.h>", kPublic },
   1116 +  { "uint64_t", kPrivate, "<inttypes.h>", kPublic },
   1117    { "intptr_t", kPrivate, "<stdint.h>", kPublic },
   1118 +  { "intptr_t", kPrivate, "<inttypes.h>", kPublic },
   1119    { "uintptr_t", kPrivate, "<stdint.h>", kPublic },
   1120 -  { "intptr_t", kPrivate, "<unistd.h>", kPublic },
   1121 +  { "uintptr_t", kPrivate, "<inttypes.h>", kPublic },
   1122    { "key_t", kPrivate, "<sys/types.h>", kPublic },
   1123    { "key_t", kPrivate, "<sys/ipc.h>", kPublic },
   1124 +  { "lconv", kPrivate, "<locale.h>", kPublic },
   1125 +  { "ldiv_t", kPrivate, "<stdlib.h>", kPublic },
   1126 +  { "lldiv_t", kPrivate, "<stdlib.h>", kPublic },
   1127    { "max_align_t", kPrivate, "<stddef.h>", kPublic },
   1128    { "mode_t", kPrivate, "<sys/types.h>", kPublic },
   1129 -  { "mode_t", kPrivate, "<sys/stat.h>", kPublic },
   1130 +  { "mode_t", kPrivate, "<fcntl.h>", kPublic },
   1131 +  { "mode_t", kPrivate, "<ndbm.h>", kPublic },
   1132 +  { "mode_t", kPrivate, "<spawn.h>", kPublic },
   1133    { "mode_t", kPrivate, "<sys/ipc.h>", kPublic },
   1134    { "mode_t", kPrivate, "<sys/mman.h>", kPublic },
   1135 +  { "mode_t", kPrivate, "<sys/stat.h>", kPublic },
   1136    { "nlink_t", kPrivate, "<sys/types.h>", kPublic },
   1137    { "nlink_t", kPrivate, "<sys/stat.h>", kPublic },
   1138    { "off64_t", kPrivate, "<sys/types.h>", kPublic },
   1139    { "off64_t", kPrivate, "<unistd.h>", kPublic },
   1140    { "off_t", kPrivate, "<sys/types.h>", kPublic },
   1141 -  { "off_t", kPrivate, "<unistd.h>", kPublic },
   1142 -  { "off_t", kPrivate, "<sys/stat.h>", kPublic },
   1143 +  { "off_t", kPrivate, "<aio.h>", kPublic },
   1144 +  { "off_t", kPrivate, "<fcntl.h>", kPublic },
   1145 +  { "off_t", kPrivate, "<stdio.h>", kPublic },
   1146    { "off_t", kPrivate, "<sys/mman.h>", kPublic },
   1147 +  { "off_t", kPrivate, "<sys/stat.h>", kPublic },
   1148 +  { "off_t", kPrivate, "<unistd.h>", kPublic },
   1149    { "pid_t", kPrivate, "<sys/types.h>", kPublic },
   1150 -  { "pid_t", kPrivate, "<unistd.h>", kPublic },
   1151 +  { "pid_t", kPrivate, "<fcntl.h>", kPublic },
   1152 +  { "pid_t", kPrivate, "<sched.h>", kPublic },
   1153    { "pid_t", kPrivate, "<signal.h>", kPublic },
   1154 +  { "pid_t", kPrivate, "<spawn.h>", kPublic },
   1155    { "pid_t", kPrivate, "<sys/msg.h>", kPublic },
   1156 +  { "pid_t", kPrivate, "<sys/sem.h>", kPublic },
   1157    { "pid_t", kPrivate, "<sys/shm.h>", kPublic },
   1158 +  { "pid_t", kPrivate, "<sys/wait.h>", kPublic },
   1159    { "pid_t", kPrivate, "<termios.h>", kPublic },
   1160    { "pid_t", kPrivate, "<time.h>", kPublic },
   1161 +  { "pid_t", kPrivate, "<unistd.h>", kPublic },
   1162    { "pid_t", kPrivate, "<utmpx.h>", kPublic },
   1163    { "ptrdiff_t", kPrivate, "<stddef.h>", kPublic },
   1164 +  { "regex_t", kPrivate, "<regex.h>", kPublic },
   1165 +  { "regmatch_t", kPrivate, "<regex.h>", kPublic },
   1166 +  { "regoff_t", kPrivate, "<regex.h>", kPublic },
   1167 +  { "sigevent", kPrivate, "<signal.h>", kPublic },
   1168 +  { "sigevent", kPrivate, "<aio.h>", kPublic },
   1169 +  { "sigevent", kPrivate, "<mqueue.h>", kPublic },
   1170 +  { "sigevent", kPrivate, "<time.h>", kPublic },
   1171 +  { "siginfo_t", kPrivate, "<signal.h>", kPublic },
   1172 +  { "siginfo_t", kPrivate, "<sys/wait.h>", kPublic },
   1173    { "sigset_t", kPrivate, "<signal.h>", kPublic },
   1174 -  { "sigset_t", kPrivate, "<sys/epoll.h>", kPublic },
   1175 +  { "sigset_t", kPrivate, "<spawn.h>", kPublic },
   1176    { "sigset_t", kPrivate, "<sys/select.h>", kPublic },
   1177 -  { "socklen_t", kPrivate, "<bits/socket.h>", kPrivate },
   1178 -  { "socklen_t", kPrivate, "<unistd.h>", kPublic },
   1179 -  { "socklen_t", kPrivate, "<arpa/inet.h>", kPublic },
   1180 +  { "sigval", kPrivate, "<signal.h>", kPublic },
   1181 +  { "sockaddr", kPrivate, "<sys/socket.h>", kPublic },
   1182 +  { "socklen_t", kPrivate, "<sys/socket.h>", kPublic },
   1183 +  { "socklen_t", kPrivate, "<netdb.h>", kPublic },
   1184    { "ssize_t", kPrivate, "<sys/types.h>", kPublic },
   1185 -  { "ssize_t", kPrivate, "<unistd.h>", kPublic },
   1186 +  { "ssize_t", kPrivate, "<aio.h>", kPublic },
   1187    { "ssize_t", kPrivate, "<monetary.h>", kPublic },
   1188 +  { "ssize_t", kPrivate, "<mqueue.h>", kPublic },
   1189 +  { "ssize_t", kPrivate, "<stdio.h>", kPublic },
   1190    { "ssize_t", kPrivate, "<sys/msg.h>", kPublic },
   1191 +  { "ssize_t", kPrivate, "<sys/socket.h>", kPublic },
   1192 +  { "ssize_t", kPrivate, "<sys/uio.h>", kPublic },
   1193 +  { "ssize_t", kPrivate, "<unistd.h>", kPublic },
   1194    { "suseconds_t", kPrivate, "<sys/types.h>", kPublic },
   1195 -  { "suseconds_t", kPrivate, "<sys/time.h>", kPublic },
   1196    { "suseconds_t", kPrivate, "<sys/select.h>", kPublic },
   1197 -  { "time_t", kPrivate, "<sys/types.h>", kPublic },
   1198 +  { "suseconds_t", kPrivate, "<sys/time.h>", kPublic },
   1199    { "time_t", kPrivate, "<time.h>", kPublic },
   1200 +  { "time_t", kPrivate, "<sched.h>", kPublic },
   1201 +  { "time_t", kPrivate, "<sys/msg.h>", kPublic },
   1202 +  { "time_t", kPrivate, "<sys/select.h>", kPublic },
   1203 +  { "time_t", kPrivate, "<sys/sem.h>", kPublic },
   1204 +  { "time_t", kPrivate, "<sys/shm.h>", kPublic },
   1205 +  { "time_t", kPrivate, "<sys/stat.h>", kPublic },
   1206 +  { "time_t", kPrivate, "<sys/time.h>", kPublic },
   1207 +  { "time_t", kPrivate, "<sys/types.h>", kPublic },
   1208 +  { "time_t", kPrivate, "<utime.h>", kPublic },
   1209 +  { "timer_t", kPrivate, "<sys/types.h>", kPublic },
   1210 +  { "timer_t", kPrivate, "<time.h>", kPublic },
   1211    { "timespec", kPrivate, "<time.h>", kPublic },
   1212 +  { "timespec", kPrivate, "<aio.h>", kPublic },
   1213 +  { "timespec", kPrivate, "<mqueue.h>", kPublic },
   1214 +  { "timespec", kPrivate, "<sched.h>", kPublic },
   1215 +  { "timespec", kPrivate, "<signal.h>", kPublic },
   1216 +  { "timespec", kPrivate, "<sys/select.h>", kPublic },
   1217 +  { "timespec", kPrivate, "<sys/stat.h>", kPublic },
   1218    { "timeval", kPrivate, "<sys/time.h>", kPublic },
   1219 +  { "timeval", kPrivate, "<sys/resource.h>", kPublic },
   1220 +  { "timeval", kPrivate, "<sys/select.h>", kPublic },
   1221 +  { "timeval", kPrivate, "<utmpx.h>", kPublic },
   1222    { "u_char", kPrivate, "<sys/types.h>", kPublic },
   1223    { "u_char", kPrivate, "<rpc/types.h>", kPublic },
   1224    { "uid_t", kPrivate, "<sys/types.h>", kPublic },
   1225 -  { "uid_t", kPrivate, "<unistd.h>", kPublic },
   1226    { "uid_t", kPrivate, "<pwd.h>", kPublic },
   1227    { "uid_t", kPrivate, "<signal.h>", kPublic },
   1228    { "uid_t", kPrivate, "<stropts.h>", kPublic },
   1229    { "uid_t", kPrivate, "<sys/ipc.h>", kPublic },
   1230    { "uid_t", kPrivate, "<sys/stat.h>", kPublic },
   1231 +  { "uid_t", kPrivate, "<unistd.h>", kPublic },
   1232    { "useconds_t", kPrivate, "<sys/types.h>", kPublic },
   1233    { "useconds_t", kPrivate, "<unistd.h>", kPublic },
   1234    { "wchar_t", kPrivate, "<stddef.h>", kPublic },
   1235    { "wchar_t", kPrivate, "<stdlib.h>", kPublic },
   1236 -  // glob.h seems to define size_t if necessary, but it should come from stddef.
   1237    // It is unspecified if the cname headers provide ::size_t.
   1238    // <locale.h> is the one header which defines NULL but not size_t.
   1239    { "size_t", kPrivate, "<stddef.h>", kPublic },  // 'canonical' location for size_t
   1240 +  { "size_t", kPrivate, "<aio.h>", kPublic },
   1241 +  { "size_t", kPrivate, "<glob.h>", kPublic },
   1242 +  { "size_t", kPrivate, "<grp.h>", kPublic },
   1243 +  { "size_t", kPrivate, "<iconv.h>", kPublic },
   1244 +  { "size_t", kPrivate, "<monetary.h>", kPublic },
   1245 +  { "size_t", kPrivate, "<mqueue.h>", kPublic },
   1246 +  { "size_t", kPrivate, "<ndbm.h>", kPublic },
   1247 +  { "size_t", kPrivate, "<pwd.h>", kPublic },
   1248 +  { "size_t", kPrivate, "<regex.h>", kPublic },
   1249 +  { "size_t", kPrivate, "<search.h>", kPublic },
   1250 +  { "size_t", kPrivate, "<signal.h>", kPublic },
   1251    { "size_t", kPrivate, "<stdio.h>", kPublic },
   1252    { "size_t", kPrivate, "<stdlib.h>", kPublic },
   1253    { "size_t", kPrivate, "<string.h>", kPublic },
   1254 +  { "size_t", kPrivate, "<strings.h>", kPublic },
   1255 +  { "size_t", kPrivate, "<sys/mman.h>", kPublic },
   1256 +  { "size_t", kPrivate, "<sys/msg.h>", kPublic },
   1257 +  { "size_t", kPrivate, "<sys/sem.h>", kPublic },
   1258 +  { "size_t", kPrivate, "<sys/shm.h>", kPublic },
   1259 +  { "size_t", kPrivate, "<sys/socket.h>", kPublic },
   1260 +  { "size_t", kPrivate, "<sys/types.h>", kPublic },
   1261 +  { "size_t", kPrivate, "<sys/uio.h>", kPublic },
   1262    { "size_t", kPrivate, "<time.h>", kPublic },
   1263    { "size_t", kPrivate, "<uchar.h>", kPublic },
   1264 +  { "size_t", kPrivate, "<unistd.h>", kPublic },
   1265    { "size_t", kPrivate, "<wchar.h>", kPublic },
   1266 +  { "size_t", kPrivate, "<wordexp.h>", kPublic },
   1267    // Macros that can be defined in more than one file, don't have the
   1268    // same __foo_defined guard that other types do, so the grep above
   1269    // doesn't discover them.  Until I figure out a better way, I just
   1270 @@ -204,6 +300,8 @@ const IncludeMapEntry libc_symbol_map[] = {
   1271    { "EOF", kPrivate, "<libio.h>", kPublic },
   1272    { "FILE", kPrivate, "<stdio.h>", kPublic },
   1273    { "va_list", kPrivate, "<stdarg.h>", kPublic },
   1274 +  { "va_list", kPrivate, "<stdio.h>", kPublic },
   1275 +  { "va_list", kPrivate, "<wchar.h>", kPublic },
   1276    // These are symbols that could be defined in either stdlib.h or
   1277    // malloc.h, but we always want the stdlib location.
   1278    { "malloc", kPrivate, "<stdlib.h>", kPublic },
   1279 @@ -1315,16 +1413,17 @@ void IncludePicker::ExpandRegexes() {
   1280      for (const string& regex_key : filepath_include_map_regex_keys) {
   1281        const vector<MappedInclude>& map_to = filepath_include_map_[regex_key];
   1282        // Enclose the regex in ^(...)$ for full match.
   1283 -      llvm::Regex regex(std::string("^(" + regex_key.substr(1) + ")$"));
   1284 -      if (regex.match(hdr, nullptr) && !ContainsQuotedInclude(map_to, hdr)) {
   1285 +      std::regex regex(std::string("^(" + regex_key.substr(1) + ")$"));
   1286 +      if (std::regex_match(hdr, regex) &&
   1287 +          !ContainsQuotedInclude(map_to, hdr)) {
   1288          Extend(&filepath_include_map_[hdr], filepath_include_map_[regex_key]);
   1289          MarkVisibility(&include_visibility_map_, hdr,
   1290                         include_visibility_map_[regex_key]);
   1291        }
   1292      }
   1293      for (const string& regex_key : friend_to_headers_map_regex_keys) {
   1294 -      llvm::Regex regex(std::string("^(" + regex_key.substr(1) + ")$"));
   1295 -      if (regex.match(hdr, nullptr)) {
   1296 +      std::regex regex(std::string("^(" + regex_key.substr(1) + ")$"));
   1297 +      if (std::regex_match(hdr, regex)) {
   1298          InsertAllInto(friend_to_headers_map_[regex_key],
   1299                        &friend_to_headers_map_[hdr]);
   1300        }
   1301 diff --git a/iwyu_output.cc b/iwyu_output.cc
   1302 index e6bb851..d805242 100644
   1303 --- a/iwyu_output.cc
   1304 +++ b/iwyu_output.cc
   1305 @@ -1161,7 +1161,7 @@ void ProcessFullUse(OneUse* use,
   1306    // We normally ignore uses for builtins, but when there is a mapping defined
   1307    // for the symbol, we should respect that.  So, we need to determine whether
   1308    // the symbol has any mappings.
   1309 -  bool is_builtin_function = IsBuiltinFunction(use->decl(), use->symbol_name());
   1310 +  bool is_builtin_function = IsBuiltinFunction(use->decl());
   1311  
   1312    bool is_builtin_function_with_mappings =
   1313        is_builtin_function && HasMapping(use->symbol_name());
   1314 @@ -1987,7 +1987,7 @@ size_t PrintableDiffs(const string& filename,
   1315        break;
   1316      }
   1317    }
   1318 -  if (no_adds_or_deletes) {
   1319 +  if (no_adds_or_deletes && !GlobalFlags().update_comments) {
   1320      output = "\n(" + filename + " has correct #includes/fwd-decls)\n";
   1321      return 0;
   1322    }
   1323 diff --git a/iwyu_port.h b/iwyu_port.h
   1324 index d890575..e1fabb3 100644
   1325 --- a/iwyu_port.h
   1326 +++ b/iwyu_port.h
   1327 @@ -26,7 +26,7 @@ class FatalMessageEmitter {
   1328    FatalMessageEmitter(const char* file, int line, const char* message) {
   1329      stream() << file << ":" << line << ": Assertion failed: " << message;
   1330    }
   1331 -  LLVM_ATTRIBUTE_NORETURN ~FatalMessageEmitter() {
   1332 +  [[noreturn]] ~FatalMessageEmitter() {
   1333      stream() << "\n";
   1334      ::abort();
   1335  #ifdef LLVM_BUILTIN_UNREACHABLE
   1336 diff --git a/iwyu_preprocessor.cc b/iwyu_preprocessor.cc
   1337 index 6dc70bf..dc72b2b 100644
   1338 --- a/iwyu_preprocessor.cc
   1339 +++ b/iwyu_preprocessor.cc
   1340 @@ -34,7 +34,6 @@
   1341  #include "clang/Lex/MacroInfo.h"
   1342  
   1343  using clang::FileEntry;
   1344 -using clang::FileEntryRef;
   1345  using clang::FileID;
   1346  using clang::MacroDefinition;
   1347  using clang::MacroDirective;
   1348 @@ -704,7 +703,7 @@ void IwyuPreprocessorInfo::FileChanged(SourceLocation loc,
   1349  // Called when we see an #include, but decide we don't need to
   1350  // actually read it because it's already been #included (and is
   1351  // protected by a header guard).
   1352 -void IwyuPreprocessorInfo::FileSkipped(const FileEntryRef& file,
   1353 +void IwyuPreprocessorInfo::FileSkipped(const FileEntry& file,
   1354                                         const Token &filename,
   1355                                         SrcMgr::CharacteristicKind file_type) {
   1356    CHECK_(include_filename_loc_.isValid() &&
   1357 @@ -715,11 +714,11 @@ void IwyuPreprocessorInfo::FileSkipped(const FileEntryRef& file,
   1358        GetInstantiationLoc(filename.getLocation());
   1359    ERRSYM(GetFileEntry(include_loc))
   1360        << "[ (#include)  ] " << include_name_as_written
   1361 -      << " (" << GetFilePath(&file.getFileEntry()) << ")\n";
   1362 +      << " (" << GetFilePath(&file) << ")\n";
   1363  
   1364 -  AddDirectInclude(include_loc, &file.getFileEntry(), include_name_as_written);
   1365 -  if (ShouldReportIWYUViolationsFor(&file.getFileEntry())) {
   1366 -    files_to_report_iwyu_violations_for_.insert(&file.getFileEntry());
   1367 +  AddDirectInclude(include_loc, &file, include_name_as_written);
   1368 +  if (ShouldReportIWYUViolationsFor(&file)) {
   1369 +    files_to_report_iwyu_violations_for_.insert(&file);
   1370    }
   1371  }
   1372  
   1373 diff --git a/iwyu_preprocessor.h b/iwyu_preprocessor.h
   1374 index c46dbc9..00073ce 100644
   1375 --- a/iwyu_preprocessor.h
   1376 +++ b/iwyu_preprocessor.h
   1377 @@ -203,7 +203,7 @@ class IwyuPreprocessorInfo : public clang::PPCallbacks,
   1378    void FileChanged(clang::SourceLocation loc, FileChangeReason reason,
   1379                     clang::SrcMgr::CharacteristicKind file_type,
   1380                     clang::FileID exiting_from_id) override;
   1381 -  void FileSkipped(const clang::FileEntryRef& file, const clang::Token &filename,
   1382 +  void FileSkipped(const clang::FileEntry& file, const clang::Token &filename,
   1383                     clang::SrcMgr::CharacteristicKind file_type) override;
   1384    // FileChanged is actually a multi-plexer for 4 different callbacks.
   1385    void FileChanged_EnterFile(clang::SourceLocation file_beginning);
   1386 diff --git a/iwyu_tool.py b/iwyu_tool.py
   1387 index eaf0abc..45b2a4a 100755
   1388 --- a/iwyu_tool.py
   1389 +++ b/iwyu_tool.py
   1390 @@ -42,6 +42,7 @@ import subprocess
   1391  
   1392  CORRECT_RE = re.compile(r'^\((.*?) has correct #includes/fwd-decls\)$')
   1393  SHOULD_ADD_RE = re.compile(r'^(.*?) should add these lines:$')
   1394 +ADD_RE = re.compile('^(.*?) +// (.*)$')
   1395  SHOULD_REMOVE_RE = re.compile(r'^(.*?) should remove these lines:$')
   1396  FULL_LIST_RE = re.compile(r'The full include-list for (.*?):$')
   1397  END_RE = re.compile(r'^---$')
   1398 @@ -80,14 +81,17 @@ def clang_formatter(output):
   1399          elif state[0] == GENERAL:
   1400              formatted.append(line)
   1401          elif state[0] == ADD:
   1402 -            formatted.append('%s:1:1: error: add the following line' % state[1])
   1403 -            formatted.append(line)
   1404 +            match = ADD_RE.match(line)
   1405 +            if match:
   1406 +                formatted.append("%s:1:1: error: add '%s' (%s)" %
   1407 +                                 (state[1], match.group(1), match.group(2)))
   1408 +            else:
   1409 +                formatted.append("%s:1:1: error: add '%s'" % (state[1], line))
   1410          elif state[0] == REMOVE:
   1411              match = LINES_RE.match(line)
   1412              line_no = match.group(2) if match else '1'
   1413 -            formatted.append('%s:%s:1: error: remove the following line' %
   1414 -                             (state[1], line_no))
   1415 -            formatted.append(match.group(1))
   1416 +            formatted.append("%s:%s:1: error: superfluous '%s'" %
   1417 +                             (state[1], line_no, match.group(1)))
   1418  
   1419      return os.linesep.join(formatted)
   1420  
   1421 diff --git a/iwyu_version.h b/iwyu_version.h
   1422 index 12a451f..7c3b41c 100644
   1423 --- a/iwyu_version.h
   1424 +++ b/iwyu_version.h
   1425 @@ -10,6 +10,6 @@
   1426  #ifndef INCLUDE_WHAT_YOU_USE_IWYU_VERSION_H_
   1427  #define INCLUDE_WHAT_YOU_USE_IWYU_VERSION_H_
   1428  
   1429 -#define IWYU_VERSION_STRING "0.16"
   1430 +#define IWYU_VERSION_STRING "0.17"
   1431  
   1432  #endif  // INCLUDE_WHAT_YOU_USE_IWYU_VERSION_H_
   1433 diff --git a/tests/c/libbuiltins-direct.h b/tests/c/libbuiltins-direct.h
   1434 new file mode 100644
   1435 index 0000000..eef6b58
   1436 --- /dev/null
   1437 +++ b/tests/c/libbuiltins-direct.h
   1438 @@ -0,0 +1,10 @@
   1439 +//===--- libbuiltins-direct.h - test input file for iwyu ------------------===//
   1440 +//
   1441 +//                     The LLVM Compiler Infrastructure
   1442 +//
   1443 +// This file is distributed under the University of Illinois Open Source
   1444 +// License. See LICENSE.TXT for details.
   1445 +//
   1446 +//===----------------------------------------------------------------------===//
   1447 +
   1448 +#include <math.h>
   1449 diff --git a/tests/c/libbuiltins.c b/tests/c/libbuiltins.c
   1450 new file mode 100644
   1451 index 0000000..4ba3033
   1452 --- /dev/null
   1453 +++ b/tests/c/libbuiltins.c
   1454 @@ -0,0 +1,34 @@
   1455 +//===--- libbuiltins.c - test input file for iwyu -------------------------===//
   1456 +//
   1457 +//                     The LLVM Compiler Infrastructure
   1458 +//
   1459 +// This file is distributed under the University of Illinois Open Source
   1460 +// License. See LICENSE.TXT for details.
   1461 +//
   1462 +//===----------------------------------------------------------------------===//
   1463 +
   1464 +// Library builtins are, like normal builtins, compiled down to an intrinsic,
   1465 +// but a header still needs to be included for the program to be valid. The math
   1466 +// library (pow, round, etc) is a typical example.
   1467 +
   1468 +// IWYU_ARGS: -I .
   1469 +
   1470 +#include "tests/c/libbuiltins-direct.h"
   1471 +
   1472 +float kapow(float x) {
   1473 +  // IWYU: pow is...*math.h
   1474 +  return pow(x, 2.0F);
   1475 +}
   1476 +
   1477 +/**** IWYU_SUMMARY
   1478 +
   1479 +tests/c/libbuiltins.c should add these lines:
   1480 +#include <math.h>
   1481 +
   1482 +tests/c/libbuiltins.c should remove these lines:
   1483 +- #include "tests/c/libbuiltins-direct.h"  // lines XX-XX
   1484 +
   1485 +The full include-list for tests/c/libbuiltins.c:
   1486 +#include <math.h>  // for pow
   1487 +
   1488 +***** IWYU_SUMMARY */
   1489 diff --git a/tests/cxx/badinc.cc b/tests/cxx/badinc.cc
   1490 index e58a98f..3c3c3aa 100644
   1491 --- a/tests/cxx/badinc.cc
   1492 +++ b/tests/cxx/badinc.cc
   1493 @@ -1094,8 +1094,10 @@ int main() {
   1494    // IWYU: I1_PtrDereferenceClass needs a declaration
   1495    I1_PtrDereferenceClass* local_i1_ptrdereference_class = 0;
   1496    int x;
   1497 -  // IWYU: va_list is...*<stdarg.h>
   1498 -  va_list vl;  // in gcc, va_list is an internal type, so this tests <built-in>
   1499 +  // va_list is normally in <stdarg.h>, but we already have <stdio.h>
   1500 +  // available, so mappings will source it from there.
   1501 +  // IWYU: va_list is...*<stdio.h>
   1502 +  va_list vl;
   1503    D1_I1_Typedef d1_i1_typedef;
   1504    // IWYU: i1_int is...*badinc-i1.h
   1505    int vararray[i1_int];
   1506 @@ -1859,7 +1861,6 @@ int main() {
   1507  
   1508  tests/cxx/badinc.cc should add these lines:
   1509  #include <ctype.h>
   1510 -#include <stdarg.h>
   1511  #include <stddef.h>
   1512  #include <list>
   1513  #include "tests/cxx/badinc-i1.h"
   1514 @@ -1889,7 +1890,6 @@ The full include-list for tests/cxx/badinc.cc:
   1515  #include "tests/cxx/badinc-inl.h"
   1516  #include <ctype.h>  // for isascii
   1517  #include <setjmp.h>
   1518 -#include <stdarg.h>  // for va_list
   1519  #include <stddef.h>  // for offsetof
   1520  #include <algorithm>  // for find
   1521  #include <fstream>  // for fstream
   1522 diff --git a/tests/cxx/ctad-d1.h b/tests/cxx/ctad-d1.h
   1523 new file mode 100644
   1524 index 0000000..c492fde
   1525 --- /dev/null
   1526 +++ b/tests/cxx/ctad-d1.h
   1527 @@ -0,0 +1,10 @@
   1528 +//===--- ctad-d1.h - test input file for iwyu -----------------------------===//
   1529 +//
   1530 +//                     The LLVM Compiler Infrastructure
   1531 +//
   1532 +// This file is distributed under the University of Illinois Open Source
   1533 +// License. See LICENSE.TXT for details.
   1534 +//
   1535 +//===----------------------------------------------------------------------===//
   1536 +
   1537 +#include "tests/cxx/ctad-i1.h"
   1538 diff --git a/tests/cxx/ctad-i1.h b/tests/cxx/ctad-i1.h
   1539 new file mode 100644
   1540 index 0000000..defd3f0
   1541 --- /dev/null
   1542 +++ b/tests/cxx/ctad-i1.h
   1543 @@ -0,0 +1,20 @@
   1544 +//===--- ctad-i1.h - test input file for iwyu -----------------------------===//
   1545 +//
   1546 +//                     The LLVM Compiler Infrastructure
   1547 +//
   1548 +// This file is distributed under the University of Illinois Open Source
   1549 +// License. See LICENSE.TXT for details.
   1550 +//
   1551 +//===----------------------------------------------------------------------===//
   1552 +
   1553 +template <class Func>
   1554 +struct Deduced {
   1555 +  Deduced(Func&& deferred) : deferred(deferred) {
   1556 +  }
   1557 +
   1558 +  ~Deduced() {
   1559 +    deferred();
   1560 +  }
   1561 +
   1562 +  Func deferred;
   1563 +};
   1564 diff --git a/tests/cxx/ctad.cc b/tests/cxx/ctad.cc
   1565 new file mode 100644
   1566 index 0000000..792343b
   1567 --- /dev/null
   1568 +++ b/tests/cxx/ctad.cc
   1569 @@ -0,0 +1,33 @@
   1570 +//===--- ctad.cc - test input file for iwyu -------------------------------===//
   1571 +//
   1572 +//                     The LLVM Compiler Infrastructure
   1573 +//
   1574 +// This file is distributed under the University of Illinois Open Source
   1575 +// License. See LICENSE.TXT for details.
   1576 +//
   1577 +//===----------------------------------------------------------------------===//
   1578 +
   1579 +// IWYU_ARGS: -I . -std=c++17
   1580 +
   1581 +// Test that C++17 CTAD (Class Template Argument Deduction) is recognized as
   1582 +// pointing back to a template, even if it's not explicitly specialized.
   1583 +
   1584 +#include "tests/cxx/ctad-d1.h"
   1585 +
   1586 +void f() {
   1587 +  // IWYU: Deduced is...*ctad-i1.h
   1588 +  Deduced d([] {});
   1589 +}
   1590 +
   1591 +/**** IWYU_SUMMARY
   1592 +
   1593 +tests/cxx/ctad.cc should add these lines:
   1594 +#include "tests/cxx/ctad-i1.h"
   1595 +
   1596 +tests/cxx/ctad.cc should remove these lines:
   1597 +- #include "tests/cxx/ctad-d1.h"  // lines XX-XX
   1598 +
   1599 +The full include-list for tests/cxx/ctad.cc:
   1600 +#include "tests/cxx/ctad-i1.h"  // for Deduced
   1601 +
   1602 +***** IWYU_SUMMARY */
   1603 diff --git a/tests/cxx/iwyu_stricter_than_cpp-type_alias.h b/tests/cxx/iwyu_stricter_than_cpp-type_alias.h
   1604 new file mode 100644
   1605 index 0000000..3256f55
   1606 --- /dev/null
   1607 +++ b/tests/cxx/iwyu_stricter_than_cpp-type_alias.h
   1608 @@ -0,0 +1,76 @@
   1609 +//===--- iwyu_stricter_than_cpp-type_alias.h - test input file for iwyu ---===//
   1610 +//
   1611 +//                     The LLVM Compiler Infrastructure
   1612 +//
   1613 +// This file is distributed under the University of Illinois Open Source
   1614 +// License. See LICENSE.TXT for details.
   1615 +//
   1616 +//===----------------------------------------------------------------------===//
   1617 +
   1618 +// The two rules the author has to follow to disable iwyu's
   1619 +// stricter-than-C++ rule and force it to fall back on the c++
   1620 +// requirement (forward-declare ok):
   1621 +// (1) forward-declare the relevant type
   1622 +// (2) do not directly #include the definition of the relevant type.
   1623 +
   1624 +#include "tests/cxx/iwyu_stricter_than_cpp-d1.h"
   1625 +
   1626 +// --- Type aliases.
   1627 +
   1628 +// Requires the full type because it does not obey rule (1)
   1629 +// IWYU: IndirectStruct1 is...*iwyu_stricter_than_cpp-i1.h
   1630 +using DoesNotForwardDeclareAl = IndirectStruct1;
   1631 +
   1632 +// This also does not obey rule (1): it's -d1 that does the fwd-declaring.
   1633 +// IWYU: IndirectStructForwardDeclaredInD1 is...*iwyu_stricter_than_cpp-i1.h
   1634 +using DoesNotForwardDeclareProperlyAl = IndirectStructForwardDeclaredInD1;
   1635 +
   1636 +// Requires the full type because it does not obey rule (2)
   1637 +struct DirectStruct1;
   1638 +using IncludesAl = DirectStruct1;
   1639 +
   1640 +// Requires the full type because it does not obey rules (1) *or* (2)
   1641 +using DoesNotForwardDeclareAndIncludesAl = DirectStruct2;
   1642 +
   1643 +// Does not require full type because it obeys all the rules.
   1644 +struct IndirectStruct2;
   1645 +using DoesEverythingRightAl = IndirectStruct2;
   1646 +
   1647 +// --- Now do it all again, with templates!
   1648 +
   1649 +// IWYU: TplIndirectStruct1 is...*iwyu_stricter_than_cpp-i1.h
   1650 +using TplDoesNotForwardDeclareAl = TplIndirectStruct1<int>;
   1651 +
   1652 +using TplDoesNotForwardDeclareProperlyAl
   1653 +// IWYU: TplIndirectStructForwardDeclaredInD1 is...*iwyu_stricter_than_cpp-i1.h
   1654 +    = TplIndirectStructForwardDeclaredInD1<int>;
   1655 +
   1656 +template <typename T> struct TplDirectStruct1;
   1657 +using TplIncludesAl = TplDirectStruct1<int>;
   1658 +
   1659 +using TplDoesNotForwardDeclareAndIncludesAl = TplDirectStruct2<int>;
   1660 +
   1661 +template <typename T> struct TplIndirectStruct2;
   1662 +using TplDoesEverythingRightAl = TplIndirectStruct2<int>;
   1663 +
   1664 +// Another way to forward-declare a class template.
   1665 +template <> struct TplIndirectStruct2<float>;
   1666 +using TplDoesEverythingRightAgainAl = TplIndirectStruct2<float>;
   1667 +
   1668 +
   1669 +/**** IWYU_SUMMARY
   1670 +
   1671 +tests/cxx/iwyu_stricter_than_cpp-type_alias.h should add these lines:
   1672 +#include "tests/cxx/iwyu_stricter_than_cpp-i1.h"
   1673 +
   1674 +tests/cxx/iwyu_stricter_than_cpp-type_alias.h should remove these lines:
   1675 +- struct DirectStruct1;  // lines XX-XX
   1676 +- template <typename T> struct TplDirectStruct1;  // lines XX-XX
   1677 +
   1678 +The full include-list for tests/cxx/iwyu_stricter_than_cpp-type_alias.h:
   1679 +#include "tests/cxx/iwyu_stricter_than_cpp-d1.h"  // for DirectStruct1, DirectStruct2, TplDirectStruct1, TplDirectStruct2
   1680 +#include "tests/cxx/iwyu_stricter_than_cpp-i1.h"  // for IndirectStruct1, IndirectStructForwardDeclaredInD1, TplIndirectStruct1, TplIndirectStructForwardDeclaredInD1
   1681 +struct IndirectStruct2;  // lines XX-XX
   1682 +template <typename T> struct TplIndirectStruct2;  // lines XX-XX
   1683 +
   1684 +***** IWYU_SUMMARY */
   1685 diff --git a/tests/cxx/iwyu_stricter_than_cpp.cc b/tests/cxx/iwyu_stricter_than_cpp.cc
   1686 index d6f70d8..2bfa1c1 100644
   1687 --- a/tests/cxx/iwyu_stricter_than_cpp.cc
   1688 +++ b/tests/cxx/iwyu_stricter_than_cpp.cc
   1689 @@ -10,6 +10,7 @@
   1690  // IWYU_ARGS: -Xiwyu --check_also="tests/cxx/*-autocast.h" \
   1691  //            -Xiwyu --check_also="tests/cxx/*-fnreturn.h" \
   1692  //            -Xiwyu --check_also="tests/cxx/*-typedefs.h" \
   1693 +//            -Xiwyu --check_also="tests/cxx/*-type_alias.h" \
   1694  //            -Xiwyu --check_also="tests/cxx/*-d2.h" \
   1695  //            -I .
   1696  
   1697 @@ -36,6 +37,7 @@
   1698  // when these two conditions are met, and not otherwise.
   1699  
   1700  #include "tests/cxx/iwyu_stricter_than_cpp-typedefs.h"
   1701 +#include "tests/cxx/iwyu_stricter_than_cpp-type_alias.h"
   1702  #include "tests/cxx/iwyu_stricter_than_cpp-autocast.h"
   1703  #include "tests/cxx/iwyu_stricter_than_cpp-fnreturn.h"
   1704  // We include this so the second declaration of TwiceDeclaredFunction
   1705 @@ -81,6 +83,39 @@ void TestTypedefs() {
   1706    // all) of the template args as well.
   1707  }
   1708  
   1709 +using DoubleTypedefAl = DoesEverythingRightAl;
   1710 +
   1711 +void TestTypeAliases() {
   1712 +  DoesNotForwardDeclareAl dnfd(1);
   1713 +  DoesNotForwardDeclareProperlyAl dnfdp(2);
   1714 +  IncludesAl i(3);
   1715 +  DoesNotForwardDeclareAndIncludesAl dnfdai(4);
   1716 +  // IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h
   1717 +  DoesEverythingRightAl dor(5);
   1718 +  // Because DoubleTypedefAl resolves to DoesEverythingRightAl, we need the
   1719 +  // same things DoesEverythingRightAl does.
   1720 +  // IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h
   1721 +  DoubleTypedefAl dt(6);
   1722 +
   1723 +  // ...and with templates.
   1724 +  TplDoesNotForwardDeclareAl tdnfd(7);
   1725 +  TplDoesNotForwardDeclareProperlyAl tdnfdp(8);
   1726 +  TplIncludesAl ti(9);
   1727 +  TplDoesNotForwardDeclareAndIncludesAl tdnfdai(10);
   1728 +  // IWYU: TplIndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h
   1729 +  TplDoesEverythingRightAl tdor(11);
   1730 +  // IWYU: TplIndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h
   1731 +  TplDoesEverythingRightAgainAl tdora(12);
   1732 +
   1733 +  // But if we're in a forward-declare context, we don't require the
   1734 +  // underlying type!
   1735 +  DoesEverythingRightAl* dor_ptr = 0;
   1736 +  TplDoesEverythingRightAgainAl* tdora_ptr = 0;
   1737 +  // ...at least until we dereference the pointer
   1738 +  // IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h
   1739 +  (void) dor_ptr->a;
   1740 +}
   1741 +
   1742  void TestAutocast() {
   1743    // We need full type of is2 because the declarer of Fn didn't
   1744    // IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h
   1745 @@ -159,6 +194,7 @@ The full include-list for tests/cxx/iwyu_stricter_than_cpp.cc:
   1746  #include "tests/cxx/iwyu_stricter_than_cpp-autocast.h"  // for Fn, TplFn
   1747  #include "tests/cxx/iwyu_stricter_than_cpp-fnreturn.h"  // for DoesEverythingRightFn, DoesNotForwardDeclareAndIncludesFn, DoesNotForwardDeclareFn, DoesNotForwardDeclareProperlyFn, IncludesFn, TplDoesEverythingRightAgainFn, TplDoesEverythingRightFn, TplDoesNotForwardDeclareAndIncludesFn, TplDoesNotForwardDeclareFn, TplDoesNotForwardDeclareProperlyFn, TplIncludesFn
   1748  #include "tests/cxx/iwyu_stricter_than_cpp-i2.h"  // for IndirectStruct2, TplIndirectStruct2
   1749 +#include "tests/cxx/iwyu_stricter_than_cpp-type_alias.h"  // for DoesEverythingRightAl, DoesNotForwardDeclareAl, DoesNotForwardDeclareAndIncludesAl, DoesNotForwardDeclareProperlyAl, IncludesAl, TplDoesEverythingRightAgainAl, TplDoesEverythingRightAl, TplDoesNotForwardDeclareAl, TplDoesNotForwardDeclareAndIncludesAl, TplDoesNotForwardDeclareProperlyAl, TplIncludesAl
   1750  #include "tests/cxx/iwyu_stricter_than_cpp-typedefs.h"  // for DoesEverythingRight, DoesNotForwardDeclare, DoesNotForwardDeclareAndIncludes, DoesNotForwardDeclareProperly, Includes, TplDoesEverythingRight, TplDoesEverythingRightAgain, TplDoesNotForwardDeclare, TplDoesNotForwardDeclareAndIncludes, TplDoesNotForwardDeclareProperly, TplIncludes
   1751  struct DirectStruct1;
   1752  struct DirectStruct2;
   1753 diff --git a/tests/cxx/libbuiltins-direct.h b/tests/cxx/libbuiltins-direct.h
   1754 new file mode 100644
   1755 index 0000000..47afdf6
   1756 --- /dev/null
   1757 +++ b/tests/cxx/libbuiltins-direct.h
   1758 @@ -0,0 +1,10 @@
   1759 +//===--- libbuiltins-direct.h - test input file for iwyu ------------------===//
   1760 +//
   1761 +//                     The LLVM Compiler Infrastructure
   1762 +//
   1763 +// This file is distributed under the University of Illinois Open Source
   1764 +// License. See LICENSE.TXT for details.
   1765 +//
   1766 +//===----------------------------------------------------------------------===//
   1767 +
   1768 +#include <cmath>
   1769 diff --git a/tests/cxx/libbuiltins.cc b/tests/cxx/libbuiltins.cc
   1770 new file mode 100644
   1771 index 0000000..d2cdd3e
   1772 --- /dev/null
   1773 +++ b/tests/cxx/libbuiltins.cc
   1774 @@ -0,0 +1,34 @@
   1775 +//===--- libbuiltins.cc - test input file for iwyu ------------------------===//
   1776 +//
   1777 +//                     The LLVM Compiler Infrastructure
   1778 +//
   1779 +// This file is distributed under the University of Illinois Open Source
   1780 +// License. See LICENSE.TXT for details.
   1781 +//
   1782 +//===----------------------------------------------------------------------===//
   1783 +
   1784 +// Library builtins are, like normal builtins, compiled down to an intrinsic,
   1785 +// but a header still needs to be included for the program to be valid. The math
   1786 +// library (std::pow, std::round, etc) is a typical example.
   1787 +
   1788 +// IWYU_ARGS: -I .
   1789 +
   1790 +#include "tests/cxx/libbuiltins-direct.h"
   1791 +
   1792 +float kapow(float x) {
   1793 +  // IWYU: std::pow is...*cmath
   1794 +  return std::pow(x, 2.0F);
   1795 +}
   1796 +
   1797 +/**** IWYU_SUMMARY
   1798 +
   1799 +tests/cxx/libbuiltins.cc should add these lines:
   1800 +#include <cmath>
   1801 +
   1802 +tests/cxx/libbuiltins.cc should remove these lines:
   1803 +- #include "tests/cxx/libbuiltins-direct.h"  // lines XX-XX
   1804 +
   1805 +The full include-list for tests/cxx/libbuiltins.cc:
   1806 +#include <cmath>  // for pow
   1807 +
   1808 +***** IWYU_SUMMARY */
   1809 diff --git a/tests/cxx/macro_location_tpl-d1.h b/tests/cxx/macro_location_tpl-d1.h
   1810 new file mode 100644
   1811 index 0000000..cf7712f
   1812 --- /dev/null
   1813 +++ b/tests/cxx/macro_location_tpl-d1.h
   1814 @@ -0,0 +1,10 @@
   1815 +//===--- macro_location_tpl-d1.h - test input file for iwyu ---------------===//
   1816 +//
   1817 +//                     The LLVM Compiler Infrastructure
   1818 +//
   1819 +// This file is distributed under the University of Illinois Open Source
   1820 +// License. See LICENSE.TXT for details.
   1821 +//
   1822 +//===----------------------------------------------------------------------===//
   1823 +
   1824 +#include "tests/cxx/macro_location_tpl-i1.h"
   1825 diff --git a/tests/cxx/macro_location_tpl-d2.h b/tests/cxx/macro_location_tpl-d2.h
   1826 new file mode 100644
   1827 index 0000000..33da0bb
   1828 --- /dev/null
   1829 +++ b/tests/cxx/macro_location_tpl-d2.h
   1830 @@ -0,0 +1,33 @@
   1831 +//===--- macro_location_tpl-d2.h - test input file for iwyu ---------------===//
   1832 +//
   1833 +//                     The LLVM Compiler Infrastructure
   1834 +//
   1835 +// This file is distributed under the University of Illinois Open Source
   1836 +// License. See LICENSE.TXT for details.
   1837 +//
   1838 +//===----------------------------------------------------------------------===//
   1839 +
   1840 +// Declare a couple of function templates whose specializations are used in a
   1841 +// macro, to check that author intent hints attribute uses to the right place.
   1842 +template <typename>
   1843 +void expansion_template() = delete;
   1844 +template <>
   1845 +void expansion_template<int>();
   1846 +
   1847 +template <typename>
   1848 +void spelling_template() = delete;
   1849 +template <>
   1850 +void spelling_template<int>();
   1851 +
   1852 +// As above, but for class templates.
   1853 +template <typename>
   1854 +struct ExpansionTemplate {
   1855 +  void method() {
   1856 +  }
   1857 +};
   1858 +
   1859 +template <typename>
   1860 +struct SpellingTemplate {
   1861 +  void method() {
   1862 +  }
   1863 +};
   1864 diff --git a/tests/cxx/macro_location_tpl-i1.h b/tests/cxx/macro_location_tpl-i1.h
   1865 new file mode 100644
   1866 index 0000000..460e2a5
   1867 --- /dev/null
   1868 +++ b/tests/cxx/macro_location_tpl-i1.h
   1869 @@ -0,0 +1,30 @@
   1870 +//===--- macro_location_tpl-i1.h - test input file for iwyu ---------------===//
   1871 +//
   1872 +//                     The LLVM Compiler Infrastructure
   1873 +//
   1874 +// This file is distributed under the University of Illinois Open Source
   1875 +// License. See LICENSE.TXT for details.
   1876 +//
   1877 +//===----------------------------------------------------------------------===//
   1878 +
   1879 +// Forward-declare the primary templates as a signal that specialization uses
   1880 +// belong in the expansion location.
   1881 +template <typename>
   1882 +void expansion_template();
   1883 +
   1884 +template <typename>
   1885 +class ExpansionTemplate;
   1886 +
   1887 +// expansion_template should be attributed to expansion loc.
   1888 +#define FUNC_TEMPLATE_SPEC_EXPANSION expansion_template<int>()
   1889 +
   1890 +// spelling_template should be attributed to this file, because there's no
   1891 +// forward-declare hint.
   1892 +#define FUNC_TEMPLATE_SPEC_SPELLING spelling_template<int>();
   1893 +
   1894 +// ExpansionTemplate should be attributed to expansion loc.
   1895 +#define CLASS_TEMPLATE_SPEC_EXPANSION ExpansionTemplate<int>().method();
   1896 +
   1897 +// SpellingTemplate should be attributed to this file, because there's no
   1898 +// forward-declare hint.
   1899 +#define CLASS_TEMPLATE_SPEC_SPELLING SpellingTemplate<int>().method();
   1900 diff --git a/tests/cxx/macro_location_tpl.cc b/tests/cxx/macro_location_tpl.cc
   1901 new file mode 100644
   1902 index 0000000..01a0a00
   1903 --- /dev/null
   1904 +++ b/tests/cxx/macro_location_tpl.cc
   1905 @@ -0,0 +1,46 @@
   1906 +//===--- macro_location_tpl.cc - test input file for iwyu -----------------===//
   1907 +//
   1908 +//                     The LLVM Compiler Infrastructure
   1909 +//
   1910 +// This file is distributed under the University of Illinois Open Source
   1911 +// License. See LICENSE.TXT for details.
   1912 +//
   1913 +//===----------------------------------------------------------------------===//
   1914 +
   1915 +// Expands on macro_location test case to also cover template scenarios.  Macro
   1916 +// uses are attributed to spelling location, but forward-declarations of primary
   1917 +// templates also work as author intent hints for template specializations used
   1918 +// inside the macro.
   1919 +
   1920 +// IWYU_ARGS: -I .
   1921 +
   1922 +#include "tests/cxx/macro_location_tpl-d2.h"
   1923 +#include "tests/cxx/macro_location_tpl-d1.h"
   1924 +
   1925 +void use_macro_with_template_spec() {
   1926 +  // IWYU: FUNC_TEMPLATE_SPEC_EXPANSION is defined...*macro_location_tpl-i1.h
   1927 +  FUNC_TEMPLATE_SPEC_EXPANSION;
   1928 +
   1929 +  // IWYU: FUNC_TEMPLATE_SPEC_SPELLING is defined...*macro_location_tpl-i1.h
   1930 +  FUNC_TEMPLATE_SPEC_SPELLING;
   1931 +
   1932 +  // IWYU: CLASS_TEMPLATE_SPEC_EXPANSION is defined...*macro_location_tpl-i1.h
   1933 +  CLASS_TEMPLATE_SPEC_EXPANSION;
   1934 +
   1935 +  // IWYU: CLASS_TEMPLATE_SPEC_SPELLING is defined...*macro_location_tpl-i1.h
   1936 +  CLASS_TEMPLATE_SPEC_SPELLING;
   1937 +}
   1938 +
   1939 +/**** IWYU_SUMMARY
   1940 +
   1941 +tests/cxx/macro_location_tpl.cc should add these lines:
   1942 +#include "tests/cxx/macro_location_tpl-i1.h"
   1943 +
   1944 +tests/cxx/macro_location_tpl.cc should remove these lines:
   1945 +- #include "tests/cxx/macro_location_tpl-d1.h"  // lines XX-XX
   1946 +
   1947 +The full include-list for tests/cxx/macro_location_tpl.cc:
   1948 +#include "tests/cxx/macro_location_tpl-d2.h"  // for ExpansionTemplate, expansion_template
   1949 +#include "tests/cxx/macro_location_tpl-i1.h"  // for CLASS_TEMPLATE_SPEC_EXPANSION, CLASS_TEMPLATE_SPEC_SPELLING, FUNC_TEMPLATE_SPEC_EXPANSION, FUNC_TEMPLATE_SPEC_SPELLING
   1950 +
   1951 +***** IWYU_SUMMARY */
   1952 diff --git a/tests/cxx/no_forced_alias_callability-d1.h b/tests/cxx/no_forced_alias_callability-d1.h
   1953 new file mode 100644
   1954 index 0000000..895a73f
   1955 --- /dev/null
   1956 +++ b/tests/cxx/no_forced_alias_callability-d1.h
   1957 @@ -0,0 +1,14 @@
   1958 +//===--- no_forced_alias_callability-d1.h - test input file for iwyu ------===//
   1959 +//
   1960 +//                     The LLVM Compiler Infrastructure
   1961 +//
   1962 +// This file is distributed under the University of Illinois Open Source
   1963 +// License. See LICENSE.TXT for details.
   1964 +//
   1965 +//===----------------------------------------------------------------------===//
   1966 +
   1967 +struct ReturnType;
   1968 +
   1969 +struct Aliased {
   1970 +  ReturnType doSomething();
   1971 +};
   1972 diff --git a/tests/cxx/no_forced_alias_callability-d2.h b/tests/cxx/no_forced_alias_callability-d2.h
   1973 new file mode 100644
   1974 index 0000000..7be9a1b
   1975 --- /dev/null
   1976 +++ b/tests/cxx/no_forced_alias_callability-d2.h
   1977 @@ -0,0 +1,18 @@
   1978 +//===--- no_forced_alias_callability-d2.h - test input file for iwyu ------===//
   1979 +//
   1980 +//                     The LLVM Compiler Infrastructure
   1981 +//
   1982 +// This file is distributed under the University of Illinois Open Source
   1983 +// License. See LICENSE.TXT for details.
   1984 +//
   1985 +//===----------------------------------------------------------------------===//
   1986 +
   1987 +struct Aliased;
   1988 +
   1989 +typedef Aliased Alias;
   1990 +
   1991 +/**** IWYU_SUMMARY
   1992 +
   1993 +(tests/cxx/no_forced_alias_callability-d2.h has correct #includes/fwd-decls)
   1994 +
   1995 +***** IWYU_SUMMARY */
   1996 diff --git a/tests/cxx/no_forced_alias_callability.cc b/tests/cxx/no_forced_alias_callability.cc
   1997 new file mode 100644
   1998 index 0000000..6d4ce0a
   1999 --- /dev/null
   2000 +++ b/tests/cxx/no_forced_alias_callability.cc
   2001 @@ -0,0 +1,29 @@
   2002 +//===--- no_forced_alias_callability.cc - test input file for iwyu --------===//
   2003 +//
   2004 +//                     The LLVM Compiler Infrastructure
   2005 +//
   2006 +// This file is distributed under the University of Illinois Open Source
   2007 +// License. See LICENSE.TXT for details.
   2008 +//
   2009 +//===----------------------------------------------------------------------===//
   2010 +
   2011 +// IWYU_ARGS: -Xiwyu --check_also="tests/cxx/no_forced_alias_callability-d2.h" \
   2012 +//            -I .
   2013 +
   2014 +// Tests that IWYU doesn't require inclusion of an aliased class header
   2015 +// (...-d1.h) into a header with the alias to provide callability of methods
   2016 +// of the aliased class if the aliased class is explicitly made forward declared
   2017 +// in accordance with the IWYU policy
   2018 +
   2019 +#include "tests/cxx/no_forced_alias_callability-d1.h"
   2020 +#include "tests/cxx/no_forced_alias_callability-d2.h"
   2021 +
   2022 +int main() {
   2023 +  Alias a;
   2024 +}
   2025 +
   2026 +/**** IWYU_SUMMARY
   2027 +
   2028 +(tests/cxx/no_forced_alias_callability.cc has correct #includes/fwd-decls)
   2029 +
   2030 +***** IWYU_SUMMARY */
   2031 diff --git a/tests/cxx/scope_crash.cc b/tests/cxx/scope_crash.cc
   2032 new file mode 100644
   2033 index 0000000..1659e08
   2034 --- /dev/null
   2035 +++ b/tests/cxx/scope_crash.cc
   2036 @@ -0,0 +1,45 @@
   2037 +//===--- scope_crash.cc - test input file for iwyu ------------------------===//
   2038 +//
   2039 +//                     The LLVM Compiler Infrastructure
   2040 +//
   2041 +// This file is distributed under the University of Illinois Open Source
   2042 +// License. See LICENSE.TXT for details.
   2043 +//
   2044 +//===----------------------------------------------------------------------===//
   2045 +
   2046 +// This is a weak testcase, but it's the smallest example we've found to
   2047 +// reproduce an IWYU crash where Sema::TUScope was unexpectedly null.
   2048 +//
   2049 +// For some reason libstdc++9's std::map with a value with explicit default
   2050 +// constructor triggers some path in Sema's constructor lookup that needs a
   2051 +// non-null TUScope.
   2052 +//
   2053 +// Clang or libstdc++ might change so that this can no longer trigger the
   2054 +// original bug, or so that the bug manifests some other way. But testers can't
   2055 +// be choosers.
   2056 +
   2057 +#include <string>
   2058 +#include <map>
   2059 +
   2060 +struct A {};
   2061 +
   2062 +bool operator<(const A& lhs, const A& rhs) {
   2063 +  return false;
   2064 +}
   2065 +
   2066 +struct B {
   2067 +  // Used to crash with libstdc++ 9, worked without 'explicit'
   2068 +  explicit B() = default;
   2069 +  std::string data;
   2070 +};
   2071 +
   2072 +void foo(const A& a) {
   2073 +  std::map<A, B> m;
   2074 +  m.erase(a);
   2075 +}
   2076 +
   2077 +/**** IWYU_SUMMARY
   2078 +
   2079 +(tests/cxx/scope_crash.cc has correct #includes/fwd-decls)
   2080 +
   2081 +***** IWYU_SUMMARY */
   2082 diff --git a/tests/cxx/update_comments.cc b/tests/cxx/update_comments.cc
   2083 new file mode 100644
   2084 index 0000000..bf0eccb
   2085 --- /dev/null
   2086 +++ b/tests/cxx/update_comments.cc
   2087 @@ -0,0 +1,28 @@
   2088 +//===--- update_comments.cc - test input file for iwyu --------------------===//
   2089 +//
   2090 +//                     The LLVM Compiler Infrastructure
   2091 +//
   2092 +// This file is distributed under the University of Illinois Open Source
   2093 +// License. See LICENSE.TXT for details.
   2094 +//
   2095 +//===----------------------------------------------------------------------===//
   2096 +
   2097 +// IWYU_ARGS: -Xiwyu --update_comments -I .
   2098 +
   2099 +// Test that passing the --update_comments switch to IWYU makes it always print
   2100 +// the full include-list, with up to date "// for XYZ" comments.
   2101 +
   2102 +#include "tests/cxx/indirect.h"  // for SomethingElse
   2103 +
   2104 +IndirectClass indirect;
   2105 +
   2106 +/**** IWYU_SUMMARY
   2107 +
   2108 +tests/cxx/update_comments.cc should add these lines:
   2109 +
   2110 +tests/cxx/update_comments.cc should remove these lines:
   2111 +
   2112 +The full include-list for tests/cxx/update_comments.cc:
   2113 +#include "tests/cxx/indirect.h"  // for IndirectClass
   2114 +
   2115 +***** IWYU_SUMMARY */