@@ -32,15 +32,13 @@ public override void Process()
32
32
NewLine ( ) ;
33
33
}
34
34
35
- public override bool VisitClassTemplateSpecializationDecl ( ClassTemplateSpecialization specialization )
36
- {
37
- WriteLine ( $ "template class { GetExporting ( ) } { specialization . Visit ( cppTypePrinter ) } ;") ;
38
- return true ;
39
- }
40
-
41
35
public override bool VisitMethodDecl ( Method method )
42
36
{
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 ) ) ) )
44
42
{
45
43
WriteLine ( $ "template { GetExporting ( ) } { method . Visit ( cppTypePrinter ) } ;") ;
46
44
return true ;
@@ -120,7 +118,7 @@ private void WrapConstructor(Method method)
120
118
if ( method . Access == AccessSpecifier . Protected )
121
119
{
122
120
Write ( GetDerivedType ( @namespace , wrapper ) ) ;
123
- Write ( $ " { wrapper } { @namespace } " ) ;
121
+ Write ( wrapper + @namespace ) ;
124
122
Write ( $@ "({ string . Join ( ", " , method . Parameters . Select (
125
123
p => cppTypePrinter . VisitParameter ( p ) ) ) } )" ) ;
126
124
WriteLine ( $ ": { @namespace } ({ @params } ) {{}} }};") ;
@@ -129,7 +127,7 @@ private void WrapConstructor(Method method)
129
127
}
130
128
else
131
129
{
132
- Write ( $ "extern \" C\" ") ;
130
+ Write ( "extern \" C\" " ) ;
133
131
if ( method . Namespace . Access == AccessSpecifier . Protected )
134
132
Write ( $@ "{{ class { wrapper } { method . Namespace . Namespace . Name } : public {
135
133
method . Namespace . Namespace . Visit ( cppTypePrinter ) } " ) ;
@@ -168,22 +166,24 @@ private void WrapDestructor(Method method)
168
166
bool isProtected = method . Access == AccessSpecifier . Protected ;
169
167
string @namespace = method . Namespace . Visit ( cppTypePrinter ) ;
170
168
if ( isProtected )
171
- Write ( GetDerivedType ( @namespace , wrapper ) ) ;
169
+ Write ( $ "class { wrapper } : public { @namespace } {{ public: " ) ;
172
170
else
173
171
Write ( "extern \" C\" { " ) ;
174
172
if ( method . Namespace . Access == AccessSpecifier . Protected )
175
173
Write ( $@ "class { wrapper } { method . Namespace . Namespace . Name } : public {
176
174
method . Namespace . Namespace . Visit ( cppTypePrinter ) } {{ " ) ;
177
175
Write ( $ "void { wrapper } ") ;
178
176
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 } ; }} }};" ) ;
182
182
if ( isProtected )
183
183
{
184
184
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 } ); }} }}" ) ;
187
187
}
188
188
if ( method . Namespace . Access == AccessSpecifier . Protected )
189
189
Write ( "; }" ) ;
@@ -192,14 +192,14 @@ private void WrapDestructor(Method method)
192
192
193
193
private void TakeFunctionAddress ( Function function )
194
194
{
195
+ //function = function.OriginalFunction ?? function;
195
196
string wrapper = GetWrapper ( function ) ;
196
- string @namespace = function . Namespace . Visit ( cppTypePrinter ) ;
197
+ string @namespace = function . OriginalNamespace . Visit ( cppTypePrinter ) ;
197
198
if ( function . Access == AccessSpecifier . Protected )
198
199
{
199
- Write ( GetDerivedType ( @namespace , wrapper ) ) ;
200
+ Write ( $ "class { wrapper } { function . Namespace . Name } : public { @namespace } {{ public: " ) ;
200
201
Write ( "static constexpr " ) ;
201
202
}
202
-
203
203
string returnType = function . OriginalReturnType . Visit ( cppTypePrinter ) ;
204
204
string signature = GetSignature ( function ) ;
205
205
@@ -209,15 +209,15 @@ private void TakeFunctionAddress(Function function)
209
209
210
210
var method = function as Method ;
211
211
if ( function . Namespace . Access == AccessSpecifier . Protected )
212
- Write ( $@ "class { wrapper } { function . Namespace . Namespace . Name } : public {
212
+ Write ( $@ "class { wrapper } { function . Namespace . Name } : public {
213
213
function . Namespace . Namespace . Visit ( cppTypePrinter ) } {{ " ) ;
214
214
Write ( $@ "{ returnType } ({ ( method != null && ! method . IsStatic ?
215
215
( @namespace + "::" ) : string . Empty ) } *{ wrapper } ){ signature } " ) ;
216
216
if ( function . Access == AccessSpecifier . Protected )
217
217
{
218
- Write ( $ " = &{ wrapper } { @namespace } ::{ functionName } ;") ;
218
+ Write ( $ " = &{ wrapper } { function . Namespace . Name } ::{ functionName } ;") ;
219
219
WriteLine ( " };" ) ;
220
- Write ( $ "auto { wrapper } protected = { wrapper } { @namespace } ::{ wrapper } ;") ;
220
+ Write ( $ "auto { wrapper } Protected = { wrapper } { function . Namespace . Name } ::{ wrapper } ;") ;
221
221
}
222
222
else
223
223
{
@@ -251,25 +251,47 @@ private string GetSignature(Function function)
251
251
252
252
private string GetFunctionName ( Function function , string @namespace )
253
253
{
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
+ } ) ;
273
295
}
274
296
275
297
private void WriteRedeclaration ( Function function , string returnType ,
@@ -286,7 +308,7 @@ private void WriteRedeclaration(Function function, string returnType,
286
308
Write ( paramTypes ) ;
287
309
if ( functionType . ExceptionSpecType == ExceptionSpecType . BasicNoexcept )
288
310
Write ( " noexcept" ) ;
289
- WriteLine ( $ ";{ string . Concat ( parentsOpen . Select ( p => " }" ) ) } ") ;
311
+ WriteLine ( $ ";{ string . Concat ( parentsOpen . Select ( _ => " }" ) ) } ") ;
290
312
}
291
313
292
314
private static Stack < string > GenerateNamespace ( Function function )
@@ -301,7 +323,7 @@ private static Stack<string> GenerateNamespace(Function function)
301
323
if ( finalType . TryGetDeclaration ( out declaration ) )
302
324
declarationContextsInSignature . Add ( declaration . Namespace ) ;
303
325
}
304
- var nestedNamespace = declarationContextsInSignature . FirstOrDefault ( d =>
326
+ var nestedNamespace = declarationContextsInSignature . Find ( d =>
305
327
d . Namespace is Namespace && ! ( d . Namespace is TranslationUnit ) ) ;
306
328
var parentsOpen = new Stack < string > ( ) ;
307
329
if ( nestedNamespace != null )
@@ -320,7 +342,8 @@ private static Stack<string> GenerateNamespace(Function function)
320
342
321
343
private CppTypePrinter cppTypePrinter = new CppTypePrinter
322
344
{
323
- ScopeKind = TypePrintScopeKind . Qualified
345
+ ScopeKind = TypePrintScopeKind . Qualified ,
346
+ ResolveTypedefs = true
324
347
} ;
325
348
private int functionCount ;
326
349
}
0 commit comments