Track span information of include statements
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 6a177d5..a4b393a 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -1,9 +1,27 @@
-use crate::syntax::{ExternFn, Impl, Receiver, Ref, Signature, Slice, Ty1, Type};
+use crate::syntax::{ExternFn, Impl, Include, Receiver, Ref, Signature, Slice, Ty1, Type};
 use std::borrow::Borrow;
 use std::hash::{Hash, Hasher};
 use std::mem;
 use std::ops::{Deref, DerefMut};
 
+impl PartialEq for Include {
+    fn eq(&self, other: &Include) -> bool {
+        let Include {
+            path,
+            kind,
+            begin_span: _,
+            end_span: _,
+        } = self;
+        let Include {
+            path: path2,
+            kind: kind2,
+            begin_span: _,
+            end_span: _,
+        } = other;
+        path == path2 && kind == kind2
+    }
+}
+
 impl Deref for ExternFn {
     type Target = Signature;
 
diff --git a/syntax/mod.rs b/syntax/mod.rs
index c8dea67..2eccdb6 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -34,7 +34,7 @@
 pub use self::types::Types;
 
 pub enum Api {
-    Include(String),
+    Include(Include),
     Struct(Struct),
     Enum(Enum),
     CxxType(ExternType),
@@ -45,6 +45,19 @@
     Impl(Impl),
 }
 
+pub struct Include {
+    pub path: String,
+    pub kind: IncludeKind,
+    pub begin_span: Span,
+    pub end_span: Span,
+}
+
+#[derive(Copy, Clone, PartialEq)]
+pub enum IncludeKind {
+    Quoted,    // #include "quoted/path/to"
+    Bracketed, // #include <bracketed/path/to>
+}
+
 pub struct ExternType {
     pub doc: Doc,
     pub type_token: Token![type],
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 367ad05..5b6abbb 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -3,10 +3,10 @@
 use crate::syntax::report::Errors;
 use crate::syntax::Atom::*;
 use crate::syntax::{
-    attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Lang, Pair, Receiver, Ref, Signature,
-    Slice, Struct, Ty1, Type, TypeAlias, Var, Variant,
+    attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Include, IncludeKind, Lang, Pair,
+    Receiver, Ref, Signature, Slice, Struct, Ty1, Type, TypeAlias, Var, Variant,
 };
-use proc_macro2::{Delimiter, Group, TokenStream, TokenTree};
+use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
 use quote::{format_ident, quote, quote_spanned};
 use syn::parse::{ParseStream, Parser};
 use syn::punctuated::Punctuated;
@@ -471,17 +471,28 @@
     }))
 }
 
-fn parse_include(input: ParseStream) -> Result<String> {
+fn parse_include(input: ParseStream) -> Result<Include> {
     if input.peek(LitStr) {
-        return Ok(input.parse::<LitStr>()?.value());
+        let lit: LitStr = input.parse()?;
+        let span = lit.span();
+        return Ok(Include {
+            path: lit.value(),
+            kind: IncludeKind::Quoted,
+            begin_span: span,
+            end_span: span,
+        });
     }
 
     if input.peek(Token![<]) {
         let mut path = String::new();
+        let mut begin_span = None;
+        let mut end_span = Span::call_site();
+
         input.parse::<Token![<]>()?;
-        path.push('<');
         while !input.is_empty() && !input.peek(Token![>]) {
             let token: TokenTree = input.parse()?;
+            end_span = token.span();
+            begin_span = Some(begin_span.unwrap_or(end_span));
             match token {
                 TokenTree::Ident(token) => path += &token.to_string(),
                 TokenTree::Literal(token)
@@ -495,9 +506,16 @@
                 _ => return Err(Error::new(token.span(), "unexpected token in include path")),
             }
         }
-        input.parse::<Token![>]>()?;
-        path.push('>');
-        return Ok(path);
+        let rangle: Token![>] = input.parse()?;
+        let begin_span =
+            begin_span.ok_or_else(|| Error::new(rangle.span, "empty filename in #include"))?;
+
+        return Ok(Include {
+            path,
+            kind: IncludeKind::Bracketed,
+            begin_span,
+            end_span,
+        });
     }
 
     Err(input.error("expected \"quoted/path/to\" or <bracketed/path/to>"))