1 // Functionality that is shared between the cxxbridge macro and the cmd. 2 3 pub(crate) mod atom; 4 pub(crate) mod attrs; 5 pub(crate) mod cfg; 6 pub(crate) mod check; 7 pub(crate) mod derive; 8 mod discriminant; 9 mod doc; 10 pub(crate) mod error; 11 pub(crate) mod file; 12 pub(crate) mod ident; 13 mod impls; 14 mod improper; 15 pub(crate) mod instantiate; 16 pub(crate) mod mangle; 17 pub(crate) mod map; 18 mod names; 19 pub(crate) mod namespace; 20 mod parse; 21 mod pod; 22 pub(crate) mod qualified; 23 pub(crate) mod report; 24 pub(crate) mod resolve; 25 pub(crate) mod set; 26 pub(crate) mod symbol; 27 mod tokens; 28 mod toposort; 29 pub(crate) mod trivial; 30 pub(crate) mod types; 31 mod visit; 32 33 use self::attrs::OtherAttrs; 34 use self::cfg::CfgExpr; 35 use self::namespace::Namespace; 36 use self::parse::kw; 37 use self::symbol::Symbol; 38 use proc_macro2::{Ident, Span}; 39 use syn::punctuated::Punctuated; 40 use syn::token::{Brace, Bracket, Paren}; 41 use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType}; 42 43 pub(crate) use self::atom::Atom; 44 pub(crate) use self::derive::{Derive, Trait}; 45 pub(crate) use self::discriminant::Discriminant; 46 pub(crate) use self::doc::Doc; 47 pub(crate) use self::names::ForeignName; 48 pub(crate) use self::parse::parse_items; 49 pub(crate) use self::types::Types; 50 51 pub(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 64 pub(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)] 76 pub enum IncludeKind { 77 /// `#include "quoted/path/to"` 78 Quoted, 79 /// `#include <bracketed/path/to>` 80 Bracketed, 81 } 82 83 pub(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 104 pub(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 120 pub(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 141 pub(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 152 pub(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 167 pub(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 188 pub(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)] 203 pub(crate) struct Lifetimes { 204 pub lt_token: Option<Token![<]>, 205 pub lifetimes: Punctuated<Lifetime, Token![,]>, 206 pub gt_token: Option<Token![>]>, 207 } 208 209 pub(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 222 pub(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 236 pub(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 251 pub(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 263 pub(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 280 pub(crate) struct Ty1 { 281 pub name: Ident, 282 pub langle: Token![<], 283 pub inner: Type, 284 pub rangle: Token![>], 285 } 286 287 pub(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 297 pub(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 305 pub(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 314 pub(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)] 323 pub(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)] 331 pub(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)] 340 pub(crate) struct NamedType { 341 pub rust: Ident, 342 pub generics: Lifetimes, 343 } 344