1- // Copyright (c) Alexandre Mutel. All rights reserved.
1+ // Copyright (c) Alexandre Mutel. All rights reserved.
22// Licensed under the BSD-Clause 2 license.
33// See license.txt file in the project root for full license information.
44
@@ -84,7 +84,7 @@ private CppType TryToCreateTemplateParameters(CXCursor cursor, void* data)
8484 return null ;
8585 }
8686
87- private CppContainerContext GetOrCreateDeclarationContainer ( CXCursor cursor , void * data )
87+ private bool TryGetDeclarationContainer ( CXCursor cursor , void * data , out string typeKey , out CppContainerContext containerContext )
8888 {
8989 while ( cursor . Kind == CXCursorKind . CXCursor_LinkageSpec )
9090 {
@@ -97,8 +97,13 @@ private CppContainerContext GetOrCreateDeclarationContainer(CXCursor cursor, voi
9797 typeAsCString = CXUtil . GetCursorDisplayName ( cursor ) ;
9898 }
9999 // Try to workaround anonymous types
100- var typeKey = $ "{ cursor . Kind } :{ typeAsCString } { ( cursor . IsAnonymous ? "/" + cursor . Hash : string . Empty ) } ";
101- if ( _containers . TryGetValue ( typeKey , out var containerContext ) )
100+ typeKey = $ "{ cursor . Kind } :{ typeAsCString } { ( cursor . IsAnonymous ? "/" + cursor . Hash : string . Empty ) } ";
101+ return _containers . TryGetValue ( typeKey , out containerContext ) ;
102+ }
103+
104+ private CppContainerContext GetOrCreateDeclarationContainer ( CXCursor cursor , void * data )
105+ {
106+ if ( TryGetDeclarationContainer ( cursor , data , out string typeKey , out var containerContext ) )
102107 {
103108 return containerContext ;
104109 }
@@ -127,7 +132,6 @@ private CppContainerContext GetOrCreateDeclarationContainer(CXCursor cursor, voi
127132 break ;
128133
129134 case CXCursorKind . CXCursor_EnumDecl :
130- Debug . Assert ( parent != null ) ;
131135 var cppEnum = new CppEnum ( CXUtil . GetCursorSpelling ( cursor ) )
132136 {
133137 IsAnonymous = cursor . IsAnonymous ,
@@ -142,7 +146,6 @@ private CppContainerContext GetOrCreateDeclarationContainer(CXCursor cursor, voi
142146 case CXCursorKind . CXCursor_ClassDecl :
143147 case CXCursorKind . CXCursor_StructDecl :
144148 case CXCursorKind . CXCursor_UnionDecl :
145- Debug . Assert ( parent != null ) ;
146149 var cppClass = new CppClass ( CXUtil . GetCursorSpelling ( cursor ) ) ;
147150 parentDeclarationContainer . Classes . Add ( cppClass ) ;
148151 symbol = cppClass ;
@@ -243,10 +246,15 @@ private CppContainerContext GetOrCreateDeclarationContainer(CXCursor cursor, voi
243246 case CXCursorKind . CXCursor_TranslationUnit :
244247 case CXCursorKind . CXCursor_UnexposedDecl :
245248 case CXCursorKind . CXCursor_FirstInvalid :
249+ if ( ! _containers . ContainsKey ( typeKey ) )
250+ {
251+ _containers . Add ( typeKey , _rootContainerContext ) ;
252+ }
246253 return _rootContainerContext ;
247254 default :
248255 Unhandled ( cursor ) ;
249- break ;
256+ // TODO: Workaround for now, as the container below would have an empty symbol
257+ goto case CXCursorKind . CXCursor_TranslationUnit ;
250258 }
251259
252260 containerContext = new CppContainerContext ( symbol ) { CurrentVisibility = defaultContainerVisibility } ;
@@ -1772,6 +1780,13 @@ private CppType VisitElaboratedDecl(CXCursor cursor, CXType type, CXCursor paren
17721780 return typeRef ;
17731781 }
17741782
1783+ // If the type has been already declared, return it immediately.
1784+ if ( TryGetDeclarationContainer ( cursor , data , out _ , out var containerContext ) )
1785+ {
1786+ return ( CppType ) containerContext . Container ;
1787+ }
1788+
1789+ // TODO: Pseudo fix, we are not supposed to land here, as the TryGet before should resolve an existing type already declared (but not necessarily defined)
17751790 return GetCppType ( type . CanonicalType . Declaration , type . CanonicalType , parent , data ) ;
17761791 }
17771792
0 commit comments