cxx_gen/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;
8pub(crate) mod 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    #[expect(dead_code)]
182    pub attrs: OtherAttrs,
183    pub impl_token: Token![impl],
184    pub impl_generics: Lifetimes,
185    #[expect(dead_code)]
186    pub negative: bool,
187    pub ty: Type,
188    #[cfg_attr(not(proc_macro), expect(dead_code))]
189    pub ty_generics: Lifetimes,
190    pub brace_token: Brace,
191    pub negative_token: Option<Token![!]>,
192}
193
194#[derive(Clone, Default)]
195pub(crate) struct Lifetimes {
196    pub lt_token: Option<Token![<]>,
197    pub lifetimes: Punctuated<Lifetime, Token![,]>,
198    pub gt_token: Option<Token![>]>,
199}
200
201pub(crate) struct Signature {
202    pub asyncness: Option<Token![async]>,
203    pub unsafety: Option<Token![unsafe]>,
204    pub fn_token: Token![fn],
205    pub generics: Generics,
206    pub kind: FnKind,
207    pub args: Punctuated<Var, Token![,]>,
208    pub ret: Option<Type>,
209    pub throws: bool,
210    pub paren_token: Paren,
211    pub throws_tokens: Option<(kw::Result, Token![<], Token![>])>,
212}
213
214#[derive(PartialEq, Hash)]
215pub(crate) enum FnKind {
216    /// Rust method or C++ non-static member function.
217    Method(Receiver),
218    /// Rust associated function or C++ static member function.
219    Assoc(Ident),
220    /// Non-member function.
221    Free,
222}
223
224pub(crate) struct Var {
225    pub cfg: CfgExpr,
226    pub doc: Doc,
227    #[cfg_attr(not(proc_macro), expect(dead_code))]
228    pub attrs: OtherAttrs,
229    #[cfg_attr(not(proc_macro), expect(dead_code))]
230    pub visibility: Token![pub],
231    pub name: Pair,
232    #[cfg_attr(not(proc_macro), expect(dead_code))]
233    pub colon_token: Token![:],
234    pub ty: Type,
235}
236
237pub(crate) struct Receiver {
238    pub pinned: bool,
239    pub ampersand: Token![&],
240    pub lifetime: Option<Lifetime>,
241    pub mutable: bool,
242    pub var: Token![self],
243    pub ty: NamedType,
244    #[cfg_attr(not(proc_macro), expect(dead_code))]
245    pub colon_token: Token![:],
246    pub shorthand: bool,
247    #[cfg_attr(not(proc_macro), expect(dead_code))]
248    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
249    pub mutability: Option<Token![mut]>,
250}
251
252pub(crate) struct Variant {
253    #[cfg_attr(proc_macro, expect(dead_code))]
254    pub cfg: CfgExpr,
255    pub doc: Doc,
256    pub default: bool,
257    #[cfg_attr(not(proc_macro), expect(dead_code))]
258    pub attrs: OtherAttrs,
259    pub name: Pair,
260    pub discriminant: Discriminant,
261    #[expect(dead_code)]
262    pub expr: Option<Expr>,
263}
264
265pub(crate) enum Type {
266    Ident(NamedType),
267    RustBox(Box<Ty1>),
268    RustVec(Box<Ty1>),
269    UniquePtr(Box<Ty1>),
270    SharedPtr(Box<Ty1>),
271    WeakPtr(Box<Ty1>),
272    Ref(Box<Ref>),
273    Ptr(Box<Ptr>),
274    Str(Box<Ref>),
275    CxxVector(Box<Ty1>),
276    Fn(Box<Signature>),
277    Void(Span),
278    SliceRef(Box<SliceRef>),
279    Array(Box<Array>),
280}
281
282pub(crate) struct Ty1 {
283    pub name: Ident,
284    pub langle: Token![<],
285    pub inner: Type,
286    pub rangle: Token![>],
287}
288
289pub(crate) struct Ref {
290    pub pinned: bool,
291    pub ampersand: Token![&],
292    pub lifetime: Option<Lifetime>,
293    pub mutable: bool,
294    pub inner: Type,
295    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
296    pub mutability: Option<Token![mut]>,
297}
298
299pub(crate) struct Ptr {
300    pub star: Token![*],
301    pub mutable: bool,
302    pub inner: Type,
303    pub mutability: Option<Token![mut]>,
304    pub constness: Option<Token![const]>,
305}
306
307pub(crate) struct SliceRef {
308    pub ampersand: Token![&],
309    pub lifetime: Option<Lifetime>,
310    pub mutable: bool,
311    pub bracket: Bracket,
312    pub inner: Type,
313    pub mutability: Option<Token![mut]>,
314}
315
316pub(crate) struct Array {
317    pub bracket: Bracket,
318    pub inner: Type,
319    pub semi_token: Token![;],
320    pub len: usize,
321    pub len_token: LitInt,
322}
323
324#[derive(Copy, Clone, PartialEq)]
325pub(crate) enum Lang {
326    Cxx,
327    CxxUnwind,
328    Rust,
329}
330
331// An association of a defined Rust name with a fully resolved, namespace
332// qualified C++ name.
333#[derive(Clone)]
334pub(crate) struct Pair {
335    pub namespace: Namespace,
336    pub cxx: ForeignName,
337    pub rust: Ident,
338}
339
340// Wrapper for a type which needs to be resolved before it can be printed in
341// C++.
342#[derive(PartialEq, Eq, Hash)]
343pub(crate) struct NamedType {
344    pub rust: Ident,
345    pub generics: Lifetimes,
346}