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