Squashed 'third_party/autocxx/' content from commit 629e8fa53
git-subtree-dir: third_party/autocxx
git-subtree-split: 629e8fa531a633164c0b52e2a3cab536d4cd0849
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
Change-Id: I62a03b0049f49adf029e0204639cdb5468dde1a1
diff --git a/engine/src/conversion/analysis/tdef.rs b/engine/src/conversion/analysis/tdef.rs
new file mode 100644
index 0000000..5a635f8
--- /dev/null
+++ b/engine/src/conversion/analysis/tdef.rs
@@ -0,0 +1,128 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::IncludeCppConfig;
+use syn::ItemType;
+
+use crate::{
+ conversion::{
+ analysis::type_converter::{add_analysis, Annotated, TypeConversionContext, TypeConverter},
+ api::{AnalysisPhase, Api, ApiName, NullPhase, TypedefKind},
+ apivec::ApiVec,
+ convert_error::{ConvertErrorWithContext, ErrorContext},
+ error_reporter::convert_apis,
+ parse::BindgenSemanticAttributes,
+ ConvertError,
+ },
+ types::QualifiedName,
+};
+
+pub(crate) struct TypedefAnalysis {
+ pub(crate) kind: TypedefKind,
+ pub(crate) deps: HashSet<QualifiedName>,
+}
+
+/// Analysis phase where typedef analysis has been performed but no other
+/// analyses just yet.
+pub(crate) struct TypedefPhase;
+
+impl AnalysisPhase for TypedefPhase {
+ type TypedefAnalysis = TypedefAnalysis;
+ type StructAnalysis = ();
+ type FunAnalysis = ();
+}
+
+#[allow(clippy::needless_collect)] // we need the extra collect because the closure borrows extra_apis
+pub(crate) fn convert_typedef_targets(
+ config: &IncludeCppConfig,
+ apis: ApiVec<NullPhase>,
+) -> ApiVec<TypedefPhase> {
+ let mut type_converter = TypeConverter::new(config, &apis);
+ let mut extra_apis = ApiVec::new();
+ let mut results = ApiVec::new();
+ convert_apis(
+ apis,
+ &mut results,
+ Api::fun_unchanged,
+ Api::struct_unchanged,
+ Api::enum_unchanged,
+ |name, item, old_tyname, _| {
+ Ok(Box::new(std::iter::once(match item {
+ TypedefKind::Type(ity) => get_replacement_typedef(
+ name,
+ ity,
+ old_tyname,
+ &mut type_converter,
+ &mut extra_apis,
+ )?,
+ TypedefKind::Use { .. } => Api::Typedef {
+ name,
+ item: item.clone(),
+ old_tyname,
+ analysis: TypedefAnalysis {
+ kind: item,
+ deps: HashSet::new(),
+ },
+ },
+ })))
+ },
+ );
+ results.extend(extra_apis.into_iter().map(add_analysis));
+ results
+}
+
+fn get_replacement_typedef(
+ name: ApiName,
+ ity: ItemType,
+ old_tyname: Option<QualifiedName>,
+ type_converter: &mut TypeConverter,
+ extra_apis: &mut ApiVec<NullPhase>,
+) -> Result<Api<TypedefPhase>, ConvertErrorWithContext> {
+ if !ity.generics.params.is_empty() {
+ return Err(ConvertErrorWithContext(
+ ConvertError::TypedefTakesGenericParameters,
+ Some(ErrorContext::new_for_item(name.name.get_final_ident())),
+ ));
+ }
+ let mut converted_type = ity.clone();
+ let metadata = BindgenSemanticAttributes::new_retaining_others(&mut converted_type.attrs);
+ metadata.check_for_fatal_attrs(&ity.ident)?;
+ let type_conversion_results = type_converter.convert_type(
+ (*ity.ty).clone(),
+ name.name.get_namespace(),
+ &TypeConversionContext::WithinReference,
+ );
+ match type_conversion_results {
+ Err(err) => Err(ConvertErrorWithContext(
+ err,
+ Some(ErrorContext::new_for_item(name.name.get_final_ident())),
+ )),
+ Ok(Annotated {
+ ty: syn::Type::Path(ref typ),
+ ..
+ }) if QualifiedName::from_type_path(typ) == name.name => Err(ConvertErrorWithContext(
+ ConvertError::InfinitelyRecursiveTypedef(name.name.clone()),
+ Some(ErrorContext::new_for_item(name.name.get_final_ident())),
+ )),
+ Ok(mut final_type) => {
+ converted_type.ty = Box::new(final_type.ty.clone());
+ extra_apis.append(&mut final_type.extra_apis);
+ Ok(Api::Typedef {
+ name,
+ item: TypedefKind::Type(ity),
+ old_tyname,
+ analysis: TypedefAnalysis {
+ kind: TypedefKind::Type(converted_type),
+ deps: final_type.types_encountered,
+ },
+ })
+ }
+ }
+}