@@ -71,6 +71,13 @@ fn match_pattern(ctx: &mut ClangParserCtx, cursor: &Cursor) -> bool {
7171 ctx. options . match_pat . iter ( ) . any ( |pat| name. contains ( pat) )
7272}
7373
74+ fn conv_template_type_parameter ( ctx : & mut ClangParserCtx , cursor : & Cursor ) -> Type {
75+ assert_eq ! ( cursor. kind( ) , CXCursor_TemplateTypeParameter ) ;
76+ let ty = conv_ty ( ctx, & cursor. cur_type ( ) , cursor) ;
77+ let layout = Layout :: new ( ty. size ( ) , ty. align ( ) ) ;
78+ TNamed ( Rc :: new ( RefCell :: new ( TypeInfo :: new ( cursor. spelling ( ) , ctx. current_module_id , TVoid , layout) ) ) )
79+ }
80+
7481fn decl_name ( ctx : & mut ClangParserCtx , cursor : & Cursor ) -> Global {
7582 let cursor = cursor. canonical ( ) ;
7683 let override_enum_ty = ctx. options . override_enum_ty ;
@@ -101,26 +108,31 @@ fn decl_name(ctx: &mut ClangParserCtx, cursor: &Cursor) -> Global {
101108 let hide = ctx. options . blacklist_type . iter ( ) . any ( |name| * name == spelling) ;
102109
103110 let mut has_non_type_template_params = false ;
104- let args = match cursor. kind ( ) {
105- CXCursor_ClassDecl => {
106- match ty. num_template_args ( ) {
107- -1 => vec ! [ ] ,
108- len => {
109- let mut list = Vec :: with_capacity ( len as usize ) ;
110- for i in 0 ..len {
111- let arg_type = ty. template_arg_type ( i) ;
112- if arg_type. kind ( ) != CXType_Invalid {
113- list. push ( conv_ty ( ctx, & arg_type, & cursor) ) ;
114- } else {
115- has_non_type_template_params = true ;
116- ctx. logger . warn ( "warning: Template parameter is not a type" ) ;
117- }
118- }
119- list
111+ let args = match ty. num_template_args ( ) {
112+ // In forward declarations, etc, they are in the ast... sigh
113+ -1 => {
114+ let mut args = vec ! [ ] ;
115+ cursor. visit ( |c, _| {
116+ if c. kind ( ) == CXCursor_TemplateTypeParameter {
117+ args. push ( conv_template_type_parameter ( ctx, c) ) ;
118+ }
119+ CXChildVisit_Continue
120+ } ) ;
121+ args
122+ }
123+ len => {
124+ let mut list = Vec :: with_capacity ( len as usize ) ;
125+ for i in 0 ..len {
126+ let arg_type = ty. template_arg_type ( i) ;
127+ if arg_type. kind ( ) != CXType_Invalid {
128+ list. push ( conv_ty ( ctx, & arg_type, & cursor) ) ;
129+ } else {
130+ has_non_type_template_params = true ;
131+ ctx. logger . warn ( "warning: Template parameter is not a type" ) ;
120132 }
121133 }
134+ list
122135 }
123- _ => vec ! [ ] ,
124136 } ;
125137
126138 let mut ci = CompInfo :: new ( spelling, ctx. current_module_id , filename, comment, kind, vec ! [ ] , layout) ;
@@ -210,6 +222,7 @@ fn opaque_decl(ctx: &mut ClangParserCtx, decl: &Cursor) {
210222 }
211223
212224 let name = decl_name ( ctx, decl) ;
225+ println ! ( "{:?}" , name) ;
213226 ctx. current_module_mut ( ) . globals . push ( name) ;
214227}
215228
@@ -602,41 +615,41 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
602615 // incomplete type via the declaration or anything like
603616 // that. We can inspect the AST and deduct them though,
604617 // since there's a leading CXCursor_TemplateRef.
605- if child_ci. args . is_empty ( ) {
618+ if child_ci. args . is_empty ( ) && child_cursor . kind ( ) == CXCursor_ClassDecl {
606619 // println!("child: {:?} {:?}, {:?}, {:?}", cursor.spelling(),
607620 // type_to_str(cursor_ty.kind()),
608621 // type_to_str(child_cursor.cur_type().kind()),
609622 // kind_to_str(child_cursor.kind()));
610- match child_cursor. kind ( ) {
611- CXCursor_ClassDecl => {
612- if child_ci. name == ci. name &&
613- child_ci. module_id == ci. module_id {
614- child_ci. args = ci. args . clone ( ) ;
615- }
623+ if child_ci. name == ci. name &&
624+ child_ci. module_id == ci. module_id {
625+ child_ci. args = ci. args . clone ( ) ;
626+ }
627+ }
628+
629+ if child_cursor. kind ( ) == CXCursor_ClassTemplate {
630+ // We need to take into account the possibly different
631+ // type template names, so we need to clear them and
632+ // re-scan.
633+ child_ci. args . clear ( ) ;
634+ let mut found_invalid_template_ref = false ;
635+ cursor. visit ( |c, _| {
636+ // println!("ichild: {:?} {:?}, {:?}", c.spelling(),
637+ // kind_to_str(c.kind()),
638+ // type_to_str(c.cur_type().kind()));
639+ if c. kind ( ) == CXCursor_TemplateRef &&
640+ c. cur_type ( ) . kind ( ) == CXType_Invalid {
641+ found_invalid_template_ref = true ;
616642 }
617- CXCursor_ClassTemplate => {
618- let mut found_invalid_template_ref = false ;
619- cursor. visit ( |c, _| {
620- // println!("ichild: {:?} {:?}, {:?}", c.spelling(),
621- // kind_to_str(c.kind()),
622- // type_to_str(c.cur_type().kind()));
623- if c. kind ( ) == CXCursor_TemplateRef &&
624- c. cur_type ( ) . kind ( ) == CXType_Invalid {
625- found_invalid_template_ref = true ;
626- }
627- if found_invalid_template_ref &&
628- c. kind ( ) == CXCursor_TypeRef {
629- child_ci. args . push ( TNamed ( Rc :: new ( RefCell :: new (
630- TypeInfo :: new ( c. spelling ( ) ,
631- ctx. current_module_id ,
632- TVoid ,
633- Layout :: zero ( ) ) ) ) ) ) ;
634- }
635- CXChildVisit_Continue
636- } )
643+ if found_invalid_template_ref &&
644+ c. kind ( ) == CXCursor_TypeRef {
645+ child_ci. args . push ( TNamed ( Rc :: new ( RefCell :: new (
646+ TypeInfo :: new ( c. spelling ( ) ,
647+ ctx. current_module_id ,
648+ TVoid ,
649+ Layout :: zero ( ) ) ) ) ) ) ;
637650 }
638- _ => { }
639- }
651+ CXChildVisit_Continue
652+ } )
640653 }
641654 }
642655 }
@@ -796,9 +809,7 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
796809 ci. layout . packed = true ;
797810 }
798811 CXCursor_TemplateTypeParameter => {
799- let ty = conv_ty ( ctx, & cursor. cur_type ( ) , cursor) ;
800- let layout = Layout :: new ( ty. size ( ) , ty. align ( ) ) ;
801- ci. args . push ( TNamed ( Rc :: new ( RefCell :: new ( TypeInfo :: new ( cursor. spelling ( ) , ctx. current_module_id , TVoid , layout) ) ) ) ) ;
812+ ci. args . push ( conv_template_type_parameter ( ctx, cursor) ) ;
802813 }
803814 CXCursor_EnumDecl => {
804815 let anno = Annotations :: new ( cursor) ;
0 commit comments