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 qualified;
23pub(crate) mod report;
24pub(crate) mod resolve;
25pub(crate) mod set;
26pub(crate) mod symbol;
27mod tokens;
28mod toposort;
29pub(crate) mod trivial;
30pub(crate) mod types;
31mod visit;
32
33use self::attrs::OtherAttrs;
34use self::cfg::CfgExpr;
35use self::namespace::Namespace;
36use self::parse::kw;
37use self::symbol::Symbol;
38use proc_macro2::{Ident, Span};
39use syn::punctuated::Punctuated;
40use syn::token::{Brace, Bracket, Paren};
41use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
42
43pub(crate) use self::atom::Atom;
44pub(crate) use self::derive::{Derive, Trait};
45pub(crate) use self::discriminant::Discriminant;
46pub(crate) use self::doc::Doc;
47pub(crate) use self::names::ForeignName;
48pub(crate) use self::parse::parse_items;
49pub(crate) use self::types::Types;
50
51pub(crate) enum Api {
52    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
53    Include(Include),
54    Struct(Struct),
55    Enum(Enum),
56    CxxType(ExternType),
57    CxxFunction(ExternFn),
58    RustType(ExternType),
59    RustFunction(ExternFn),
60    TypeAlias(TypeAlias),
61    Impl(Impl),
62}
63
64pub(crate) struct Include {
65    pub cfg: CfgExpr,
66    pub path: String,
67    pub kind: IncludeKind,
68    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
69    pub begin_span: Span,
70    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
71    pub end_span: Span,
72}
73
74/// Whether to emit `#include "path"` or `#include <path>`.
75#[derive(Copy, Clone, PartialEq, Debug)]
76pub enum IncludeKind {
77    /// `#include "quoted/path/to"`
78    Quoted,
79    /// `#include <bracketed/path/to>`
80    Bracketed,
81}
82
83pub(crate) struct ExternType {
84    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
85    pub cfg: CfgExpr,
86    pub lang: Lang,
87    pub doc: Doc,
88    pub derives: Vec<Derive>,
89    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
90    pub attrs: OtherAttrs,
91    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
92    pub visibility: Token![pub],
93    pub type_token: Token![type],
94    pub name: Pair,
95    pub generics: Lifetimes,
96    #[allow(dead_code)]
97    pub colon_token: Option<Token![:]>,
98    pub bounds: Vec<Derive>,
99    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
100    pub semi_token: Token![;],
101    pub trusted: bool,
102}
103
104pub(crate) struct Struct {
105    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
106    pub cfg: CfgExpr,
107    pub doc: Doc,
108    pub derives: Vec<Derive>,
109    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
110    pub attrs: OtherAttrs,
111    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
112    pub visibility: Token![pub],
113    pub struct_token: Token![struct],
114    pub name: Pair,
115    pub generics: Lifetimes,
116    pub brace_token: Brace,
117    pub fields: Vec<Var>,
118}
119
120pub(crate) struct Enum {
121    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
122    pub cfg: CfgExpr,
123    pub doc: Doc,
124    pub derives: Vec<Derive>,
125    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
126    pub attrs: OtherAttrs,
127    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
128    pub visibility: Token![pub],
129    pub enum_token: Token![enum],
130    pub name: Pair,
131    pub generics: Lifetimes,
132    pub brace_token: Brace,
133    pub variants: Vec<Variant>,
134    pub variants_from_header: bool,
135    #[allow(dead_code)]
136    pub variants_from_header_attr: Option<Attribute>,
137    pub repr: EnumRepr,
138    pub explicit_repr: bool,
139}
140
141pub(crate) enum EnumRepr {
142    Native {
143        atom: Atom,
144        repr_type: Type,
145    },
146    #[cfg(feature = "experimental-enum-variants-from-header")]
147    Foreign {
148        rust_type: syn::Path,
149    },
150}
151
152pub(crate) struct ExternFn {
153    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
154    pub cfg: CfgExpr,
155    pub lang: Lang,
156    pub doc: Doc,
157    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
158    pub attrs: OtherAttrs,
159    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
160    pub visibility: Token![pub],
161    pub name: Pair,
162    pub sig: Signature,
163    pub semi_token: Token![;],
164    pub trusted: bool,
165}
166
167pub(crate) struct TypeAlias {
168    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
169    pub cfg: CfgExpr,
170    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
171    pub doc: Doc,
172    pub derives: Vec<Derive>,
173    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
174    pub attrs: OtherAttrs,
175    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
176    pub visibility: Token![pub],
177    pub type_token: Token![type],
178    pub name: Pair,
179    pub generics: Lifetimes,
180    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
181    pub eq_token: Token![=],
182    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
183    pub ty: RustType,
184    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
185    pub semi_token: Token![;],
186}
187
188pub(crate) struct Impl {
189    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
190    pub cfg: CfgExpr,
191    pub impl_token: Token![impl],
192    pub impl_generics: Lifetimes,
193    #[allow(dead_code)]
194    pub negative: bool,
195    pub ty: Type,
196    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
197    pub ty_generics: Lifetimes,
198    pub brace_token: Brace,
199    pub negative_token: Option<Token![!]>,
200}
201
202#[derive(Clone, Default)]
203pub(crate) struct Lifetimes {
204    pub lt_token: Option<Token![<]>,
205    pub lifetimes: Punctuated<Lifetime, Token![,]>,
206    pub gt_token: Option<Token![>]>,
207}
208
209pub(crate) struct Signature {
210    pub asyncness: Option<Token![async]>,
211    pub unsafety: Option<Token![unsafe]>,
212    pub fn_token: Token![fn],
213    pub generics: Generics,
214    pub receiver: Option<Receiver>,
215    pub args: Punctuated<Var, Token![,]>,
216    pub ret: Option<Type>,
217    pub throws: bool,
218    pub paren_token: Paren,
219    pub throws_tokens: Option<(kw::Result, Token![<], Token![>])>,
220}
221
222pub(crate) struct Var {
223    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
224    pub cfg: CfgExpr,
225    pub doc: Doc,
226    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
227    pub attrs: OtherAttrs,
228    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
229    pub visibility: Token![pub],
230    pub name: Pair,
231    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
232    pub colon_token: Token![:],
233    pub ty: Type,
234}
235
236pub(crate) struct Receiver {
237    pub pinned: bool,
238    pub ampersand: Token![&],
239    pub lifetime: Option<Lifetime>,
240    pub mutable: bool,
241    pub var: Token![self],
242    pub ty: NamedType,
243    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
244    pub colon_token: Token![:],
245    pub shorthand: bool,
246    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
247    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
248    pub mutability: Option<Token![mut]>,
249}
250
251pub(crate) struct Variant {
252    #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
253    pub cfg: CfgExpr,
254    pub doc: Doc,
255    #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
256    pub attrs: OtherAttrs,
257    pub name: Pair,
258    pub discriminant: Discriminant,
259    #[allow(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    Rust,
326}
327
328// An association of a defined Rust name with a fully resolved, namespace
329// qualified C++ name.
330#[derive(Clone)]
331pub(crate) struct Pair {
332    pub namespace: Namespace,
333    pub cxx: ForeignName,
334    pub rust: Ident,
335}
336
337// Wrapper for a type which needs to be resolved before it can be printed in
338// C++.
339#[derive(PartialEq, Eq, Hash)]
340pub(crate) struct NamedType {
341    pub rust: Ident,
342    pub generics: Lifetimes,
343}