@@ -738,19 +738,17 @@ impl Snapshot {
738738 return Err ( Error ( format ! ( "duplicate planned name `{}`" , function. name) ) ) ;
739739 }
740740 }
741- for constant in plan. constants {
741+ for planned in plan. constants {
742+ let constant = planned. constant ;
742743 let encoding = match & constant. value {
743744 Value :: Utf8 ( _) => " #[encoding(\" ansi\" )]\n " ,
744745 Value :: Utf16 ( _) => " #[encoding(\" utf-16\" )]\n " ,
745746 _ => "" ,
746747 } ;
747- let ty = match & constant. value {
748- Value :: Utf8 ( _) | Value :: Utf16 ( _) => "String" . to_string ( ) ,
749- _ => constant_type_name ( & constant. ty , & plan. type_names ) ,
750- } ;
751748 let item = format ! (
752- "{encoding} const {}: {ty } = {};\n " ,
749+ "{encoding} const {}: {} = {};\n " ,
753750 rdl_ident( & constant. name) ,
751+ planned. ty,
754752 value_name( & constant. value)
755753 ) ;
756754 if items
@@ -1617,10 +1615,52 @@ impl Snapshot {
16171615 ) ) ) ;
16181616 }
16191617 }
1618+ let mut pointer_aliases: BTreeMap < & str , Vec < & str > > = BTreeMap :: new ( ) ;
1619+ for fact in & self . facts {
1620+ let FactData :: Typedef {
1621+ target : TypeRef :: Named { name : target, .. } | TypeRef :: Generic { name : target, .. } ,
1622+ } = & fact. data
1623+ else {
1624+ continue ;
1625+ } ;
1626+ pointer_aliases. entry ( target) . or_default ( ) . push ( & fact. name ) ;
1627+ }
1628+ let mut pointer_alias_queue: Vec < _ > = pointer_interface_aliases. keys ( ) . cloned ( ) . collect ( ) ;
1629+ while let Some ( target) = pointer_alias_queue. pop ( ) {
1630+ let projected = pointer_interface_aliases[ & target] . clone ( ) ;
1631+ for alias in pointer_aliases. get ( target. as_str ( ) ) . into_iter ( ) . flatten ( ) {
1632+ if let Some ( previous) = pointer_interface_aliases. get ( * alias) {
1633+ if previous != & projected {
1634+ return Err ( Error ( format ! (
1635+ "interface pointer alias `{alias}` has conflicting targets"
1636+ ) ) ) ;
1637+ }
1638+ } else {
1639+ pointer_interface_aliases. insert ( ( * alias) . to_string ( ) , projected. clone ( ) ) ;
1640+ pointer_alias_queue. push ( ( * alias) . to_string ( ) ) ;
1641+ }
1642+ }
1643+ }
16201644 for ( alias, target) in & pointer_interface_aliases {
16211645 type_names. insert ( alias. clone ( ) , target. clone ( ) ) ;
16221646 }
16231647 types. retain ( |planned| !pointer_interface_aliases. contains_key ( & planned. fact . name ) ) ;
1648+ let mut constants: Vec < _ > = constants
1649+ . into_iter ( )
1650+ . filter_map ( |constant| {
1651+ let ty = match & constant. value {
1652+ Value :: Utf8 ( _) | Value :: Utf16 ( _) => Some ( "String" . to_string ( ) ) ,
1653+ _ => constant_type_name (
1654+ & constant. ty ,
1655+ & type_names,
1656+ & interface_names,
1657+ & pointer_interface_aliases,
1658+ & constant. root . tu ,
1659+ ) ,
1660+ } ?;
1661+ Some ( PlannedConstant { constant, ty } )
1662+ } )
1663+ . collect ( ) ;
16241664 if timing {
16251665 eprintln ! (
16261666 "clang plan interfaces: {:.2}s" ,
@@ -1651,9 +1691,12 @@ impl Snapshot {
16511691 return Err ( Error ( format ! ( "duplicate planned name `{}`" , planned. name) ) ) ;
16521692 }
16531693 }
1654- for constant in & constants {
1655- if !value_output_names. insert ( constant. name . as_str ( ) ) {
1656- return Err ( Error ( format ! ( "duplicate planned name `{}`" , constant. name) ) ) ;
1694+ for planned in & constants {
1695+ if !value_output_names. insert ( planned. constant . name . as_str ( ) ) {
1696+ return Err ( Error ( format ! (
1697+ "duplicate planned name `{}`" ,
1698+ planned. constant. name
1699+ ) ) ) ;
16571700 }
16581701 }
16591702 for function in & functions {
@@ -1663,7 +1706,7 @@ impl Snapshot {
16631706 return Err ( Error ( format ! ( "duplicate planned name `{}`" , function. name) ) ) ;
16641707 }
16651708 }
1666- constants. sort_by ( |left, right| left. name . cmp ( & right. name ) ) ;
1709+ constants. sort_by ( |left, right| left. constant . name . cmp ( & right. constant . name ) ) ;
16671710 functions. sort_by ( |left, right| left. name . cmp ( & right. name ) ) ;
16681711 if timing {
16691712 eprintln ! (
@@ -1722,6 +1765,11 @@ struct PlannedFact<'a> {
17221765 name : String ,
17231766}
17241767
1768+ struct PlannedConstant < ' a > {
1769+ constant : & ' a Constant ,
1770+ ty : String ,
1771+ }
1772+
17251773#[ derive( Clone , Copy , Eq , Ord , PartialEq , PartialOrd ) ]
17261774enum OutputKind {
17271775 Value ,
@@ -1732,7 +1780,7 @@ struct Plan<'a> {
17321780 types : Vec < PlannedFact < ' a > > ,
17331781 values : Vec < PlannedFact < ' a > > ,
17341782 functions : Vec < & ' a Fact > ,
1735- constants : Vec < & ' a Constant > ,
1783+ constants : Vec < PlannedConstant < ' a > > ,
17361784 type_names : BTreeMap < String , String > ,
17371785 interface_names : BTreeSet < ( String , String ) > ,
17381786 interface_guids : BTreeMap < String , String > ,
@@ -3806,16 +3854,36 @@ fn pointer_run(mut ty: &TypeRef) -> (bool, usize, &TypeRef) {
38063854 ( mutable, depth, ty)
38073855}
38083856
3809- fn constant_type_name ( ty : & TypeRef , type_names : & BTreeMap < String , String > ) -> String {
3810- match ty {
3857+ fn constant_type_name (
3858+ ty : & TypeRef ,
3859+ type_names : & BTreeMap < String , String > ,
3860+ interface_names : & BTreeSet < ( String , String ) > ,
3861+ pointer_interface_aliases : & BTreeMap < String , String > ,
3862+ tu : & str ,
3863+ ) -> Option < String > {
3864+ let name = match ty {
38113865 TypeRef :: Scalar ( Scalar :: Bool ) => "u32" . to_string ( ) ,
3866+ TypeRef :: Named { name, .. } if pointer_interface_aliases. contains_key ( name) => {
3867+ return None ;
3868+ }
3869+ TypeRef :: Named { name, .. } | TypeRef :: Generic { name, .. }
3870+ if interface_names. contains ( & ( tu. to_string ( ) , name. clone ( ) ) ) =>
3871+ {
3872+ return None ;
3873+ }
38123874 TypeRef :: Named { name, .. } if type_names. contains_key ( name) => {
38133875 planned_type_name ( ty, type_names)
38143876 }
38153877 TypeRef :: Named { name, .. } => canonical_named_type ( name)
38163878 . map_or_else ( || planned_type_name ( ty, type_names) , str:: to_string) ,
3879+ TypeRef :: Void
3880+ | TypeRef :: Object
3881+ | TypeRef :: Generic { .. }
3882+ | TypeRef :: Array { .. }
3883+ | TypeRef :: InlineRecord ( _) => return None ,
38173884 _ => planned_type_name ( ty, type_names) ,
3818- }
3885+ } ;
3886+ Some ( name)
38193887}
38203888
38213889fn value_name ( value : & Value ) -> String {
0 commit comments