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