@@ -46,12 +46,38 @@ public override bool VisitClassDecl(Class @class)
4646 return base . VisitClassDecl ( @class ) ;
4747 }
4848
49+ public override bool VisitClassTemplateSpecializationDecl ( ClassTemplateSpecialization specialization )
50+ {
51+ if ( ! base . VisitClassTemplateSpecializationDecl ( specialization ) ||
52+ ! specialization . IsGenerated || ! specialization . TemplatedDecl . TemplatedDecl . IsGenerated )
53+ return false ;
54+
55+ foreach ( TemplateArgument arg in specialization . Arguments . Where (
56+ a => a . Kind == TemplateArgument . ArgumentKind . Type ) )
57+ {
58+ arg . Type = CheckForDelegate ( arg . Type , specialization ) ;
59+ }
60+
61+ return true ;
62+ }
63+
4964 public override bool VisitMethodDecl ( Method method )
5065 {
5166 if ( ! base . VisitMethodDecl ( method ) || ! method . IsVirtual || method . Ignore )
5267 return false ;
5368
54- method . FunctionType = CheckForDelegate ( method . FunctionType , method ) ;
69+ var functionType = new FunctionType
70+ {
71+ CallingConvention = method . CallingConvention ,
72+ IsDependent = method . IsDependent ,
73+ ReturnType = method . ReturnType
74+ } ;
75+
76+ functionType . Parameters . AddRange (
77+ method . GatherInternalParams ( Context . ParserOptions . IsItaniumLikeAbi , true ) ) ;
78+
79+ method . FunctionType = CheckForDelegate ( new QualifiedType ( functionType ) ,
80+ method . Namespace , @private : true ) ;
5581
5682 return true ;
5783 }
@@ -61,7 +87,8 @@ public override bool VisitFunctionDecl(Function function)
6187 if ( ! base . VisitFunctionDecl ( function ) || function . Ignore )
6288 return false ;
6389
64- function . ReturnType = CheckForDelegate ( function . ReturnType , function ) ;
90+ function . ReturnType = CheckForDelegate ( function . ReturnType ,
91+ function . Namespace ) ;
6592 return true ;
6693 }
6794
@@ -71,7 +98,8 @@ public override bool VisitParameterDecl(Parameter parameter)
7198 parameter . Namespace . Ignore )
7299 return false ;
73100
74- parameter . QualifiedType = CheckForDelegate ( parameter . QualifiedType , parameter ) ;
101+ parameter . QualifiedType = CheckForDelegate ( parameter . QualifiedType ,
102+ parameter . Namespace ) ;
75103
76104 return true ;
77105 }
@@ -81,7 +109,8 @@ public override bool VisitProperty(Property property)
81109 if ( ! base . VisitProperty ( property ) )
82110 return false ;
83111
84- property . QualifiedType = CheckForDelegate ( property . QualifiedType , property ) ;
112+ property . QualifiedType = CheckForDelegate ( property . QualifiedType ,
113+ property . Namespace ) ;
85114
86115 return true ;
87116 }
@@ -91,12 +120,14 @@ public override bool VisitFieldDecl(Field field)
91120 if ( ! base . VisitFieldDecl ( field ) )
92121 return false ;
93122
94- field . QualifiedType = CheckForDelegate ( field . QualifiedType , field ) ;
123+ field . QualifiedType = CheckForDelegate ( field . QualifiedType ,
124+ field . Namespace ) ;
95125
96126 return true ;
97127 }
98128
99- private QualifiedType CheckForDelegate ( QualifiedType type , ITypedDecl decl )
129+ private QualifiedType CheckForDelegate ( QualifiedType type ,
130+ DeclarationContext declarationContext , bool @private = false )
100131 {
101132 if ( type . Type is TypedefType )
102133 return type ;
@@ -109,22 +140,21 @@ private QualifiedType CheckForDelegate(QualifiedType type, ITypedDecl decl)
109140 if ( pointee is TypedefType )
110141 return type ;
111142
112- var functionType = pointee . Desugar ( ) as FunctionType ;
113- if ( functionType == null )
143+ desugared = pointee . Desugar ( ) ;
144+ FunctionType functionType = desugared as FunctionType ;
145+ if ( functionType == null && ! desugared . IsPointerTo ( out functionType ) )
114146 return type ;
115147
116- TypedefDecl @delegate = GetDelegate ( type , decl ) ;
148+ TypedefDecl @delegate = GetDelegate ( functionType , declarationContext , @private ) ;
117149 return new QualifiedType ( new TypedefType { Declaration = @delegate } ) ;
118150 }
119151
120- private TypedefDecl GetDelegate ( QualifiedType type , ITypedDecl typedDecl )
152+ private TypedefDecl GetDelegate ( FunctionType functionType ,
153+ DeclarationContext declarationContext , bool @private = false )
121154 {
122- FunctionType newFunctionType = GetNewFunctionType ( typedDecl , type ) ;
123-
124- var delegateName = GetDelegateName ( newFunctionType ) ;
125- var access = typedDecl is Method ? AccessSpecifier . Private : AccessSpecifier . Public ;
126- var decl = ( Declaration ) typedDecl ;
127- Module module = decl . TranslationUnit . Module ;
155+ var delegateName = GetDelegateName ( functionType ) ;
156+ var access = @private ? AccessSpecifier . Private : AccessSpecifier . Public ;
157+ Module module = declarationContext . TranslationUnit . Module ;
128158 var existingDelegate = delegates . Find ( t => Match ( t , delegateName , module ) ) ;
129159 if ( existingDelegate != null )
130160 {
@@ -135,18 +165,18 @@ private TypedefDecl GetDelegate(QualifiedType type, ITypedDecl typedDecl)
135165
136166 // Check if there is an existing delegate with a different calling convention
137167 if ( ( ( FunctionType ) existingDelegate . Type . GetPointee ( ) ) . CallingConvention ==
138- newFunctionType . CallingConvention )
168+ functionType . CallingConvention )
139169 return existingDelegate ;
140170
141171 // Add a new delegate with the calling convention appended to its name
142- delegateName += '_' + newFunctionType . CallingConvention . ToString ( ) ;
172+ delegateName += '_' + functionType . CallingConvention . ToString ( ) ;
143173 existingDelegate = delegates . Find ( t => Match ( t , delegateName , module ) ) ;
144174 if ( existingDelegate != null )
145175 return existingDelegate ;
146176 }
147177
148- var namespaceDelegates = GetDeclContextForDelegates ( decl . Namespace ) ;
149- var delegateType = new QualifiedType ( new PointerType ( new QualifiedType ( newFunctionType ) ) ) ;
178+ var namespaceDelegates = GetDeclContextForDelegates ( declarationContext ) ;
179+ var delegateType = new QualifiedType ( new PointerType ( new QualifiedType ( functionType ) ) ) ;
150180 existingDelegate = new TypedefDecl
151181 {
152182 Access = access ,
@@ -160,30 +190,6 @@ private TypedefDecl GetDelegate(QualifiedType type, ITypedDecl typedDecl)
160190 return existingDelegate ;
161191 }
162192
163- private FunctionType GetNewFunctionType ( ITypedDecl decl , QualifiedType type )
164- {
165- var functionType = new FunctionType ( ) ;
166- var method = decl as Method ;
167- if ( method != null && method . FunctionType == type )
168- {
169- functionType . Parameters . AddRange (
170- method . GatherInternalParams ( Context . ParserOptions . IsItaniumLikeAbi , true ) ) ;
171- functionType . CallingConvention = method . CallingConvention ;
172- functionType . IsDependent = method . IsDependent ;
173- functionType . ReturnType = method . ReturnType ;
174- }
175- else
176- {
177- var funcTypeParam = ( FunctionType ) decl . Type . Desugar ( ) . GetFinalPointee ( ) . Desugar ( ) ;
178- functionType = new FunctionType ( funcTypeParam ) ;
179- }
180-
181- for ( int i = 0 ; i < functionType . Parameters . Count ; i ++ )
182- functionType . Parameters [ i ] . Name = $ "_{ i } ";
183-
184- return functionType ;
185- }
186-
187193 private static bool Match ( TypedefDecl t , string delegateName , Module module )
188194 {
189195 return t . Name == delegateName &&
0 commit comments