Repository: rust-lang/rust-bindgen
Pull request #3244 (2025-07-08 20:59:42)

Include source code location in discovery callback
[ This is a takeover of #3141, resolving merge conflicts. Original PR text below. ]

Builds on top of #3140.

This provides the source code location of an item in the existing item discovery callback. See f607994c3ab87ee754ce7a9138564c2a22b6bb92 for discussion of whether it's OK to break compatibility like this.

Part of https://github.com/google/autocxx/issues/124


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index b302509c..92f1f78e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13,32 +13,70 @@ dependencies = [
 
 [[package]]
 name = "annotate-snippets"
-version = "0.11.4"
+version = "0.11.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24e35ed54e5ea7997c14ed4c70ba043478db1112e98263b3b035907aa197d991"
+checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4"
 dependencies = [
  "anstyle",
  "unicode-width",
 ]
 
+[[package]]
+name = "anstream"
+version = "0.6.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
 [[package]]
 name = "anstyle"
-version = "1.0.10"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
+dependencies = [
+ "utf8parse",
+]
 
 [[package]]
-name = "autocfg"
-version = "1.4.0"
+name = "anstyle-query"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys",
+]
 
 [[package]]
 name = "bindgen"
 version = "0.72.0"
 dependencies = [
  "annotate-snippets",
- "bitflags 2.2.1",
+ "bitflags",
  "cexpr",
  "clang-sys",
  "clap",
@@ -51,7 +89,7 @@ dependencies = [
  "regex",
  "rustc-hash",
  "shlex",
- "syn 2.0.90",
+ "syn",
 ]
 
 [[package]]
@@ -59,7 +97,7 @@ name = "bindgen-cli"
 version = "0.72.0"
 dependencies = [
  "bindgen",
- "env_logger 0.10.0",
+ "env_logger 0.10.2",
  "log",
  "proc-macro2",
  "shlex",
@@ -84,21 +122,15 @@ dependencies = [
  "regex",
  "shlex",
  "similar",
- "syn 2.0.90",
+ "syn",
  "tempfile",
 ]
 
 [[package]]
 name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bitflags"
-version = "2.2.1"
+version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 
 [[package]]
 name = "block"
@@ -108,9 +140,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
 
 [[package]]
 name = "cc"
-version = "1.2.2"
+version = "1.2.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc"
+checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
 dependencies = [
  "shlex",
 ]
@@ -126,9 +158,9 @@ dependencies = [
 
 [[package]]
 name = "cfg-if"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
 
 [[package]]
 name = "clang-sys"
@@ -143,55 +175,64 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.1.4"
+version = "4.4.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
+checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
 dependencies = [
- "bitflags 1.3.2",
+ "clap_builder",
  "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
+dependencies = [
+ "anstream",
+ "anstyle",
  "clap_lex",
- "is-terminal",
- "once_cell",
  "strsim",
- "termcolor",
 ]
 
 [[package]]
 name = "clap_complete"
-version = "4.2.0"
+version = "4.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd"
+checksum = "abb745187d7f4d76267b37485a65e0149edd0e91a4cfcdd3f27524ad86cee9f3"
 dependencies = [
  "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "4.1.0"
+version = "4.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
+checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
 dependencies = [
  "heck",
- "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn",
 ]
 
 [[package]]
 name = "clap_lex"
-version = "0.3.1"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
-dependencies = [
- "os_str_bytes",
-]
+checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
 
 [[package]]
 name = "either"
-version = "1.13.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
 
 [[package]]
 name = "env_logger"
@@ -205,9 +246,9 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.10.0"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
+checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
 dependencies = [
  "humantime",
  "is-terminal",
@@ -218,39 +259,48 @@ dependencies = [
 
 [[package]]
 name = "errno"
-version = "0.3.10"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
+checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
 dependencies = [
  "libc",
- "windows-sys 0.52.0",
+ "windows-sys",
 ]
 
 [[package]]
 name = "fastrand"
-version = "1.9.0"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
 dependencies = [
- "instant",
+ "cfg-if",
+ "libc",
+ "wasi 0.11.1+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.2.15"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
 ]
 
 [[package]]
 name = "glob"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
 
 [[package]]
 name = "heck"
@@ -260,52 +310,32 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
 name = "hermit-abi"
-version = "0.3.9"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
-
-[[package]]
-name = "hermit-abi"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
 
 [[package]]
 name = "humantime"
-version = "2.1.0"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
-
-[[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
+checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f"
 
 [[package]]
-name = "io-lifetimes"
-version = "1.0.11"
+name = "is-terminal"
+version = "0.4.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
 dependencies = [
- "hermit-abi 0.3.9",
+ "hermit-abi",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
-name = "is-terminal"
-version = "0.4.13"
+name = "is_terminal_polyfill"
+version = "1.70.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
-dependencies = [
- "hermit-abi 0.4.0",
- "libc",
- "windows-sys 0.52.0",
-]
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 
 [[package]]
 name = "itertools"
@@ -318,31 +348,31 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.167"
+version = "0.2.174"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
+checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
 
 [[package]]
 name = "libloading"
-version = "0.8.6"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
+checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
 dependencies = [
  "cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.3.8"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
+checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
 
 [[package]]
 name = "log"
-version = "0.4.22"
+version = "0.4.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
 
 [[package]]
 name = "malloc_buf"
@@ -355,9 +385,9 @@ dependencies = [
 
 [[package]]
 name = "memchr"
-version = "2.7.4"
+version = "2.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
 
 [[package]]
 name = "minimal-lexical"
@@ -386,61 +416,37 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
-name = "os_str_bytes"
-version = "6.4.1"
+name = "once_cell_polyfill"
+version = "1.70.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
 
 [[package]]
 name = "owo-colors"
-version = "4.1.0"
+version = "4.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56"
+checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e"
 
 [[package]]
 name = "prettyplease"
-version = "0.2.25"
+version = "0.2.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
+checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a"
 dependencies = [
  "proc-macro2",
- "syn 2.0.90",
-]
-
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
+ "syn",
 ]
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -467,13 +473,19 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.37"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
 [[package]]
 name = "rand"
 version = "0.8.5"
@@ -489,16 +501,7 @@ version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
-dependencies = [
- "bitflags 1.3.2",
+ "getrandom 0.2.16",
 ]
 
 [[package]]
@@ -532,22 +535,21 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 
 [[package]]
 name = "rustc-hash"
-version = "2.1.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
 
 [[package]]
 name = "rustix"
-version = "0.37.27"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
+checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
 dependencies = [
- "bitflags 1.3.2",
+ "bitflags",
  "errno",
- "io-lifetimes",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -558,9 +560,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
 name = "similar"
-version = "2.6.0"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e"
+checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
 
 [[package]]
 name = "strsim"
@@ -570,20 +572,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.90"
+version = "2.0.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -592,23 +583,22 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.6.0"
+version = "3.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
+checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
 dependencies = [
- "autocfg",
- "cfg-if",
  "fastrand",
- "redox_syscall",
+ "getrandom 0.3.3",
+ "once_cell",
  "rustix",
- "windows-sys 0.48.0",
+ "windows-sys",
 ]
 
 [[package]]
 name = "termcolor"
-version = "1.2.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
 dependencies = [
  "winapi-util",
 ]
@@ -624,90 +614,53 @@ dependencies = [
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.14"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.14"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
 
 [[package]]
-name = "version_check"
-version = "0.9.4"
+name = "utf8parse"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.11.1+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
 
 [[package]]
-name = "winapi"
-version = "0.3.9"
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
 dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
+ "wit-bindgen-rt",
 ]
 
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
 [[package]]
 name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
 dependencies = [
- "windows-targets 0.48.5",
+ "windows-sys",
 ]
 
 [[package]]
 name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
+version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets",
 ]
 
 [[package]]
@@ -716,46 +669,28 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
  "windows_i686_gnullvm",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
 [[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
@@ -768,36 +703,18 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
 [[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
@@ -806,12 +723,15 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.48.5"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.6"
+name = "wit-bindgen-rt"
+version = "0.39.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
diff --git a/bindgen/callbacks.rs b/bindgen/callbacks.rs
index 8ad06b33..c8ac9a5e 100644
--- a/bindgen/callbacks.rs
+++ b/bindgen/callbacks.rs
@@ -169,7 +169,13 @@ pub trait ParseCallbacks: fmt::Debug {
     }
 
     /// This will get called everytime an item (currently struct, union, and alias) is found with some information about it
-    fn new_item_found(&self, _id: DiscoveredItemId, _item: DiscoveredItem) {}
+    fn new_item_found(
+        &self,
+        _id: DiscoveredItemId,
+        _item: DiscoveredItem,
+        _source_location: Option<&SourceLocation>,
+    ) {
+    }
 
     // TODO add callback for ResolvedTypeRef
 }
@@ -315,3 +321,17 @@ pub struct FieldInfo<'a> {
     /// The name of the type of the field.
     pub field_type_name: Option<&'a str>,
 }
+
+/// Location in the source code. Roughly equivalent to the same type
+/// within `clang_sys`.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct SourceLocation {
+    /// Line number.
+    pub line: usize,
+    /// Column number within line.
+    pub col: usize,
+    /// Byte offset within file.
+    pub byte_offset: usize,
+    /// Filename, if known.
+    pub file_name: Option<String>,
+}
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs
index 433fc85f..c0f461b3 100644
--- a/bindgen/codegen/mod.rs
+++ b/bindgen/codegen/mod.rs
@@ -494,8 +494,7 @@ impl Item {
         if self.is_blocklisted(ctx) || result.seen(self.id()) {
             debug!(
                 "<Item as CodeGenerator>::process_before_codegen: Ignoring hidden or seen: \
-                 self = {:?}",
-                self
+                 self = {self:?}"
             );
             return false;
         }
@@ -986,8 +985,7 @@ impl CodeGenerator for Type {
                     if inner_canon_type.is_invalid_type_param() {
                         warn!(
                             "Item contained invalid named type, skipping: \
-                             {:?}, {:?}",
-                            item, inner_item
+                             {item:?}, {inner_item:?}"
                         );
                         return;
                     }
@@ -995,16 +993,13 @@ impl CodeGenerator for Type {
 
                 let rust_name = ctx.rust_ident(&name);
 
-                ctx.options().for_each_callback(|cb| {
-                    cb.new_item_found(
-                        DiscoveredItemId::new(item.id().as_usize()),
-                        DiscoveredItem::Alias {
-                            alias_name: rust_name.to_string(),
-                            alias_for: DiscoveredItemId::new(
-                                inner_item.id().as_usize(),
-                            ),
-                        },
-                    );
+                utils::call_discovered_item_callback(ctx, item, || {
+                    DiscoveredItem::Alias {
+                        alias_name: rust_name.to_string(),
+                        alias_for: DiscoveredItemId::new(
+                            inner_item.id().as_usize(),
+                        ),
+                    }
                 });
 
                 let mut tokens = if let Some(comment) = item.comment(ctx) {
@@ -1098,8 +1093,7 @@ impl CodeGenerator for Type {
                 {
                     warn!(
                         "Item contained invalid template \
-                         parameter: {:?}",
-                        item
+                         parameter: {item:?}"
                     );
                     return;
                 }
@@ -2480,28 +2474,23 @@ impl CodeGenerator for CompInfo {
 
         let is_rust_union = is_union && struct_layout.is_rust_union();
 
-        let discovered_id = DiscoveredItemId::new(item.id().as_usize());
-        ctx.options().for_each_callback(|cb| {
-            let discovered_item = match self.kind() {
-                CompKind::Struct => DiscoveredItem::Struct {
-                    original_name: item
-                        .kind()
-                        .expect_type()
-                        .name()
-                        .map(String::from),
-                    final_name: canonical_ident.to_string(),
-                },
-                CompKind::Union => DiscoveredItem::Union {
-                    original_name: item
-                        .kind()
-                        .expect_type()
-                        .name()
-                        .map(String::from),
-                    final_name: canonical_ident.to_string(),
-                },
-            };
-
-            cb.new_item_found(discovered_id, discovered_item);
+        utils::call_discovered_item_callback(ctx, item, || match self.kind() {
+            CompKind::Struct => DiscoveredItem::Struct {
+                original_name: item
+                    .kind()
+                    .expect_type()
+                    .name()
+                    .map(String::from),
+                final_name: canonical_ident.to_string(),
+            },
+            CompKind::Union => DiscoveredItem::Union {
+                original_name: item
+                    .kind()
+                    .expect_type()
+                    .name()
+                    .map(String::from),
+                final_name: canonical_ident.to_string(),
+            },
         });
 
         // The custom derives callback may return a list of derive attributes;
@@ -2699,6 +2688,7 @@ impl CodeGenerator for CompInfo {
             }
 
             let mut method_names = Default::default();
+            let discovered_id = DiscoveredItemId::new(item.id().as_usize());
             if ctx.options().codegen_config.methods() {
                 for method in self.methods() {
                     assert_ne!(method.kind(), MethodKind::Constructor);
@@ -3020,7 +3010,6 @@ impl Method {
 
         // First of all, output the actual function.
         let function_item = ctx.resolve_item(self.signature());
-        let id = DiscoveredItemId::new(function_item.id().as_usize());
         if !function_item.process_before_codegen(ctx, result) {
             return;
         }
@@ -3067,14 +3056,11 @@ impl Method {
 
         method_names.insert(name.clone());
 
-        ctx.options().for_each_callback(|cb| {
-            cb.new_item_found(
-                id,
-                DiscoveredItem::Method {
-                    parent: parent_id,
-                    final_name: name.clone(),
-                },
-            );
+        utils::call_discovered_item_callback(ctx, function_item, || {
+            DiscoveredItem::Method {
+                parent: parent_id,
+                final_name: name.clone(),
+            }
         });
 
         let mut function_name = function_item.canonical_name(ctx);
@@ -3804,13 +3790,10 @@ impl CodeGenerator for Enum {
         let repr = repr.to_rust_ty_or_opaque(ctx, item);
         let has_typedef = ctx.is_enum_typedef_combo(item.id());
 
-        ctx.options().for_each_callback(|cb| {
-            cb.new_item_found(
-                DiscoveredItemId::new(item.id().as_usize()),
-                DiscoveredItem::Enum {
-                    final_name: name.to_string(),
-                },
-            );
+        utils::call_discovered_item_callback(ctx, item, || {
+            DiscoveredItem::Enum {
+                final_name: name.to_string(),
+            }
         });
 
         let mut builder = EnumBuilder::new(
@@ -4595,7 +4578,6 @@ impl CodeGenerator for Function {
     ) -> Self::Return {
         debug!("<Function as CodeGenerator>::codegen: item = {item:?}");
         debug_assert!(item.is_enabled_for_codegen(ctx));
-        let id = DiscoveredItemId::new(item.id().as_usize());
 
         let is_internal = matches!(self.linkage(), Linkage::Internal);
 
@@ -4712,13 +4694,10 @@ impl CodeGenerator for Function {
         if times_seen > 0 {
             write!(&mut canonical_name, "{times_seen}").unwrap();
         }
-        ctx.options().for_each_callback(|cb| {
-            cb.new_item_found(
-                id,
-                DiscoveredItem::Function {
-                    final_name: canonical_name.to_string(),
-                },
-            );
+        utils::call_discovered_item_callback(ctx, item, || {
+            DiscoveredItem::Function {
+                final_name: canonical_name.to_string(),
+            }
         });
 
         let link_name_attr = self.link_name().or_else(|| {
@@ -5259,6 +5238,7 @@ pub(crate) mod utils {
     use super::helpers::BITFIELD_UNIT;
     use super::serialize::CSerialize;
     use super::{error, CodegenError, CodegenResult, ToRustTyOrOpaque};
+    use crate::callbacks::DiscoveredItemId;
     use crate::ir::context::BindgenContext;
     use crate::ir::context::TypeId;
     use crate::ir::function::{Abi, ClangAbi, FunctionSig};
@@ -5988,4 +5968,28 @@ pub(crate) mod utils {
 
         true
     }
+
+    pub(super) fn call_discovered_item_callback(
+        ctx: &BindgenContext,
+        item: &Item,
+        discovered_item_creator: impl Fn() -> crate::callbacks::DiscoveredItem,
+    ) {
+        let source_location = item.location().map(|clang_location| {
+            let (file, line, col, byte_offset) = clang_location.location();
+            let file_name = file.name();
+            crate::callbacks::SourceLocation {
+                line,
+                col,
+                byte_offset,
+                file_name,
+            }
+        });
+        ctx.options().for_each_callback(|cb| {
+            cb.new_item_found(
+                DiscoveredItemId::new(item.id().as_usize()),
+                discovered_item_creator(),
+                source_location.as_ref(),
+            );
+        });
+    }
 }
diff --git a/bindgen/ir/context.rs b/bindgen/ir/context.rs
index 6adbcd59..47f837f9 100644
--- a/bindgen/ir/context.rs
+++ b/bindgen/ir/context.rs
@@ -1755,8 +1755,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
                         // Bypass all the validations in add_item explicitly.
                         debug!(
                             "instantiate_template: inserting nested \
-                             instantiation item: {:?}",
-                            sub_item
+                             instantiation item: {sub_item:?}"
                         );
                         self.add_item_to_module(&sub_item);
                         debug_assert_eq!(sub_id, sub_item.id());
diff --git a/bindgen/ir/ty.rs b/bindgen/ir/ty.rs
index 38a7f634..5819f111 100644
--- a/bindgen/ir/ty.rs
+++ b/bindgen/ir/ty.rs
@@ -920,8 +920,7 @@ impl Type {
                                 let Ok(inner_type) = inner else {
                                     warn!(
                                         "Failed to parse template alias \
-                                             {:?}",
-                                        location
+                                             {location:?}"
                                     );
                                     return Err(ParseError::Continue);
                                 };


Test patch:
diff --git a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs
index 6a6d0149..a9a95238 100644
--- a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs
+++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs
@@ -4,23 +4,57 @@ use std::rc::Rc;
 
 use regex::Regex;
 
-use bindgen::callbacks::{DiscoveredItem, DiscoveredItemId, ParseCallbacks};
+use bindgen::callbacks::{
+    DiscoveredItem, DiscoveredItemId, ParseCallbacks, SourceLocation,
+};
 use bindgen::Builder;
 
 #[derive(Debug, Default)]
 struct ItemDiscovery(Rc<RefCell<ItemCache>>);
 
-pub type ItemCache = HashMap<DiscoveredItemId, DiscoveredItem>;
+pub type ItemCache = HashMap<DiscoveredItemId, DiscoveredInformation>;
+
+#[derive(Debug)]
+pub struct DiscoveredInformation(DiscoveredItem, Option<SourceLocation>);
 
 impl ParseCallbacks for ItemDiscovery {
-    fn new_item_found(&self, _id: DiscoveredItemId, _item: DiscoveredItem) {
-        self.0.borrow_mut().insert(_id, _item);
+    fn new_item_found(
+        &self,
+        id: DiscoveredItemId,
+        item: DiscoveredItem,
+        source_location: Option<&SourceLocation>,
+    ) {
+        self.0
+            .borrow_mut()
+            .insert(id, DiscoveredInformation(item, source_location.cloned()));
     }
 }
 
+#[derive(Debug)]
+pub struct ItemExpectations {
+    item: DiscoveredItem,
+    source_location: Option<(usize, usize, usize)>,
+}
+
+impl ItemExpectations {
+    fn new(
+        item: DiscoveredItem,
+        line: usize,
+        col: usize,
+        byte_offset: usize,
+    ) -> Self {
+        Self {
+            item,
+            source_location: Some((line, col, byte_offset)),
+        }
+    }
+}
+
+type ExpectationMap = HashMap<DiscoveredItemId, ItemExpectations>;
+
 fn test_item_discovery_callback(
     header: &str,
-    expected: &HashMap<DiscoveredItemId, DiscoveredItem>,
+    expected: &HashMap<DiscoveredItemId, ItemExpectations>,
 ) {
     let discovery = ItemDiscovery::default();
     let info = Rc::clone(&discovery.0);
@@ -34,72 +68,117 @@ fn test_item_discovery_callback(
         .generate()
         .expect("TODO: panic message");
 
-    compare_item_caches(&info.borrow(), expected);
+    compare_item_caches(&info.borrow(), expected, header);
 }
 
 #[test]
 fn test_item_discovery_callback_c() {
-    let expected = ItemCache::from([
+    let expected = ExpectationMap::from([
         (
             DiscoveredItemId::new(10),
-            DiscoveredItem::Struct {
-                original_name: Some("NamedStruct".to_string()),
-                final_name: "NamedStruct".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Struct {
+                    original_name: Some("NamedStruct".to_string()),
+                    final_name: "NamedStruct".to_string(),
+                },
+                4,
+                8,
+                73,
+            ),
         ),
         (
             DiscoveredItemId::new(11),
-            DiscoveredItem::Alias {
-                alias_name: "AliasOfNamedStruct".to_string(),
-                alias_for: DiscoveredItemId::new(10),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Alias {
+                    alias_name: "AliasOfNamedStruct".to_string(),
+                    alias_for: DiscoveredItemId::new(10),
+                },
+                7,
+                28,
+                118,
+            ),
         ),
         (
             DiscoveredItemId::new(20),
-            DiscoveredItem::Union {
-                original_name: Some("NamedUnion".to_string()),
-                final_name: "NamedUnion".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Union {
+                    original_name: Some("NamedUnion".to_string()),
+                    final_name: "NamedUnion".to_string(),
+                },
+                13,
+                7,
+                209,
+            ),
         ),
         (
             DiscoveredItemId::new(21),
-            DiscoveredItem::Alias {
-                alias_name: "AliasOfNamedUnion".to_string(),
-                alias_for: DiscoveredItemId::new(20),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Alias {
+                    alias_name: "AliasOfNamedUnion".to_string(),
+                    alias_for: DiscoveredItemId::new(20),
+                },
+                16,
+                26,
+                251,
+            ),
         ),
         (
             DiscoveredItemId::new(27),
-            DiscoveredItem::Alias {
-                alias_name: "AliasOfNamedEnum".to_string(),
-                alias_for: DiscoveredItemId::new(24),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Alias {
+                    alias_name: "AliasOfNamedEnum".to_string(),
+                    alias_for: DiscoveredItemId::new(24),
+                },
+                28,
+                24,
+                515,
+            ),
         ),
         (
             DiscoveredItemId::new(24),
-            DiscoveredItem::Enum {
-                final_name: "NamedEnum".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Enum {
+                    final_name: "NamedEnum".to_string(),
+                },
+                24,
+                6,
+                466,
+            ),
         ),
         (
             DiscoveredItemId::new(30),
-            DiscoveredItem::Struct {
-                original_name: None,
-                final_name: "_bindgen_ty_*".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Struct {
+                    original_name: None,
+                    final_name: "_bindgen_ty_*".to_string(),
+                },
+                2,
+                38,
+                48,
+            ),
         ),
         (
             DiscoveredItemId::new(40),
-            DiscoveredItem::Union {
-                original_name: None,
-                final_name: "_bindgen_ty_*".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Union {
+                    original_name: None,
+                    final_name: "_bindgen_ty_*".to_string(),
+                },
+                11,
+                37,
+                186,
+            ),
         ),
         (
             DiscoveredItemId::new(41),
-            DiscoveredItem::Function {
-                final_name: "named_function".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Function {
+                    final_name: "named_function".to_string(),
+                },
+                32,
+                6,
+                553,
+            ),
         ),
     ]);
     test_item_discovery_callback(
@@ -108,27 +187,41 @@ fn test_item_discovery_callback_c() {
 
 #[test]
 fn test_item_discovery_callback_cpp() {
-    let expected = ItemCache::from([
+    let expected = ExpectationMap::from([
         (
             DiscoveredItemId::new(1),
-            DiscoveredItem::Struct {
-                original_name: Some("SomeClass".to_string()),
-                final_name: "SomeClass".to_string(),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Struct {
+                    original_name: Some("SomeClass".to_string()),
+                    final_name: "SomeClass".to_string(),
+                },
+                3,
+                7,
+                18,
+            ),
         ),
         (
             DiscoveredItemId::new(2),
-            DiscoveredItem::Method {
-                final_name: "named_method".to_string(),
-                parent: DiscoveredItemId::new(1),
-            },
+            ItemExpectations::new(
+                DiscoveredItem::Method {
+                    final_name: "named_method".to_string(),
+                    parent: DiscoveredItemId::new(1),
+                },
+                5,
+                10,
+                47,
+            ),
         ),
     ]);
     test_item_discovery_callback(
         "/tests/parse_callbacks/item_discovery_callback/header_item_discovery.hpp", &expected);
 }
 
-pub fn compare_item_caches(generated: &ItemCache, expected: &ItemCache) {
+fn compare_item_caches(
+    generated: &ItemCache,
+    expected: &ExpectationMap,
+    expected_filename: &str,
+) {
     // We can't use a simple Eq::eq comparison because of two reasons:
     // - anonymous structs/unions will have a final name generated by bindgen which may change
     //   if the header file or the bindgen logic is altered
@@ -140,6 +233,7 @@ pub fn compare_item_caches(generated: &ItemCache, expected: &ItemCache) {
                 generated_item,
                 expected,
                 generated,
+                expected_filename,
             )
         });
 
@@ -151,40 +245,72 @@ pub fn compare_item_caches(generated: &ItemCache, expected: &ItemCache) {
 }
 
 fn compare_item_info(
-    expected_item: &DiscoveredItem,
-    generated_item: &DiscoveredItem,
-    expected: &ItemCache,
+    expected_item: &ItemExpectations,
+    generated_item: &DiscoveredInformation,
+    expected: &ExpectationMap,
     generated: &ItemCache,
+    expected_filename: &str,
 ) -> bool {
-    if std::mem::discriminant(expected_item) !=
-        std::mem::discriminant(generated_item)
+    if std::mem::discriminant(&expected_item.item) !=
+        std::mem::discriminant(&generated_item.0)
     {
         return false;
     }
 
-    match generated_item {
+    let is_a_match = match generated_item.0 {
         DiscoveredItem::Struct { .. } => {
-            compare_struct_info(expected_item, generated_item)
+            compare_struct_info(&expected_item.item, &generated_item.0)
         }
         DiscoveredItem::Union { .. } => {
-            compare_union_info(expected_item, generated_item)
+            compare_union_info(&expected_item.item, &generated_item.0)
         }
         DiscoveredItem::Alias { .. } => compare_alias_info(
-            expected_item,
-            generated_item,
+            &expected_item.item,
+            &generated_item.0,
             expected,
             generated,
+            expected_filename,
         ),
         DiscoveredItem::Enum { .. } => {
-            compare_enum_info(expected_item, generated_item)
+            compare_enum_info(&expected_item.item, &generated_item.0)
         }
         DiscoveredItem::Function { .. } => {
-            compare_function_info(expected_item, generated_item)
+            compare_function_info(&expected_item.item, &generated_item.0)
         }
         DiscoveredItem::Method { .. } => {
-            compare_method_info(expected_item, generated_item)
+            compare_method_info(&expected_item.item, &generated_item.0)
+        }
+    };
+
+    if is_a_match {
+        // Compare source location
+        assert!(
+            generated_item.1.is_some() ==
+                expected_item.source_location.is_some(),
+            "No source location provided when one was expected"
+        );
+        if let Some(generated_location) = generated_item.1.as_ref() {
+            let expected_location = expected_item.source_location.unwrap();
+            assert!(
+                generated_location
+                    .file_name
+                    .as_ref()
+                    .expect("No filename provided")
+                    .ends_with(expected_filename),
+                "Filename differed"
+            );
+            assert_eq!(
+                (
+                    generated_location.line,
+                    generated_location.col,
+                    generated_location.byte_offset
+                ),
+                expected_location,
+                "Line/col/offsets differ"
+            );
         }
     }
+    is_a_match
 }
 
 pub fn compare_names(expected_name: &str, generated_name: &str) -> bool {
@@ -288,8 +414,9 @@ pub fn compare_enum_info(
 pub fn compare_alias_info(
     expected_item: &DiscoveredItem,
     generated_item: &DiscoveredItem,
-    expected: &ItemCache,
+    expected: &ExpectationMap,
     generated: &ItemCache,
+    expected_filename: &str,
 ) -> bool {
     let DiscoveredItem::Alias {
         alias_name: expected_alias_name,
@@ -319,7 +446,13 @@ pub fn compare_alias_info(
         return false;
     };
 
-    compare_item_info(expected_aliased, generated_aliased, expected, generated)
+    compare_item_info(
+        expected_aliased,
+        generated_aliased,
+        expected,
+        generated,
+        expected_filename,
+    )
 }
 
 pub fn compare_function_info(