@@ -32,15 +32,13 @@ public override void Process()
3232 NewLine ( ) ;
3333 }
3434
35- public override bool VisitClassTemplateSpecializationDecl ( ClassTemplateSpecialization specialization )
36- {
37- WriteLine ( $ "template class { GetExporting ( ) } { specialization . Visit ( cppTypePrinter ) } ;") ;
38- return true ;
39- }
40-
4135 public override bool VisitMethodDecl ( Method method )
4236 {
43- if ( method . Namespace is ClassTemplateSpecialization )
37+ if ( method . Namespace is ClassTemplateSpecialization specialization &&
38+ ( method . TranslationUnit . IsSystemHeader ||
39+ ( ( method . IsConstructor || method . IsDestructor ) &&
40+ ! method . IsImplicit && ! method . IsDefaulted && ! method . IsPure &&
41+ string . IsNullOrEmpty ( method . Body ) ) ) )
4442 {
4543 WriteLine ( $ "template { GetExporting ( ) } { method . Visit ( cppTypePrinter ) } ;") ;
4644 return true ;
@@ -120,7 +118,7 @@ private void WrapConstructor(Method method)
120118 if ( method . Access == AccessSpecifier . Protected )
121119 {
122120 Write ( GetDerivedType ( @namespace , wrapper ) ) ;
123- Write ( $ " { wrapper } { @namespace } " ) ;
121+ Write ( wrapper + @namespace ) ;
124122 Write ( $@ "({ string . Join ( ", " , method . Parameters . Select (
125123 p => cppTypePrinter . VisitParameter ( p ) ) ) } )" ) ;
126124 WriteLine ( $ ": { @namespace } ({ @params } ) {{}} }};") ;
@@ -129,7 +127,7 @@ private void WrapConstructor(Method method)
129127 }
130128 else
131129 {
132- Write ( $ "extern \" C\" ") ;
130+ Write ( "extern \" C\" " ) ;
133131 if ( method . Namespace . Access == AccessSpecifier . Protected )
134132 Write ( $@ "{{ class { wrapper } { method . Namespace . Namespace . Name } : public {
135133 method . Namespace . Namespace . Visit ( cppTypePrinter ) } " ) ;
@@ -168,22 +166,24 @@ private void WrapDestructor(Method method)
168166 bool isProtected = method . Access == AccessSpecifier . Protected ;
169167 string @namespace = method . Namespace . Visit ( cppTypePrinter ) ;
170168 if ( isProtected )
171- Write ( GetDerivedType ( @namespace , wrapper ) ) ;
169+ Write ( $ "class { wrapper } : public { @namespace } {{ public: " ) ;
172170 else
173171 Write ( "extern \" C\" { " ) ;
174172 if ( method . Namespace . Access == AccessSpecifier . Protected )
175173 Write ( $@ "class { wrapper } { method . Namespace . Namespace . Name } : public {
176174 method . Namespace . Namespace . Visit ( cppTypePrinter ) } {{ " ) ;
177175 Write ( $ "void { wrapper } ") ;
178176 if ( isProtected )
179- Write ( "protected" ) ;
180- Write ( $@ "({ @namespace } * { Helpers . InstanceField } ) {{ {
181- Helpers . InstanceField } ->~{ method . Namespace . OriginalName } (); }} }}" ) ;
177+ Write ( "Protected" ) ;
178+
179+ string instance = Helpers . InstanceField ;
180+ Write ( $@ "({ ( isProtected ? wrapper : @namespace ) } * {
181+ instance } ) {{ delete { instance } ; }} }};" ) ;
182182 if ( isProtected )
183183 {
184184 NewLine ( ) ;
185- Write ( $@ "void { wrapper } ({ @namespace } { Helpers . InstanceField } ) {{ {
186- wrapper } { @namespace } :: { wrapper } protected( { Helpers . InstanceField } ); }}" ) ;
185+ Write ( $@ "extern ""C"" {{ void { wrapper } ({ wrapper } * { instance } ) {{ {
186+ instance } -> { wrapper } Protected( { instance } ); }} }}" ) ;
187187 }
188188 if ( method . Namespace . Access == AccessSpecifier . Protected )
189189 Write ( "; }" ) ;
@@ -192,14 +192,14 @@ private void WrapDestructor(Method method)
192192
193193 private void TakeFunctionAddress ( Function function )
194194 {
195+ //function = function.OriginalFunction ?? function;
195196 string wrapper = GetWrapper ( function ) ;
196- string @namespace = function . Namespace . Visit ( cppTypePrinter ) ;
197+ string @namespace = function . OriginalNamespace . Visit ( cppTypePrinter ) ;
197198 if ( function . Access == AccessSpecifier . Protected )
198199 {
199- Write ( GetDerivedType ( @namespace , wrapper ) ) ;
200+ Write ( $ "class { wrapper } { function . Namespace . Name } : public { @namespace } {{ public: " ) ;
200201 Write ( "static constexpr " ) ;
201202 }
202-
203203 string returnType = function . OriginalReturnType . Visit ( cppTypePrinter ) ;
204204 string signature = GetSignature ( function ) ;
205205
@@ -209,15 +209,15 @@ private void TakeFunctionAddress(Function function)
209209
210210 var method = function as Method ;
211211 if ( function . Namespace . Access == AccessSpecifier . Protected )
212- Write ( $@ "class { wrapper } { function . Namespace . Namespace . Name } : public {
212+ Write ( $@ "class { wrapper } { function . Namespace . Name } : public {
213213 function . Namespace . Namespace . Visit ( cppTypePrinter ) } {{ " ) ;
214214 Write ( $@ "{ returnType } ({ ( method != null && ! method . IsStatic ?
215215 ( @namespace + "::" ) : string . Empty ) } *{ wrapper } ){ signature } " ) ;
216216 if ( function . Access == AccessSpecifier . Protected )
217217 {
218- Write ( $ " = &{ wrapper } { @namespace } ::{ functionName } ;") ;
218+ Write ( $ " = &{ wrapper } { function . Namespace . Name } ::{ functionName } ;") ;
219219 WriteLine ( " };" ) ;
220- Write ( $ "auto { wrapper } protected = { wrapper } { @namespace } ::{ wrapper } ;") ;
220+ Write ( $ "auto { wrapper } Protected = { wrapper } { function . Namespace . Name } ::{ wrapper } ;") ;
221221 }
222222 else
223223 {
@@ -251,25 +251,47 @@ private string GetSignature(Function function)
251251
252252 private string GetFunctionName ( Function function , string @namespace )
253253 {
254- return $@ "{ ( function . Access == AccessSpecifier . Protected ||
255- string . IsNullOrEmpty ( @namespace ) ?
256- string . Empty : ( @namespace + "::" ) ) } { function . OriginalName } {
257- ( function . SpecializationInfo == null ? string . Empty : $@ "<{
258- string . Join ( ", " , function . SpecializationInfo . Arguments . Select (
259- a =>
260- {
261- switch ( a . Kind )
262- {
263- case TemplateArgument . ArgumentKind . Type :
264- return a . Type . Visit ( cppTypePrinter ) . Type ;
265- case TemplateArgument . ArgumentKind . Declaration :
266- return a . Declaration . Visit ( cppTypePrinter ) . Type ;
267- case TemplateArgument . ArgumentKind . Integral :
268- return a . Integral . ToString ( CultureInfo . InvariantCulture ) ;
269- }
270- throw new System . ArgumentOutOfRangeException (
271- nameof ( a . Kind ) , a . Kind , "Unsupported kind of template argument." ) ;
272- } ) ) } >" ) } ";
254+ var nameBuilder = new StringBuilder ( ) ;
255+ if ( function . Access != AccessSpecifier . Protected &&
256+ ! string . IsNullOrEmpty ( @namespace ) )
257+ nameBuilder . Append ( @namespace ) . Append ( "::" ) ;
258+
259+ bool isConversionToSpecialization =
260+ ( function . OperatorKind == CXXOperatorKind . Conversion ||
261+ function . OperatorKind == CXXOperatorKind . ExplicitConversion ) &&
262+ function . OriginalReturnType . Type . Desugar (
263+ ) . TryGetDeclaration ( out ClassTemplateSpecialization specialization ) ;
264+
265+ nameBuilder . Append ( isConversionToSpecialization ?
266+ "operator " : function . OriginalName ) ;
267+
268+ if ( function . SpecializationInfo != null )
269+ nameBuilder . Append ( '<' ) . Append ( string . Join ( ", " ,
270+ GetTemplateArguments ( function . SpecializationInfo . Arguments ) ) ) . Append ( '>' ) ;
271+ else if ( isConversionToSpecialization )
272+ nameBuilder . Append ( function . OriginalReturnType . Visit ( cppTypePrinter ) ) ;
273+
274+ return nameBuilder . ToString ( ) ;
275+ }
276+
277+ private IEnumerable < string > GetTemplateArguments (
278+ IEnumerable < TemplateArgument > templateArguments )
279+ {
280+ return templateArguments . Select (
281+ a =>
282+ {
283+ switch ( a . Kind )
284+ {
285+ case TemplateArgument . ArgumentKind . Type :
286+ return a . Type . Visit ( cppTypePrinter ) . Type ;
287+ case TemplateArgument . ArgumentKind . Declaration :
288+ return a . Declaration . Visit ( cppTypePrinter ) . Type ;
289+ case TemplateArgument . ArgumentKind . Integral :
290+ return a . Integral . ToString ( CultureInfo . InvariantCulture ) ;
291+ }
292+ throw new System . ArgumentOutOfRangeException (
293+ nameof ( a . Kind ) , a . Kind , "Unsupported kind of template argument." ) ;
294+ } ) ;
273295 }
274296
275297 private void WriteRedeclaration ( Function function , string returnType ,
@@ -286,7 +308,7 @@ private void WriteRedeclaration(Function function, string returnType,
286308 Write ( paramTypes ) ;
287309 if ( functionType . ExceptionSpecType == ExceptionSpecType . BasicNoexcept )
288310 Write ( " noexcept" ) ;
289- WriteLine ( $ ";{ string . Concat ( parentsOpen . Select ( p => " }" ) ) } ") ;
311+ WriteLine ( $ ";{ string . Concat ( parentsOpen . Select ( _ => " }" ) ) } ") ;
290312 }
291313
292314 private static Stack < string > GenerateNamespace ( Function function )
@@ -301,7 +323,7 @@ private static Stack<string> GenerateNamespace(Function function)
301323 if ( finalType . TryGetDeclaration ( out declaration ) )
302324 declarationContextsInSignature . Add ( declaration . Namespace ) ;
303325 }
304- var nestedNamespace = declarationContextsInSignature . FirstOrDefault ( d =>
326+ var nestedNamespace = declarationContextsInSignature . Find ( d =>
305327 d . Namespace is Namespace && ! ( d . Namespace is TranslationUnit ) ) ;
306328 var parentsOpen = new Stack < string > ( ) ;
307329 if ( nestedNamespace != null )
@@ -320,7 +342,8 @@ private static Stack<string> GenerateNamespace(Function function)
320342
321343 private CppTypePrinter cppTypePrinter = new CppTypePrinter
322344 {
323- ScopeKind = TypePrintScopeKind . Qualified
345+ ScopeKind = TypePrintScopeKind . Qualified ,
346+ ResolveTypedefs = true
324347 } ;
325348 private int functionCount ;
326349 }
0 commit comments