@@ -115,6 +115,24 @@ private void VisitCallExpr(CallExpr callExpr)
115115                } 
116116            } 
117117
118+             var  isUnusedValue  =  false ; 
119+ 
120+             if  ( callExpr . Type . CanonicalType . Kind  !=  CXTypeKind . CXType_Void ) 
121+             { 
122+                 isUnusedValue  =  IsPrevContextStmt < CompoundStmt > ( out  _ ,  out  _ ) 
123+                              ||  IsPrevContextStmt < IfStmt > ( out  _ ,  out  _ ) ; 
124+ 
125+                 if  ( ( calleeDecl  is  FunctionDecl  functionDecl )  &&  ( functionDecl . Name  is  "memcpy"  or "memset" ) ) 
126+                 { 
127+                     isUnusedValue  =  false ; 
128+                 } 
129+             } 
130+ 
131+             if  ( isUnusedValue ) 
132+             { 
133+                 outputBuilder . Write ( "_ = " ) ; 
134+             } 
135+ 
118136            if  ( calleeDecl  is  null ) 
119137            { 
120138                Visit ( callExpr . Callee ) ; 
@@ -139,22 +157,64 @@ private void VisitCallExpr(CallExpr callExpr)
139157
140158                    case  "memset" : 
141159                    { 
160+                         NamedDecl  namedDecl  =  null ; 
161+ 
162+                         if  ( callExpr . NumArgs  ==  3 ) 
163+                         { 
164+                             if  ( IsStmtAsWritten < IntegerLiteral > ( callExpr . Args [ 1 ] ,  out  var  integerLiteralExpr ,  removeParens :  true )  &&  ( integerLiteralExpr . Value  ==  0 )  && 
165+                                 IsStmtAsWritten < UnaryExprOrTypeTraitExpr > ( callExpr . Args [ 2 ] ,  out  var  unaryExprOrTypeTraitExpr ,  removeParens :  true )  &&  ( unaryExprOrTypeTraitExpr . Kind  ==  CX_UnaryExprOrTypeTrait . CX_UETT_SizeOf ) ) 
166+                             { 
167+                                 var  typeOfArgument  =  unaryExprOrTypeTraitExpr . TypeOfArgument . CanonicalType ; 
168+                                 var  expr  =  callExpr . Args [ 0 ] ; 
169+ 
170+                                 if  ( IsStmtAsWritten < UnaryOperator > ( expr ,  out  var  unaryOperator ,  removeParens :  true )  &&  ( unaryOperator . Opcode  ==  CX_UnaryOperatorKind . CX_UO_AddrOf ) ) 
171+                                 { 
172+                                     expr  =  unaryOperator . SubExpr ; 
173+                                 } 
174+ 
175+                                 if  ( IsStmtAsWritten < DeclRefExpr > ( expr ,  out  var  declRefExpr ,  removeParens :  true )  &&  ( typeOfArgument  ==  declRefExpr . Type . CanonicalType ) ) 
176+                                 { 
177+                                     namedDecl  =  declRefExpr . Decl ; 
178+                                 } 
179+                                 else  if  ( IsStmtAsWritten < MemberExpr > ( expr ,  out  var  memberExpr ,  removeParens :  true )  &&  ( typeOfArgument  ==  memberExpr . Type . CanonicalType ) ) 
180+                                 { 
181+                                     namedDecl  =  memberExpr . MemberDecl ; 
182+                                 } 
183+                             } 
184+ 
185+                             if  ( namedDecl  is  not null ) 
186+                             { 
187+                                 outputBuilder . Write ( GetRemappedCursorName ( namedDecl ) ) ; 
188+                                 outputBuilder . Write ( " = default" ) ; 
189+                                 break ; 
190+                             } 
191+                         } 
192+ 
142193                        outputBuilder . AddUsingDirective ( "System.Runtime.CompilerServices" ) ; 
143194                        outputBuilder . Write ( "Unsafe.InitBlockUnaligned" ) ; 
144195                        VisitArgs ( callExpr ) ; 
145196                        break ; 
146197                    } 
147198
148-                     default : 
199+                     case   "wcslen" : 
149200                    { 
150-                         if  ( ( functionDecl . ReturnType . CanonicalType . Kind   !=   CXTypeKind . CXType_Void )   &&   IsPrevContextStmt < CompoundStmt > ( out   _ ,   out   _ ) ) 
201+                         if  ( _config . GenerateCompatibleCode ) 
151202                        { 
152-                             outputBuilder . Write ( "_ = " ) ; 
203+                             goto   default ; 
153204                        } 
154205
155-                         Visit ( callExpr . Callee ) ; 
206+                         outputBuilder . AddUsingDirective ( "System.Runtime.InteropServices" ) ; 
207+                         outputBuilder . Write ( "MemoryMarshal.CreateReadOnlySpanFromNullTerminated" ) ; 
208+ 
156209                        VisitArgs ( callExpr ) ; 
210+                         outputBuilder . Write ( ".Length" ) ; 
211+                         break ; 
212+                     } 
157213
214+                     default : 
215+                     { 
216+                         Visit ( callExpr . Callee ) ; 
217+                         VisitArgs ( callExpr ) ; 
158218                        break ; 
159219                    } 
160220                } 
@@ -176,19 +236,53 @@ private void VisitCallExpr(CallExpr callExpr)
176236
177237            void  VisitArgs ( CallExpr  callExpr ) 
178238            { 
239+                 var  callExprType  =  ( callExpr . Callee  is  MemberExpr  memberExpr ) 
240+                                  ?  memberExpr . MemberDecl . Type . CanonicalType 
241+                                  :  callExpr . Callee . Type . CanonicalType ; 
242+ 
243+                 if  ( callExprType  is  PointerType  pointerType ) 
244+                 { 
245+                     callExprType  =  pointerType . PointeeType . CanonicalType ; 
246+                 } 
247+ 
179248                outputBuilder . Write ( '(' ) ; 
180249
181250                var  args  =  callExpr . Args ; 
182251                var  needsComma  =  false ; 
183252
184253                for  ( var  i  =  0 ;  i  <  args . Count ;  i ++ ) 
185254                { 
186-                     if  ( needsComma ) 
255+                     var  arg  =  args [ i ] ; 
256+ 
257+                     if  ( needsComma  &&  ( arg  is  not CXXDefaultArgExpr ) ) 
187258                    { 
188259                        outputBuilder . Write ( ", " ) ; 
189260                    } 
190261
191-                     var  arg  =  args [ i ] ; 
262+                     if  ( callExprType  is  FunctionProtoType  functionProtoType ) 
263+                     { 
264+                         var  paramType  =  functionProtoType . ParamTypes [ i ] . CanonicalType ; 
265+ 
266+                         if  ( paramType  is  ReferenceType ) 
267+                         { 
268+                             if  ( IsStmtAsWritten < UnaryOperator > ( arg ,  out  var  unaryOperator ,  removeParens :  true )  &&  ( unaryOperator . Opcode  ==  CX_UnaryOperatorKind . CX_UO_Deref ) ) 
269+                             { 
270+                                 arg  =  unaryOperator . SubExpr ; 
271+                             } 
272+                             else  if  ( IsStmtAsWritten < DeclRefExpr > ( arg ,  out  var  declRefExpr ,  removeParens :  true ) ) 
273+                             { 
274+                                 if  ( declRefExpr . Decl . Type . CanonicalType  is  not ReferenceType  and not PointerType ) 
275+                                 { 
276+                                     outputBuilder . Write ( '&' ) ; 
277+                                 } 
278+                             } 
279+                             else  if  ( arg . Type . CanonicalType  is  not ReferenceType  and not PointerType ) 
280+                             { 
281+                                 outputBuilder . Write ( '&' ) ; 
282+                             } 
283+                         } 
284+                     } 
285+ 
192286                    Visit ( arg ) ; 
193287
194288                    if  ( arg  is  not CXXDefaultArgExpr ) 
@@ -651,14 +745,14 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr)
651745                        { 
652746                            var  className  =  GetClass ( enumName ) ; 
653747
654-                             if  ( outputBuilder . Name  !=  className ) 
748+                             if  ( ( outputBuilder . Name  !=  className )   &&   ( namedDecl . Parent   is  not  TagDecl ) ) 
655749                            { 
656-                                 outputBuilder . AddUsingDirective ( $ "static { GetNamespace ( enumName ) } .{ className } ") ; 
750+                                 outputBuilder . AddUsingDirective ( $ "static { GetNamespace ( enumName ,   namedDecl ) } .{ className } ") ; 
657751                            } 
658752                        } 
659753                        else 
660754                        { 
661-                             outputBuilder . AddUsingDirective ( $ "static { GetNamespace ( enumName ) } .{ enumName } ") ; 
755+                             outputBuilder . AddUsingDirective ( $ "static { GetNamespace ( enumName ,   namedDecl ) } .{ enumName } ") ; 
662756                        } 
663757                    } 
664758                    else 
@@ -1003,12 +1097,33 @@ void ForEnumConstantDecl(ImplicitCastExpr implicitCastExpr, EnumConstantDecl enu
10031097                if  ( IsPrevContextStmt < BinaryOperator > ( out  var  binaryOperator ,  out  _ )  &&  ( ( binaryOperator . Opcode  ==  CX_BinaryOperatorKind . CX_BO_EQ )  ||  ( binaryOperator . Opcode  ==  CX_BinaryOperatorKind . CX_BO_NE ) ) ) 
10041098                { 
10051099                    Visit ( subExpr ) ; 
1100+                     subExpr  =  null ; 
1101+                 } 
1102+                 else  if  ( IsPrevContextStmt < CaseStmt > ( out  _ ,  out  _ ) ) 
1103+                 { 
1104+                     var  previousContext  =  _context . Last . Previous ; 
1105+ 
1106+                     do 
1107+                     { 
1108+                         previousContext  =  previousContext . Previous ; 
1109+                     } 
1110+                     while  ( previousContext . Value . Cursor  is  ParenExpr  or ImplicitCastExpr  or CaseStmt  or CompoundStmt ) ; 
1111+ 
1112+                     var  value  =  previousContext . Value ; 
1113+ 
1114+                     if  ( ( value . Cursor  is  SwitchStmt  switchStmt )  &&  ( switchStmt . Cond . IgnoreImplicit . Type . CanonicalType  is  EnumType ) ) 
1115+                     { 
1116+                         Visit ( subExpr ) ; 
1117+                         subExpr  =  null ; 
1118+                     } 
10061119                } 
10071120                else  if  ( IsPrevContextDecl < EnumConstantDecl > ( out  _ ,  out  _ ) ) 
10081121                { 
10091122                    Visit ( subExpr ) ; 
1123+                     subExpr  =  null ; 
10101124                } 
1011-                 else 
1125+ 
1126+                 if  ( subExpr  is  not null ) 
10121127                { 
10131128                    var  type  =  implicitCastExpr . Type ; 
10141129
@@ -1272,7 +1387,7 @@ void ForType(InitListExpr initListExpr, Type type)
12721387                } 
12731388                else 
12741389                { 
1275-                     AddDiagnostic ( DiagnosticLevel . Error ,  $ "Unsupported init list expression type: '{ type . KindSpelling } '. Generated bindings may be incomplete.",  initListExpr ) ; 
1390+                     AddDiagnostic ( DiagnosticLevel . Error ,  $ "Unsupported init list expression type: '{ type . TypeClassSpelling } '. Generated bindings may be incomplete.",  initListExpr ) ; 
12761391                } 
12771392            } 
12781393
@@ -1335,6 +1450,14 @@ void HandleInitStmt(Stmt init)
13351450                            break ; 
13361451                        } 
13371452
1453+                         case  CXEvalResultKind . CXEval_StrLiteral : 
1454+                         { 
1455+                             outputBuilder . Write ( '"' ) ; 
1456+                             outputBuilder . Write ( evaluation . AsStr ) ; 
1457+                             outputBuilder . Write ( '"' ) ; 
1458+                             break ; 
1459+                         } 
1460+ 
13381461                        default : 
13391462                        { 
13401463                            AddDiagnostic ( DiagnosticLevel . Error ,  $ "Unsupported evaluation kind: '{ evaluation . Kind } '. Generated bindings may be incomplete.",  init ) ; 
@@ -1605,18 +1728,26 @@ private void VisitMemberExpr(MemberExpr memberExpr)
16051728                { 
16061729                    if  ( ( _cxxRecordDeclContext  is  not null )  &&  ( _cxxRecordDeclContext  !=  cxxMethodDecl . Parent )  &&  HasField ( cxxMethodDecl . Parent ) ) 
16071730                    { 
1608-                         var  cxxBaseSpecifier  =  _cxxRecordDeclContext . Bases . Where ( ( baseSpecifier )  =>  baseSpecifier . Referenced  ==  cxxMethodDecl . Parent ) . Single ( ) ; 
1609-                         baseFieldName  =  GetAnonymousName ( cxxBaseSpecifier ,  "Base" ) ; 
1610-                         baseFieldName  =  GetRemappedName ( baseFieldName ,  cxxBaseSpecifier ,  tryRemapOperatorName :  true ,  out  var  wasRemapped ,  skipUsing :  true ) ; 
1731+                         var  cxxBaseSpecifier  =  _cxxRecordDeclContext . Bases . Where ( ( baseSpecifier )  =>  baseSpecifier . Referenced  ==  cxxMethodDecl . Parent ) . SingleOrDefault ( ) ; 
1732+ 
1733+                         if  ( cxxBaseSpecifier  is  not null ) 
1734+                         { 
1735+                             baseFieldName  =  GetAnonymousName ( cxxBaseSpecifier ,  "Base" ) ; 
1736+                             baseFieldName  =  GetRemappedName ( baseFieldName ,  cxxBaseSpecifier ,  tryRemapOperatorName :  true ,  out  var  wasRemapped ,  skipUsing :  true ) ; 
1737+                         } 
16111738                    } 
16121739                } 
16131740                else  if  ( memberExpr . MemberDecl  is  FieldDecl  fieldDecl ) 
16141741                { 
16151742                    if  ( ( _cxxRecordDeclContext  is  not null )  &&  ( _cxxRecordDeclContext  !=  fieldDecl . Parent ) ) 
16161743                    { 
1617-                         var  cxxBaseSpecifier  =  _cxxRecordDeclContext . Bases . Where ( ( baseSpecifier )  =>  baseSpecifier . Referenced  ==  fieldDecl . Parent ) . Single ( ) ; 
1618-                         baseFieldName  =  GetAnonymousName ( cxxBaseSpecifier ,  "Base" ) ; 
1619-                         baseFieldName  =  GetRemappedName ( baseFieldName ,  cxxBaseSpecifier ,  tryRemapOperatorName :  true ,  out  var  wasRemapped ,  skipUsing :  true ) ; 
1744+                         var  cxxBaseSpecifier  =  _cxxRecordDeclContext . Bases . Where ( ( baseSpecifier )  =>  baseSpecifier . Referenced  ==  fieldDecl . Parent ) . SingleOrDefault ( ) ; 
1745+ 
1746+                         if  ( cxxBaseSpecifier  is  not null ) 
1747+                         { 
1748+                             baseFieldName  =  GetAnonymousName ( cxxBaseSpecifier ,  "Base" ) ; 
1749+                             baseFieldName  =  GetRemappedName ( baseFieldName ,  cxxBaseSpecifier ,  tryRemapOperatorName :  true ,  out  var  wasRemapped ,  skipUsing :  true ) ; 
1750+                         } 
16201751                    } 
16211752                } 
16221753            } 
@@ -1710,6 +1841,15 @@ private void VisitReturnStmt(ReturnStmt returnStmt)
17101841                if  ( returnStmt . RetValue  !=  null ) 
17111842                { 
17121843                    outputBuilder . Write ( ' ' ) ; 
1844+ 
1845+                     if  ( functionDecl . ReturnType . CanonicalType  is  not ReferenceType  and not PointerType ) 
1846+                     { 
1847+                         if  ( returnStmt . RetValue . Type . CanonicalType  is  ReferenceType ) 
1848+                         { 
1849+                             outputBuilder . Write ( '*' ) ; 
1850+                         } 
1851+                     } 
1852+ 
17131853                    Visit ( returnStmt . RetValue ) ; 
17141854                } 
17151855            } 
@@ -2609,8 +2749,21 @@ private void VisitUnaryOperator(UnaryOperator unaryOperator)
26092749                    } 
26102750                    else  if  ( canonicalType  is  PointerType  or ReferenceType ) 
26112751                    { 
2752+                         var  needsParens  =  ! IsPrevContextStmt < ParenExpr > ( out  _ ,  out  _ ,  preserveParen :  true )  && 
2753+                                           ! IsPrevContextStmt < IfStmt > ( out  _ ,  out  _ ,  preserveParen :  true ) ; 
2754+ 
2755+                         if  ( needsParens ) 
2756+                         { 
2757+                             outputBuilder . Write ( '(' ) ; 
2758+                         } 
2759+ 
26122760                        Visit ( subExpr ) ; 
26132761                        outputBuilder . Write ( " == null" ) ; 
2762+ 
2763+                         if  ( needsParens ) 
2764+                         { 
2765+                             outputBuilder . Write ( ')' ) ; 
2766+                         } 
26142767                    } 
26152768                    else 
26162769                    { 
0 commit comments