cxx_build/syntax/
mod.rs

1// Functionality that is shared between the cxxbridge macro and the cmd.
2
3pub(crate) mod atom;
4pub(crate) mod attrs;
5pub(crate) mod cfg;
6pub(crate) mod check;
7pub(crate) mod derive;
8mod discriminant;
9mod doc;
10pub(crate) mod error;
11pub(crate) mod file;
12pub(crate) mod ident;
13mod impls;
14mod improper;
15pub(crate) mod instantiate;
16pub(crate) mod mangle;
17pub(crate) mod map;
18pub(crate) mod message;
19mod names;
20pub(crate) mod namespace;
21mod parse;
22mod pod;
23pub(crate) mod primitive;
24pub(crate) mod qualified;
25pub(crate) mod query;
26pub(crate) mod report;
27pub(crate) mod repr;
28pub(crate) mod resolve;
29pub(crate) mod set;
30mod signature;
31pub(crate) mod symbol;
32mod tokens;
33mod toposort;
34pub(crate) mod trivial;
35pub(crate) mod types;
36pub(crate) mod unpin;
37mod visit;
38
39use self::attrs::OtherAttrs;
40use self::cfg::CfgExpr;
41use self::namespace::Namespace;
42use self::parse::kw;
43use self::symbol::Symbol;
44use proc_macro2::{Ident, Span};
45use syn::punctuated::Punctuated;
46use syn::token::{Brace, Bracket, Paren};
47use syn::{Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
48
49pub(crate) use self::atom::Atom;
50pub(crate) use self::derive::{Derive, Trait};
51pub(crate) use self::discriminant::Discriminant;
52pub(crate) use self::doc::Doc;
53pub(crate) use self::names::ForeignName;
54pub(crate) use self::parse::parse_items;
55pub(crate) use self::types::Types;
56
57pub(crate) enum Api {
58    #[cfg_attr(proc_macro, expect(dead_code))]
59    Include(Include),
60    Struct(Struct),
61    Enum(Enum),
62    CxxType(ExternType),
63    CxxFunction(ExternFn),
64    RustType(ExternType),
65    RustFunction(ExternFn),
66    TypeAlias(TypeAlias),
67    Impl(Impl),
68}
69
70pub(crate) struct Include {
71    pub cfg: CfgExpr,
72    pub path: String,
73    pub kind: IncludeKind,
74    #[cfg_attr(proc_macro, expect(dead_code))]
75    pub begin_span: Span,
76    #[cfg_attr(proc_macro, expect(dead_code))]
77    pub end_span: Span,
78}
79
80/// Whether to emit `#include "path"` or `#include <path>`.
81#[derive(Copy, Clone, PartialEq, Debug)]
82pub enum IncludeKind {
83    /// `#include "quoted/path/to"`
84    Quoted,
85    /// `#include <bracketed/path/to>`
86    Bracketed,
87}
88
89pub(crate) struct ExternType {
90    #[cfg_attr(proc_macro, expect(dead_code))]
91    pub cfg: CfgExpr,
92    pub lang: Lang,
93    pub doc: Doc,
94    pub derives: Vec<Derive>,
95    pub attrs: OtherAttrs,
96    #[cfg_attr(not(proc_macro), expect(dead_code))]
97    pub visibility: Token![pub],
98    pub type_token: Token![type],
99    pub name: Pair,
100    pub generics: Lifetimes,
101    #[expect(dead_code)]
102    pub colon_token: Option<Token![:]>,
103    pub bounds: Vec<Derive>,
104    #[cfg_attr(not(proc_macro), expect(dead_code))]
105    pub semi_token: Token![;],
106    pub trusted: bool,
107}
108
109pub(crate) struct Struct {
110    pub cfg: CfgExpr,
111    pub doc: Doc,
112    pub derives: Vec<Derive>,
113    pub align: Option<LitInt>,
114    pub attrs: OtherAttrs,
115    #[cfg_attr(not(proc_macro), expect(dead_code))]
116    pub visibility: Token![pub],
117    pub struct_token: Token![struct],
118    pub name: Pair,
119    pub generics: Lifetimes,
120    pub brace_token: Brace,
121    pub fields: Vec<Var>,
122}
123
124pub(crate) struct Enum {
125    pub cfg: CfgExpr,
126    pub doc: Doc,
127    pub derives: Vec<Derive>,
128    pub attrs: OtherAttrs,
129    #[cfg_attr(not(proc_macro), expect(dead_code))]
130    pub visibility: Token![pub],
131    pub enum_token: Token![enum],
132    pub name: Pair,
133    pub generics: Lifetimes,
134    pub brace_token: Brace,
135    pub variants: Vec<Variant>,
136    pub repr: EnumRepr,
137    pub explicit_repr: bool,
138}
139
140pub(crate) struct EnumRepr {
141    pub atom: Atom,
142    pub repr_type: Type,
143}
144
145pub(crate) struct ExternFn {
146    pub cfg: CfgExpr,
147    pub lang: Lang,
148    pub doc: Doc,
149    #[cfg_attr(not(proc_macro), expect(dead_code))]
150    pub attrs: OtherAttrs,
151    #[cfg_attr(not(proc_macro), expect(dead_code))]
152    pub visibility: Token![pub],
153    pub name: Pair,
154    pub sig: Signature,
155    pub semi_token: Token![;],
156    pub trusted: bool,
157}
158
159pub(crate) struct TypeAlias {
160    #[cfg_attr(proc_macro, expect(dead_code))]
161    pub cfg: CfgExpr,
162    #[cfg_attr(not(proc_macro), expect(dead_code))]
163    pub doc: Doc,
164    pub derives: Vec<Derive>,
165    pub attrs: OtherAttrs,
166    #[cfg_attr(not(proc_macro), expect(dead_code))]
167    pub visibility: Token![pub],
168    pub type_token: Token![type],
169    pub name: Pair,
170    pub generics: Lifetimes,
171    #[cfg_attr(not(proc_macro), expect(dead_code))]
172    pub eq_token: Token![=],
173    #[cfg_attr(not(proc_macro), expect(dead_code))]
174    pub ty: RustType,
175    #[cfg_attr(not(proc_macro), expect(dead_code))]
176    pub semi_token: Token![;],
177}
178
179pub(crate) struct Impl {
180    pub cfg: CfgExpr,
181    pub impl_token: Token![impl],
182    pub impl_generics: Lifetimes,
183    #[expect(dead_code)]
184    pub negative: bool,
185    pub ty: Type,
186    #[cfg_attr(not(proc_macro), expect(dead_code))]
187    pub ty_generics: Lifetimes,
188    pub brace_token: Brace,
189    pub negative_token: Option<Token![!]>,
190}
191
192#[derive(Clone, Default)]
193pub(crate) struct Lifetimes {
194    pub lt_token: Option<Token![<]>,
195    pub lifetimes: Punctuated<Lifetime, Token![,]>,
196    pub gt_token: Option<Token![>]>,
197}
198
199pub(crate) struct Signature {
200    pub asyncness: Option<Token![async]>,
201    pub unsafety: Option<Token![unsafe]>,
202    pub fn_token: Token![fn],
203    pub generics: Generics,
204    pub kind: FnKind,
205    pub args: Punctuated<Var, Token![,]>,
206    pub ret: Option<Type>,
207    pub throws: bool,
208    pub paren_token: Paren,
209    pub throws_tokens: Option<(kw::Result, Token![<], Token![>])>,
210}
211
212#[derive(PartialEq, Hash)]
213pub(crate) enum FnKind {
214    /// Rust method or C++ non-static member function.
215    Method(Receiver),
216    /// Rust associated function or C++ static member function.
217    Assoc(Ident),
218    /// Non-member function.
219    Free,
220}
221
222pub(crate) struct Var {
223    pub cfg: CfgExpr,
224    pub doc: Doc,
225    #[cfg_attr(not(proc_macro), expect(dead_code))]
226    pub attrs: OtherAttrs,
227    #[cfg_attr(not(proc_macro), expect(dead_code))]
228    pub visibility: Token![pub],
229    pub name: Pair,
230    #[cfg_attr(not(proc_macro), expect(dead_code))]
231    pub colon_token: Token![:],
232    pub ty: Type,
233}
234
235pub(crate) struct Receiver {
236    pub pinned: bool,
237    pub ampersand: Token![&],
238    pub lifetime: Option<Lifetime>,
239    pub mutable: bool,
240    pub var: Token![self],
241    pub ty: NamedType,
242    #[cfg_attr(not(proc_macro), expect(dead_code))]
243    pub colon_token: Token![:],
244    pub shorthand: bool,
245    #[cfg_attr(not(proc_macro), expect(dead_code))]
246    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
247    pub mutability: Option<Token![mut]>,
248}
249
250pub(crate) struct Variant {
251    #[cfg_attr(proc_macro, expect(dead_code))]
252    pub cfg: CfgExpr,
253    pub doc: Doc,
254    pub default: bool,
255    #[cfg_attr(not(proc_macro), expect(dead_code))]
256    pub attrs: OtherAttrs,
257    pub name: Pair,
258    pub discriminant: Discriminant,
259    #[expect(dead_code)]
260    pub expr: Option<Expr>,
261}
262
263pub(crate) enum Type {
264    Ident(NamedType),
265    RustBox(Box<Ty1>),
266    RustVec(Box<Ty1>),
267    UniquePtr(Box<Ty1>),
268    SharedPtr(Box<Ty1>),
269    WeakPtr(Box<Ty1>),
270    Ref(Box<Ref>),
271    Ptr(Box<Ptr>),
272    Str(Box<Ref>),
273    CxxVector(Box<Ty1>),
274    Fn(Box<Signature>),
275    Void(Span),
276    SliceRef(Box<SliceRef>),
277    Array(Box<Array>),
278}
279
280pub(crate) struct Ty1 {
281    pub name: Ident,
282    pub langle: Token![<],
283    pub inner: Type,
284    pub rangle: Token![>],
285}
286
287pub(crate) struct Ref {
288    pub pinned: bool,
289    pub ampersand: Token![&],
290    pub lifetime: Option<Lifetime>,
291    pub mutable: bool,
292    pub inner: Type,
293    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
294    pub mutability: Option<Token![mut]>,
295}
296
297pub(crate) struct Ptr {
298    pub star: Token![*],
299    pub mutable: bool,
300    pub inner: Type,
301    pub mutability: Option<Token![mut]>,
302    pub constness: Option<Token![const]>,
303}
304
305pub(crate) struct SliceRef {
306    pub ampersand: Token![&],
307    pub lifetime: Option<Lifetime>,
308    pub mutable: bool,
309    pub bracket: Bracket,
310    pub inner: Type,
311    pub mutability: Option<Token![mut]>,
312}
313
314pub(crate) struct Array {
315    pub bracket: Bracket,
316    pub inner: Type,
317    pub semi_token: Token![;],
318    pub len: usize,
319    pub len_token: LitInt,
320}
321
322#[derive(Copy, Clone, PartialEq)]
323pub(crate) enum Lang {
324    Cxx,
325    CxxUnwind,
326    Rust,
327}
328
329// An association of a defined Rust name with a fully resolved, namespace
330// qualified C++ name.
331#[derive(Clone)]
332pub(crate) struct Pair {
333    pub namespace: Namespace,
334    pub cxx: ForeignName,
335    pub rust: Ident,
336}
337
338// Wrapper for a type which needs to be resolved before it can be printed in
339// C++.
340#[derive(PartialEq, Eq, Hash)]
341pub(crate) struct NamedType {
342    pub rust: Ident,
343    pub generics: Lifetimes,
344}