From 69bf84168403558c0f1f5d51dd5041fa0b834b2c Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 4 Aug 2021 10:28:19 -0700 Subject: [PATCH] Fix additional low hanging bugs (#257) * Refactoring how the calling convention is looked up for a given cursor or type * Ensure that non-char based string literals don't assert with debug clang * Ensure that managled names are correctly represented in DllImport * Ensure creating a span over a pointer works on netstandard * Don't include the underscore prefix on the entry point name for simple C exports --- .../Extensions/CXModuleMapDescriptor.cs | 12 + .../Extensions/CXTranslationUnit.cs | 13 ++ .../Extensions/CXVirtualFileOverlay.cs | 12 + .../PInvokeGenerator.VisitDecl.cs | 32 +-- .../PInvokeGenerator.cs | 211 +++++++++++++----- .../PInvokeGeneratorConfiguration.cs | 23 +- sources/libClangSharp/ClangSharp.cpp | 2 +- .../Base/FunctionDeclarationDllImportTest.cs | 3 + .../Base/FunctionPointerDeclarationTest.cs | 3 + .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 65 ++++-- .../FunctionPointerDeclarationTest.cs | 28 +++ .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 64 ++++-- .../FunctionPointerDeclarationTest.cs | 28 +++ .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 64 ++++-- .../FunctionPointerDeclarationTest.cs | 22 ++ .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 64 ++++-- .../FunctionPointerDeclarationTest.cs | 22 ++ .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 60 +++-- .../FunctionPointerDeclarationTest.cs | 27 +++ .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 60 +++-- .../FunctionPointerDeclarationTest.cs | 27 +++ .../XmlLatestUnix/CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 60 +++-- .../FunctionPointerDeclarationTest.cs | 24 ++ .../CXXMethodDeclarationTest.cs | 2 +- .../FunctionDeclarationDllImportTest.cs | 60 +++-- .../FunctionPointerDeclarationTest.cs | 24 ++ 33 files changed, 808 insertions(+), 218 deletions(-) diff --git a/sources/ClangSharp.Interop/Extensions/CXModuleMapDescriptor.cs b/sources/ClangSharp.Interop/Extensions/CXModuleMapDescriptor.cs index b6b2f55c..554b06c2 100644 --- a/sources/ClangSharp.Interop/Extensions/CXModuleMapDescriptor.cs +++ b/sources/ClangSharp.Interop/Extensions/CXModuleMapDescriptor.cs @@ -54,7 +54,19 @@ public Span WriteToBuffer(uint options, out CXErrorCode errorCode) { sbyte* pBuffer; uint size; errorCode = clang.ModuleMapDescriptor_writeToBuffer(this, options, &pBuffer, &size); + +#if NETSTANDARD + var result = new byte[checked((int)size)]; + + fixed (byte* pResult = result) + { + Buffer.MemoryCopy(pBuffer, pResult, size, size); + } + + return result; +#else return new Span(pBuffer, (int)size); +#endif } } } diff --git a/sources/ClangSharp.Interop/Extensions/CXTranslationUnit.cs b/sources/ClangSharp.Interop/Extensions/CXTranslationUnit.cs index 1965ce3f..eb2171ed 100644 --- a/sources/ClangSharp.Interop/Extensions/CXTranslationUnit.cs +++ b/sources/ClangSharp.Interop/Extensions/CXTranslationUnit.cs @@ -222,7 +222,20 @@ public Span Tokenize(CXSourceRange sourceRange) { CXToken* pTokens; uint numTokens; clang.tokenize(this, sourceRange, &pTokens, &numTokens); + +#if NETSTANDARD + var result = new CXToken[checked((int)numTokens)]; + + fixed (CXToken* pResult = result) + { + var size = sizeof(CXToken) * numTokens; + Buffer.MemoryCopy(pTokens, pResult, size, size); + } + + return result; +#else return new Span(pTokens, (int)numTokens); +#endif } public override string ToString() => Spelling.ToString(); diff --git a/sources/ClangSharp.Interop/Extensions/CXVirtualFileOverlay.cs b/sources/ClangSharp.Interop/Extensions/CXVirtualFileOverlay.cs index f8599f13..39990bcd 100644 --- a/sources/ClangSharp.Interop/Extensions/CXVirtualFileOverlay.cs +++ b/sources/ClangSharp.Interop/Extensions/CXVirtualFileOverlay.cs @@ -51,7 +51,19 @@ public Span WriteToBuffer(uint options, out CXErrorCode errorCode) { sbyte* pBuffer; uint size; errorCode = clang.VirtualFileOverlay_writeToBuffer(this, options, &pBuffer, &size); + +#if NETSTANDARD + var result = new byte[checked((int)size)]; + + fixed (byte* pResult = result) + { + Buffer.MemoryCopy(pBuffer, pResult, size, size); + } + + return result; +#else return new Span(pBuffer, (int)size); +#endif } } } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index f02c4ce6..b2e138d0 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -452,28 +452,16 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) } var type = functionDecl.Type; - var callConv = CXCallingConv.CXCallingConv_Invalid; + var callingConventionName = GetCallingConvention(functionDecl, cxxRecordDecl, type); - if (type is AttributedType attributedType) - { - type = attributedType.ModifiedType; - callConv = attributedType.Handle.FunctionTypeCallingConv; - } + var isDllImport = body is null && !isVirtual; + var entryPoint = isDllImport ? functionDecl.Handle.Mangling.CString : null; - if (type is FunctionType functionType) + if (entryPoint == $"_{functionDecl.Name}") { - if (callConv == CXCallingConv.CXCallingConv_Invalid) - { - callConv = functionType.CallConv; - } + entryPoint = functionDecl.Name; } - var callingConventionName = GetCallingConvention(functionDecl, callConv, name); - var entryPoint = !isVirtual && body is null - ? (cxxMethodDecl is null) ? GetCursorName(functionDecl) : cxxMethodDecl.Handle.Mangling.CString - : null; - var isDllImport = body is null && !isVirtual; - var needsReturnFixup = isVirtual && NeedsReturnFixup(cxxMethodDecl); var desc = new FunctionOrDelegateDesc<(string Name, PInvokeGenerator This)> @@ -2435,14 +2423,10 @@ void ForFunctionProtoType(TypedefDecl typedefDecl, FunctionProtoType functionPro var name = GetRemappedCursorName(typedefDecl); var escapedName = EscapeName(name); - var callingConventionName = GetCallingConvention(typedefDecl, - (parentType is AttributedType) - ? parentType.Handle.FunctionTypeCallingConv - : functionProtoType.CallConv, name); + var callingConventionName = GetCallingConvention(typedefDecl, context: null, typedefDecl.TypeForDecl); - var returnType = functionProtoType.ReturnType; - var returnTypeName = - GetRemappedTypeName(typedefDecl, context: null, returnType, out var nativeTypeName); + var returnType = functionProtoType.ReturnType; + var returnTypeName = GetRemappedTypeName(typedefDecl, context: null, returnType, out var nativeTypeName); StartUsingOutputBuilder(name); { diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index 47c779fd..d682cac8 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; using System.Text; using ClangSharp.Abstractions; @@ -780,52 +781,146 @@ private Type[] GetBitfieldCount(RecordDecl recordDecl) return types.ToArray(); } - private CallingConvention GetCallingConvention(Cursor cursor, CXCallingConv callingConvention, string remappedName) + private CallingConvention GetCallingConvention(Cursor cursor, Cursor context, Type type) { - if (_config.WithCallConvs.TryGetValue(remappedName, out var callConv) || _config.WithCallConvs.TryGetValue("*", out callConv)) + if (cursor is NamedDecl namedDecl) { - if (Enum.TryParse(callConv, true, out CallingConvention callConvEnum)) + var remappedName = GetRemappedCursorName(namedDecl); + + if (_config.WithCallConvs.TryGetValue(remappedName, out var callConv) || _config.WithCallConvs.TryGetValue("*", out callConv)) { - return callConvEnum; + if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) + { + return remappedCallingConvention; + } + AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported manually-specified calling convention: '{callConv}'. Determining convention from cursor.", cursor); } - - AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported manually-specified calling convention: '{callConv}'. Determining convention from cursor.", cursor); } - switch (callingConvention) + var wasRemapped = false; + return GetCallingConvention(cursor, context, type, ref wasRemapped); + } + + private CallingConvention GetCallingConvention(Cursor cursor, Cursor context, Type type, ref bool wasRemapped) + { + var remappedName = GetRemappedTypeName(cursor, context, type, out _, skipUsing: true); + + if (_config.WithCallConvs.TryGetValue(remappedName, out var callConv) || _config.WithCallConvs.TryGetValue("*", out callConv)) { - case CXCallingConv.CXCallingConv_C: + if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) { - return CallingConvention.Cdecl; + wasRemapped = true; + return remappedCallingConvention; } + AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported manually-specified calling convention: '{callConv}'. Determining convention from cursor.", cursor); + } - case CXCallingConv.CXCallingConv_X86StdCall: - { - return CallingConvention.StdCall; - } + if (type is AttributedType attributedType) + { + var callingConvention = GetCallingConvention(cursor, context, attributedType.ModifiedType, ref wasRemapped); - case CXCallingConv.CXCallingConv_X86FastCall: + if (wasRemapped) { - return CallingConvention.FastCall; + return callingConvention; } - case CXCallingConv.CXCallingConv_X86ThisCall: + switch (attributedType.AttrKind) { - return CallingConvention.ThisCall; - } + case CX_AttrKind.CX_AttrKind_MSABI: + case CX_AttrKind.CX_AttrKind_SysVABI: + { + return CallingConvention.Winapi; + } - case CXCallingConv.CXCallingConv_Win64: - { - return CallingConvention.Winapi; + case CX_AttrKind.CX_AttrKind_CDecl: + { + return CallingConvention.Cdecl; + } + + case CX_AttrKind.CX_AttrKind_FastCall: + { + return CallingConvention.FastCall; + } + + case CX_AttrKind.CX_AttrKind_StdCall: + { + return CallingConvention.StdCall; + } + + case CX_AttrKind.CX_AttrKind_ThisCall: + { + return CallingConvention.ThisCall; + } + + case CX_AttrKind.CX_AttrKind_AArch64VectorPcs: + case CX_AttrKind.CX_AttrKind_Pcs: + case CX_AttrKind.CX_AttrKind_PreserveAll: + case CX_AttrKind.CX_AttrKind_PreserveMost: + case CX_AttrKind.CX_AttrKind_RegCall: + case CX_AttrKind.CX_AttrKind_VectorCall: + { + AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported calling convention: '{attributedType.AttrKind}'.", cursor); + return callingConvention; + } + + default: + { + return callingConvention; + } } + } + else if (type is FunctionType functionType) + { + var callingConv = functionType.CallConv; - default: + switch (callingConv) { - const CallingConvention Name = CallingConvention.Winapi; - AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported calling convention: '{callingConvention}'. Falling back to '{Name}'.", cursor); - return Name; + case CXCallingConv.CXCallingConv_C: + { + return CallingConvention.Cdecl; + } + + case CXCallingConv.CXCallingConv_X86StdCall: + { + return CallingConvention.StdCall; + } + + case CXCallingConv.CXCallingConv_X86FastCall: + { + return CallingConvention.FastCall; + } + + case CXCallingConv.CXCallingConv_X86ThisCall: + { + return CallingConvention.ThisCall; + } + + case CXCallingConv.CXCallingConv_Win64: + { + return CallingConvention.Winapi; + } + + default: + { + const CallingConvention Name = CallingConvention.Winapi; + AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported calling convention: '{callingConv}'. Falling back to '{Name}'.", cursor); + return Name; + } } } + else if (type is PointerType pointerType) + { + return GetCallingConvention(cursor, context, pointerType.PointeeType, ref wasRemapped); + } + else if (type is TypedefType typedefType) + { + return GetCallingConvention(cursor, context, typedefType.Decl.UnderlyingType, ref wasRemapped); + } + else + { + AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported type: '{type.TypeClass}'. Falling back to canonical type.", cursor); + return GetCallingConvention(cursor, context, type.CanonicalType, ref wasRemapped); + } } private string GetCursorName(NamedDecl namedDecl) @@ -1152,18 +1247,18 @@ private string GetRemappedCursorName(NamedDecl namedDecl) return remappedName; } - private string GetRemappedName(string name, Cursor cursor, bool tryRemapOperatorName, out bool wasRemapped) + private string GetRemappedName(string name, Cursor cursor, bool tryRemapOperatorName, out bool wasRemapped, bool skipUsing = false) { if (_config.RemappedNames.TryGetValue(name, out var remappedName)) { wasRemapped = true; - return AddUsingDirectiveIfNeeded(remappedName); + return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); } if (name.StartsWith("const ") && _config.RemappedNames.TryGetValue(name[6..], out remappedName)) { wasRemapped = true; - return AddUsingDirectiveIfNeeded(remappedName); + return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); } remappedName = name; @@ -1171,27 +1266,27 @@ private string GetRemappedName(string name, Cursor cursor, bool tryRemapOperator if ((cursor is FunctionDecl functionDecl) && tryRemapOperatorName && TryRemapOperatorName(ref remappedName, functionDecl)) { wasRemapped = true; - return AddUsingDirectiveIfNeeded(remappedName); + return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); } wasRemapped = false; - return AddUsingDirectiveIfNeeded(remappedName); + return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); - string AddUsingDirectiveIfNeeded(string remappedName) + static string AddUsingDirectiveIfNeeded(IOutputBuilder outputBuilder, string remappedName, bool skipUsing) { - if (remappedName.Equals("Guid") || remappedName.Equals("IntPtr") || remappedName.Equals("UIntPtr")) + if (!skipUsing && (remappedName.Equals("Guid") || remappedName.Equals("IntPtr") || remappedName.Equals("UIntPtr"))) { - _outputBuilder?.EmitSystemSupport(); + outputBuilder?.EmitSystemSupport(); } return remappedName; } } - private string GetRemappedTypeName(Cursor cursor, Cursor context, Type type, out string nativeTypeName) + private string GetRemappedTypeName(Cursor cursor, Cursor context, Type type, out string nativeTypeName, bool skipUsing = false) { var name = GetTypeName(cursor, context, type, out nativeTypeName); - var remappedName = GetRemappedName(name, cursor, tryRemapOperatorName: false, out var wasRemapped); + var remappedName = GetRemappedName(name, cursor, tryRemapOperatorName: false, out var wasRemapped, skipUsing); if (!wasRemapped) { @@ -1300,13 +1395,18 @@ private static string GetSourceRangeContents(CXTranslationUnit translationUnit, } private string GetTypeName(Cursor cursor, Cursor context, Type type, out string nativeTypeName) + { + return GetTypeName(cursor, context, type, type, out nativeTypeName); + } + + private string GetTypeName(Cursor cursor, Cursor context, Type rootType, Type type, out string nativeTypeName) { var name = type.AsString.Replace('\\', '/'); nativeTypeName = name; if (type is ArrayType arrayType) { - name = GetTypeName(cursor, context, arrayType.ElementType, out _); + name = GetTypeName(cursor, context, rootType, arrayType.ElementType, out _); if (cursor is FunctionDecl or ParmVarDecl) { @@ -1316,7 +1416,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string } else if (type is AttributedType attributedType) { - name = GetTypeName(cursor, context, attributedType.ModifiedType, out _); + name = GetTypeName(cursor, context, rootType, attributedType.ModifiedType, out _); } else if (type is BuiltinType) { @@ -1450,13 +1550,13 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string } else if (type is DeducedType deducedType) { - name = GetTypeName(cursor, context, deducedType.CanonicalType, out _); + name = GetTypeName(cursor, context, rootType, deducedType.CanonicalType, out _); } else if (type is DependentNameType dependentNameType) { if (dependentNameType.IsSugared) { - name = GetTypeName(cursor, context, dependentNameType.Desugar, out _); + name = GetTypeName(cursor, context, rootType, dependentNameType.Desugar, out _); } else { @@ -1465,31 +1565,31 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string } else if (type is ElaboratedType elaboratedType) { - name = GetTypeName(cursor, context, elaboratedType.NamedType, out _); + name = GetTypeName(cursor, context, rootType, elaboratedType.NamedType, out _); } else if (type is FunctionType functionType) { - name = GetTypeNameForPointeeType(cursor, context, functionType, out _); + name = GetTypeNameForPointeeType(cursor, context, rootType, functionType, out _); } else if (type is InjectedClassNameType injectedClassNameType) { - name = GetTypeName(cursor, context, injectedClassNameType.InjectedTST, out _); + name = GetTypeName(cursor, context, rootType, injectedClassNameType.InjectedTST, out _); } else if (type is PackExpansionType packExpansionType) { - name = GetTypeName(cursor, context, packExpansionType.Pattern, out _); + name = GetTypeName(cursor, context, rootType, packExpansionType.Pattern, out _); } else if (type is PointerType pointerType) { - name = GetTypeNameForPointeeType(cursor, context, pointerType.PointeeType, out _); + name = GetTypeNameForPointeeType(cursor, context, rootType, pointerType.PointeeType, out _); } else if (type is ReferenceType referenceType) { - name = GetTypeNameForPointeeType(cursor, context, referenceType.PointeeType, out _); + name = GetTypeNameForPointeeType(cursor, context, rootType, referenceType.PointeeType, out _); } else if (type is SubstTemplateTypeParmType substTemplateTypeParmType) { - name = GetTypeName(cursor, context, substTemplateTypeParmType.ReplacementType, out _); + name = GetTypeName(cursor, context, rootType, substTemplateTypeParmType.ReplacementType, out _); } else if (type is TagType tagType) { @@ -1499,7 +1599,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string } else if (tagType.Handle.IsConstQualified) { - name = GetTypeName(cursor, context, tagType.Decl.TypeForDecl, out _); + name = GetTypeName(cursor, context, rootType, tagType.Decl.TypeForDecl, out _); } else { @@ -1598,7 +1698,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string { if (templateTypeParmType.IsSugared) { - name = GetTypeName(cursor, context, templateTypeParmType.Desugar, out _); + name = GetTypeName(cursor, context, rootType, templateTypeParmType.Desugar, out _); } else { @@ -1612,7 +1712,7 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string // platform size, based on whatever parameters were passed into clang. var remappedName = GetRemappedName(name, cursor, tryRemapOperatorName: false, out var wasRemapped); - name = wasRemapped ? remappedName : GetTypeName(cursor, context, typedefType.Decl.UnderlyingType, out _); + name = wasRemapped ? remappedName : GetTypeName(cursor, context, rootType, typedefType.Decl.UnderlyingType, out _); } else { @@ -1629,25 +1729,26 @@ private string GetTypeName(Cursor cursor, Cursor context, Type type, out string return name; } - private string GetTypeNameForPointeeType(Cursor cursor, Cursor context, Type pointeeType, out string nativePointeeTypeName) + private string GetTypeNameForPointeeType(Cursor cursor, Cursor context, Type rootType, Type pointeeType, out string nativePointeeTypeName) { var name = pointeeType.AsString; nativePointeeTypeName = name; if (pointeeType is AttributedType attributedType) { - name = GetTypeNameForPointeeType(cursor, context, attributedType.ModifiedType, out var nativeModifiedTypeName); + name = GetTypeNameForPointeeType(cursor, context, rootType, attributedType.ModifiedType, out var nativeModifiedTypeName); } else if (pointeeType is ElaboratedType elaboratedType) { - name = GetTypeNameForPointeeType(cursor, context, elaboratedType.NamedType, out var nativeNamedTypeName); + name = GetTypeNameForPointeeType(cursor, context, rootType, elaboratedType.NamedType, out var nativeNamedTypeName); } else if (pointeeType is FunctionType functionType) { if (!_config.ExcludeFnptrCodegen && (functionType is FunctionProtoType functionProtoType)) { - var remappedName = GetRemappedName(name, cursor, tryRemapOperatorName: false, out var wasRemapped); - var callConv = GetCallingConvention(cursor, functionType.CallConv, remappedName); + _config.ExcludeFnptrCodegen = true; + var callConv = GetCallingConvention(cursor, context, rootType); + _config.ExcludeFnptrCodegen = false; var needsReturnFixup = false; var returnTypeName = GetRemappedTypeName(cursor, context: null, functionType.ReturnType, out _); @@ -1756,7 +1857,7 @@ private string GetTypeNameForPointeeType(Cursor cursor, Cursor context, Type poi } else { - name = GetTypeNameForPointeeType(cursor, context, typedefType.Decl.UnderlyingType, out var nativeUnderlyingTypeName); + name = GetTypeNameForPointeeType(cursor, context, rootType, typedefType.Decl.UnderlyingType, out var nativeUnderlyingTypeName); } } else diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs index 92871c73..8527d86c 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs @@ -17,7 +17,8 @@ public sealed class PInvokeGeneratorConfiguration private readonly Dictionary _withLibraryPaths; private readonly Dictionary _withTypes; private readonly Dictionary> _withUsings; - private readonly PInvokeGeneratorConfigurationOptions _options; + + private PInvokeGeneratorConfigurationOptions _options; public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, string outputLocation, string testOutputLocation, PInvokeGeneratorOutputMode outputMode = PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions options = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, string headerFile = null, string methodClassName = null, string methodPrefixToStrip = null, IReadOnlyDictionary remappedNames = null, string[] traversalNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null) { @@ -147,7 +148,25 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s public bool GenerateMacroBindings => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateMacroBindings); - public bool ExcludeFnptrCodegen => GenerateCompatibleCode || _options.HasFlag(PInvokeGeneratorConfigurationOptions.ExcludeFnptrCodegen); + public bool ExcludeFnptrCodegen + { + get + { + return GenerateCompatibleCode || _options.HasFlag(PInvokeGeneratorConfigurationOptions.ExcludeFnptrCodegen); + } + + set + { + if (value) + { + _options |= PInvokeGeneratorConfigurationOptions.ExcludeFnptrCodegen; + } + else + { + _options &= ~PInvokeGeneratorConfigurationOptions.ExcludeFnptrCodegen; + } + } + } public bool ExcludeNIntCodegen => GenerateCompatibleCode || _options.HasFlag(PInvokeGeneratorConfigurationOptions.ExcludeNIntCodegen); diff --git a/sources/libClangSharp/ClangSharp.cpp b/sources/libClangSharp/ClangSharp.cpp index b6332d21..4d1f05ec 100644 --- a/sources/libClangSharp/ClangSharp.cpp +++ b/sources/libClangSharp/ClangSharp.cpp @@ -3921,7 +3921,7 @@ CXString clangsharp_Cursor_getStringLiteralValue(CXCursor C) { const Stmt* S = getCursorStmt(C); if (const StringLiteral* SL = dyn_cast(S)) { - return createDup(SL->getString()); + return createDup(SL->getBytes()); } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs index 10314dc5..4d586330 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs @@ -16,6 +16,9 @@ public abstract class FunctionDeclarationDllImportTest : PInvokeGeneratorTest [Fact] public abstract Task FunctionPointerParameterTest(); + [Fact] + public abstract Task NamespaceTest(); + [Theory] [InlineData("int", false, "int", "")] [InlineData("bool", true, "byte", "")] diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionPointerDeclarationTest.cs index 7ac0d785..28f46f20 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionPointerDeclarationTest.cs @@ -10,6 +10,9 @@ public abstract class FunctionPointerDeclarationTest : PInvokeGeneratorTest [Fact] public abstract Task BasicTest(); + [Fact] + public abstract Task CallconvTest(); + [Fact] public abstract Task PointerlessTypedefTest(); } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs index eae3a7eb..0b132184 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/CXXMethodDeclarationTest.cs @@ -764,7 +764,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs index df324aa6..f3e5d343 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. +using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +11,7 @@ public sealed class CSharpCompatibleUnix_FunctionDeclarationDllImportTest : Func { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -28,7 +30,7 @@ public static partial class Methods public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -47,7 +49,7 @@ public static unsafe partial class Methods public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @"using System; using System.Runtime.InteropServices; @@ -65,11 +67,40 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + public static partial class Methods + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern void MyFunction(); + }} +}} +"; + + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -115,7 +146,7 @@ public partial struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -134,7 +165,7 @@ public static partial class Methods public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -157,7 +188,7 @@ public static partial class Methods public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -180,7 +211,7 @@ public static partial class Methods public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -199,7 +230,7 @@ public static partial class Methods public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -218,7 +249,7 @@ public static unsafe partial class Methods public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -243,7 +274,7 @@ public static partial class Methods public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -269,7 +300,7 @@ public static partial class Methods public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -296,7 +327,7 @@ public static partial class Methods public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -322,7 +353,7 @@ public static partial class Methods public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -348,7 +379,7 @@ public static partial class Methods public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @"using System.Runtime.InteropServices; @@ -357,8 +388,8 @@ namespace ClangSharp.Test public static partial class Methods { [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [SourceLocation(""ClangUnsavedFile.h"", 1, 6)] - public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 23)] float value); + [SourceLocation(""ClangUnsavedFile.h"", 1, 17)] + public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 34)] float value); } } "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionPointerDeclarationTest.cs index 3295a043..b8e2c699 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionPointerDeclarationTest.cs @@ -34,6 +34,34 @@ public partial struct MyStruct return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @"using System; +using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{ + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate void Callback(); + + public partial struct MyStruct + { + [NativeTypeName(""Callback"")] + public IntPtr _callback; + } +} +"; + + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs index 794ac2b0..2ad697d6 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/CXXMethodDeclarationTest.cs @@ -764,7 +764,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs index e0d1a0dd..e61de758 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class CSharpCompatibleWindows_FunctionDeclarationDllImportTest : F { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -28,7 +29,7 @@ public static partial class Methods public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -47,7 +48,7 @@ public static unsafe partial class Methods public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @"using System; using System.Runtime.InteropServices; @@ -65,11 +66,40 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + public static partial class Methods + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern void MyFunction(); + }} +}} +"; + + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -115,7 +145,7 @@ public partial struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -134,7 +164,7 @@ public static partial class Methods public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -157,7 +187,7 @@ public static partial class Methods public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -180,7 +210,7 @@ public static partial class Methods public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -199,7 +229,7 @@ public static partial class Methods public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -218,7 +248,7 @@ public static unsafe partial class Methods public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -243,7 +273,7 @@ public static partial class Methods public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -269,7 +299,7 @@ public static partial class Methods public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -296,7 +326,7 @@ public static partial class Methods public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -322,7 +352,7 @@ public static partial class Methods public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -348,7 +378,7 @@ public static partial class Methods public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @"using System.Runtime.InteropServices; @@ -357,8 +387,8 @@ namespace ClangSharp.Test public static partial class Methods { [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [SourceLocation(""ClangUnsavedFile.h"", 1, 6)] - public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 23)] float value); + [SourceLocation(""ClangUnsavedFile.h"", 1, 17)] + public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 34)] float value); } } "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionPointerDeclarationTest.cs index 6cce30cd..a2bebdba 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionPointerDeclarationTest.cs @@ -34,6 +34,34 @@ public partial struct MyStruct return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @"using System; +using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{ + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate void Callback(); + + public partial struct MyStruct + { + [NativeTypeName(""Callback"")] + public IntPtr _callback; + } +} +"; + + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs index 8768eadb..e8bedf5f 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/CXXMethodDeclarationTest.cs @@ -726,7 +726,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs index 5b6a1492..0f12f756 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class CSharpLatestUnix_FunctionDeclarationDllImportTest : Function { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -28,7 +29,7 @@ public static partial class Methods public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -47,7 +48,7 @@ public static unsafe partial class Methods public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -64,11 +65,40 @@ public static unsafe partial class Methods return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + public static partial class Methods + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern void MyFunction(); + }} +}} +"; + + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -114,7 +144,7 @@ public partial struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -133,7 +163,7 @@ public static partial class Methods public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -156,7 +186,7 @@ public static partial class Methods public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -179,7 +209,7 @@ public static partial class Methods public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -198,7 +228,7 @@ public static partial class Methods public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -217,7 +247,7 @@ public static unsafe partial class Methods public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -242,7 +272,7 @@ public static partial class Methods public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -268,7 +298,7 @@ public static partial class Methods public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -295,7 +325,7 @@ public static partial class Methods public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -321,7 +351,7 @@ public static partial class Methods public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -347,7 +377,7 @@ public static partial class Methods public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @"using System.Runtime.InteropServices; @@ -356,8 +386,8 @@ namespace ClangSharp.Test public static partial class Methods { [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [SourceLocation(""ClangUnsavedFile.h"", 1, 6)] - public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 23)] float value); + [SourceLocation(""ClangUnsavedFile.h"", 1, 17)] + public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 34)] float value); } } "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs index 3e0d3297..e1b05b19 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionPointerDeclarationTest.cs @@ -28,6 +28,28 @@ public unsafe partial struct MyStruct return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @"namespace ClangSharp.Test +{ + public unsafe partial struct MyStruct + { + [NativeTypeName(""Callback"")] + public delegate* unmanaged[Stdcall] _callback; + } +} +"; + + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs index 06e589fd..7fe60dca 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/CXXMethodDeclarationTest.cs @@ -726,7 +726,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs index c660a74c..45ecfdc9 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class CSharpLatestWindows_FunctionDeclarationDllImportTest : Funct { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -28,7 +29,7 @@ public static partial class Methods public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -47,7 +48,7 @@ public static unsafe partial class Methods public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -64,11 +65,40 @@ public static unsafe partial class Methods return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@"using System.Runtime.InteropServices; + +namespace ClangSharp.Test +{{ + public static partial class Methods + {{ + [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, EntryPoint = ""{entryPoint}"", ExactSpelling = true)] + public static extern void MyFunction(); + }} +}} +"; + + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -114,7 +144,7 @@ public partial struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -133,7 +163,7 @@ public static partial class Methods public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -156,7 +186,7 @@ public static partial class Methods public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -179,7 +209,7 @@ public static partial class Methods public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -198,7 +228,7 @@ public static partial class Methods public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -217,7 +247,7 @@ public static unsafe partial class Methods public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -242,7 +272,7 @@ public static partial class Methods public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -268,7 +298,7 @@ public static partial class Methods public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -295,7 +325,7 @@ public static partial class Methods public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -321,7 +351,7 @@ public static partial class Methods public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @"using System.Runtime.InteropServices; @@ -347,7 +377,7 @@ public static partial class Methods public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @"using System.Runtime.InteropServices; @@ -356,8 +386,8 @@ namespace ClangSharp.Test public static partial class Methods { [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [SourceLocation(""ClangUnsavedFile.h"", 1, 6)] - public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 23)] float value); + [SourceLocation(""ClangUnsavedFile.h"", 1, 17)] + public static extern void MyFunction([SourceLocation(""ClangUnsavedFile.h"", 1, 34)] float value); } } "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs index 054dd96f..2f5475e7 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionPointerDeclarationTest.cs @@ -28,6 +28,28 @@ public unsafe partial struct MyStruct return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @"namespace ClangSharp.Test +{ + public unsafe partial struct MyStruct + { + [NativeTypeName(""Callback"")] + public delegate* unmanaged[Stdcall] _callback; + } +} +"; + + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs index 8a94b296..3d418ff8 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs @@ -915,7 +915,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs index a8af6a6d..6bd20877 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class XmlCompatibleUnix_FunctionDeclarationDllImportTest : Functio { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -28,7 +29,7 @@ public override Task BasicTest() public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @" @@ -50,7 +51,7 @@ public override Task ArrayParameterTest() public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @" @@ -70,11 +71,40 @@ public override Task FunctionPointerParameterTest() return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@" + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@" @@ -123,7 +153,7 @@ struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -142,7 +172,7 @@ public override Task NoLibraryPathTest() public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -165,7 +195,7 @@ public override Task WithLibraryPathTest() public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -188,7 +218,7 @@ public override Task WithLibraryPathStarTest() public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -213,7 +243,7 @@ public override Task OptionalParameterTest(string nativeType, string nativeInit, public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -238,7 +268,7 @@ public override Task OptionalParameterUnsafeTest(string nativeType, string nativ public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -269,7 +299,7 @@ public override Task WithCallConvTest() public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -301,7 +331,7 @@ public override Task WithCallConvStarTest() public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -334,7 +364,7 @@ public override Task WithCallConvStarOverrideTest() public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -366,7 +396,7 @@ public override Task WithSetLastErrorTest() public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -398,7 +428,7 @@ public override Task WithSetLastErrorStarTest() public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs index 6763bedf..802c7960 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs @@ -33,6 +33,33 @@ struct MyStruct { return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @" + + + + void + + + + IntPtr + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs index 863e6461..87e7d714 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs @@ -915,7 +915,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs index 582c9ef8..0f93fd64 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class XmlCompatibleWindows_FunctionDeclarationDllImportTest : Func { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -28,7 +29,7 @@ public override Task BasicTest() public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @" @@ -50,7 +51,7 @@ public override Task ArrayParameterTest() public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @" @@ -70,11 +71,40 @@ public override Task FunctionPointerParameterTest() return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@" + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@" @@ -123,7 +153,7 @@ struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -142,7 +172,7 @@ public override Task NoLibraryPathTest() public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -165,7 +195,7 @@ public override Task WithLibraryPathTest() public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -188,7 +218,7 @@ public override Task WithLibraryPathStarTest() public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -213,7 +243,7 @@ public override Task OptionalParameterTest(string nativeType, string nativeInit, public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -238,7 +268,7 @@ public override Task OptionalParameterUnsafeTest(string nativeType, string nativ public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -269,7 +299,7 @@ public override Task WithCallConvTest() public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -301,7 +331,7 @@ public override Task WithCallConvStarTest() public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -334,7 +364,7 @@ public override Task WithCallConvStarOverrideTest() public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -366,7 +396,7 @@ public override Task WithSetLastErrorTest() public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -398,7 +428,7 @@ public override Task WithSetLastErrorStarTest() public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs index 3eafe565..126dc0d3 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs @@ -33,6 +33,33 @@ struct MyStruct { return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @" + + + + void + + + + IntPtr + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs index e9392f33..afc2bc0a 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs @@ -843,7 +843,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs index b03564bf..274ab2a1 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class XmlLatestUnix_FunctionDeclarationDllImportTest : FunctionDec { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -28,7 +29,7 @@ public override Task BasicTest() public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @" @@ -50,7 +51,7 @@ public override Task ArrayParameterTest() public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @" @@ -70,11 +71,40 @@ public override Task FunctionPointerParameterTest() return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@" + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@" @@ -123,7 +153,7 @@ struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -142,7 +172,7 @@ public override Task NoLibraryPathTest() public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -165,7 +195,7 @@ public override Task WithLibraryPathTest() public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -188,7 +218,7 @@ public override Task WithLibraryPathStarTest() public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -213,7 +243,7 @@ public override Task OptionalParameterTest(string nativeType, string nativeInit, public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -238,7 +268,7 @@ public override Task OptionalParameterUnsafeTest(string nativeType, string nativ public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -269,7 +299,7 @@ public override Task WithCallConvTest() public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -301,7 +331,7 @@ public override Task WithCallConvStarTest() public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -334,7 +364,7 @@ public override Task WithCallConvStarOverrideTest() public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -366,7 +396,7 @@ public override Task WithSetLastErrorTest() public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -398,7 +428,7 @@ public override Task WithSetLastErrorStarTest() public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs index d290e2db..1ad3ceec 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs @@ -30,6 +30,30 @@ struct MyStruct { return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @" + + + + + delegate* unmanaged[Stdcall]<void> + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs index 02969902..a3d695aa 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs @@ -843,7 +843,7 @@ public override Task UnsafeDoesNotImpactDllImportTest() } }; -void MyFunction();"; +extern ""C"" void MyFunction();"; var expectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs index e9cf9005..6411cea8 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; namespace ClangSharp.UnitTests @@ -9,7 +10,7 @@ public sealed class XmlLatestWindows_FunctionDeclarationDllImportTest : Function { public override Task BasicTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -28,7 +29,7 @@ public override Task BasicTest() public override Task ArrayParameterTest() { - var inputContents = @"void MyFunction(const float color[4]);"; + var inputContents = @"extern ""C"" void MyFunction(const float color[4]);"; var expectedOutputContents = @" @@ -50,7 +51,7 @@ public override Task ArrayParameterTest() public override Task FunctionPointerParameterTest() { - var inputContents = @"void MyFunction(void (*callback)());"; + var inputContents = @"extern ""C"" void MyFunction(void (*callback)());"; var expectedOutputContents = @" @@ -70,11 +71,40 @@ public override Task FunctionPointerParameterTest() return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task NamespaceTest() + { + var inputContents = @"namespace MyNamespace +{ + void MyFunction(); +}"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN11MyNamespace10MyFunctionEv" : "_ZN11MyNamespace10MyFunctionEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + entryPoint = "?MyFunction@MyNamespace@@YAXXZ"; + } + + var expectedOutputContents = $@" + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction(MyTemplate<{nativeType}> myStruct);"; +extern ""C"" void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@" @@ -123,7 +153,7 @@ struct MyStruct public override Task NoLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -142,7 +172,7 @@ public override Task NoLibraryPathTest() public override Task WithLibraryPathTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -165,7 +195,7 @@ public override Task WithLibraryPathTest() public override Task WithLibraryPathStarTest() { - var inputContents = @"void MyFunction();"; + var inputContents = @"extern ""C"" void MyFunction();"; var expectedOutputContents = @" @@ -188,7 +218,7 @@ public override Task WithLibraryPathStarTest() public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -213,7 +243,7 @@ public override Task OptionalParameterTest(string nativeType, string nativeInit, public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + var inputContents = $@"extern ""C"" void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@" @@ -238,7 +268,7 @@ public override Task OptionalParameterUnsafeTest(string nativeType, string nativ public override Task WithCallConvTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -269,7 +299,7 @@ public override Task WithCallConvTest() public override Task WithCallConvStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -301,7 +331,7 @@ public override Task WithCallConvStarTest() public override Task WithCallConvStarOverrideTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -334,7 +364,7 @@ public override Task WithCallConvStarOverrideTest() public override Task WithSetLastErrorTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -366,7 +396,7 @@ public override Task WithSetLastErrorTest() public override Task WithSetLastErrorStarTest() { - var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + var inputContents = @"extern ""C"" void MyFunction1(int value); extern ""C"" void MyFunction2(int value);"; var expectedOutputContents = @" @@ -398,7 +428,7 @@ public override Task WithSetLastErrorStarTest() public override Task SourceLocationTest() { - const string InputContents = @"void MyFunction(float value);"; + const string InputContents = @"extern ""C"" void MyFunction(float value);"; const string ExpectedOutputContents = @" diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs index 91a60e24..eb60032b 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs @@ -30,6 +30,30 @@ struct MyStruct { return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } + public override Task CallconvTest() + { + var inputContents = @"typedef void (*Callback)() __attribute__((stdcall)); + +struct MyStruct { + Callback _callback; +}; +"; + + var expectedOutputContents = @" + + + + + delegate* unmanaged[Stdcall]<void> + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task PointerlessTypedefTest() { var inputContents = @"typedef void (Callback)();