Skip to content

Commit

Permalink
Some more minor improvements (#75)
Browse files Browse the repository at this point in the history
* Adding a config switch to ignore any default remappings.

* Resolve the full path of outputLocation so just 'file.cs' works.

* Add a traverse option so you can traverse child includes.

* Fixing up CXUnsavedFile and CXTUResourceUsageEntry to use a `nulong` type.

* Simplifying and improving how the operator opcode is computed.
  • Loading branch information
tannergooding authored Jun 23, 2019
1 parent 2790eb9 commit 6684c9c
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 149 deletions.
17 changes: 15 additions & 2 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,22 @@ public void GenerateBindings(TranslationUnit translationUnit)

foreach (var decl in translationUnitDecl.Decls)
{
if (!decl.IsFromMainFile)
if (_config.TraversalNames.Length == 0)
{
continue;
if (!decl.Location.IsFromMainFile)
{
continue;
}
}
else
{
decl.Location.GetFileLocation(out CXFile file, out _, out _, out _);
var fileName = file.Name.ToString();

if (!_config.TraversalNames.Contains(fileName))
{
continue;
}
}
Visit(decl);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;

namespace ClangSharp
{
Expand All @@ -10,7 +11,7 @@ public sealed class PInvokeGeneratorConfiguration
private readonly Dictionary<string, string> _remappedNames;
private readonly PInvokeGeneratorConfigurationOptions _options;

public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, string outputLocation, PInvokeGeneratorConfigurationOptions options = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, string methodClassName = null, string methodPrefixToStrip = null, IReadOnlyDictionary<string, string> remappedNames = null)
public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, string outputLocation, PInvokeGeneratorConfigurationOptions options = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, string methodClassName = null, string methodPrefixToStrip = null, IReadOnlyDictionary<string, string> remappedNames = null, string[] traversalNames = null)
{
if (excludedNames is null)
{
Expand Down Expand Up @@ -42,22 +43,31 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s
throw new ArgumentNullException(nameof(outputLocation));
}

if (traversalNames is null)
{
traversalNames = Array.Empty<string>();
}

_options = options;

ExcludedNames = excludedNames;
LibraryPath = libraryPath;
MethodClassName = methodClassName;
MethodPrefixToStrip = methodPrefixToStrip;
Namespace = namespaceName;
OutputLocation = outputLocation;
OutputLocation = Path.GetFullPath(outputLocation);
TraversalNames = traversalNames;

_remappedNames = new Dictionary<string, string>()
if (!_options.HasFlag(PInvokeGeneratorConfigurationOptions.NoDefaultRemappings))
{
["intptr_t"] = "IntPtr",
["ptrdiff_t"] = "IntPtr",
["size_t"] = "UIntPtr",
["uintptr_t"] = "UIntPtr",
};
_remappedNames = new Dictionary<string, string>()
{
["intptr_t"] = "IntPtr",
["ptrdiff_t"] = "IntPtr",
["size_t"] = "UIntPtr",
["uintptr_t"] = "UIntPtr",
};
}

if (remappedNames != null)
{
Expand Down Expand Up @@ -87,5 +97,7 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s
public string OutputLocation { get; }

public IReadOnlyDictionary<string, string> RemappedNames => _remappedNames;

public string[] TraversalNames { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ public enum PInvokeGeneratorConfigurationOptions
GenerateMultipleFiles = 0x00000001,

GenerateUnixTypes = 0x00000002,

NoDefaultRemappings = 0x00000004,
}
}
2 changes: 0 additions & 2 deletions sources/ClangSharp/Cursors/Cursor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ private protected Cursor(CXCursor handle, CXCursorKind expectedKind)

public CXCursor Handle { get; }

public bool IsFromMainFile => Location.IsFromMainFile;

public CXCursorKind Kind => Handle.Kind;

public string KindSpelling => Handle.KindSpelling.ToString();
Expand Down
68 changes: 3 additions & 65 deletions sources/ClangSharp/Cursors/Exprs/BinaryOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,75 +28,13 @@ internal BinaryOperator(CXCursor handle, CXCursorKind expectedKind) : base(handl

protected virtual string GetOpcode()
{
var tokens = Handle.TranslationUnit.Tokenize(Extent);
var lhsTokens = Handle.TranslationUnit.Tokenize(LHS.Extent);

var tokens = Handle.TranslationUnit.Tokenize(Extent);
Debug.Assert(tokens.Length >= 3);

int operatorIndex = -1;
int parenDepth = 0;

for (int index = 0; (index < tokens.Length) && (operatorIndex == -1); index++)
{
var token = tokens[index];

if (token.Kind != CXTokenKind.CXToken_Punctuation)
{
continue;
}

var punctuation = tokens[index].GetSpelling(Handle.TranslationUnit).ToString();

switch (punctuation)
{
case "!=":
case "%":
case "&":
case "&&":
case "*":
case "+":
case "-":
case "/":
case "<":
case "<<":
case "<=":
case "=":
case "==":
case ">":
case ">>":
case ">=":
case "^":
case "|":
case "||":
{
if (parenDepth == 0)
{
operatorIndex = index;
}
break;
}

case "(":
{
parenDepth++;
break;
}

case ")":
{
parenDepth--;
break;
}

default:
{
Debug.WriteLine($"Unhandled punctuation kind: {punctuation}.");
Debugger.Break();
break;
}
}
}
int operatorIndex = lhsTokens.Length;

Debug.Assert(operatorIndex != -1);
Debug.Assert(tokens[operatorIndex].Kind == CXTokenKind.CXToken_Punctuation);
return tokens[operatorIndex].GetSpelling(Handle.TranslationUnit).ToString();
}
Expand Down
70 changes: 4 additions & 66 deletions sources/ClangSharp/Cursors/Exprs/UnaryOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,77 +26,15 @@ internal UnaryOperator(CXCursor handle) : base(handle, CXCursorKind.CXCursor_Una

private (string Opcode, bool IsPrefix) GetOpcode()
{
var tokens = Handle.TranslationUnit.Tokenize(Extent);
var subExprTokens = Handle.TranslationUnit.Tokenize(SubExpr.Extent);

var tokens = Handle.TranslationUnit.Tokenize(Extent);
Debug.Assert(tokens.Length >= 2);

int operatorIndex = -1;
int parenDepth = 0;
bool isPrefix = false;

for (int index = 0; (index < tokens.Length) && (operatorIndex == -1); index++)
{
var token = tokens[index];

if (token.Kind != CXTokenKind.CXToken_Punctuation)
{
continue;
}

var punctuation = tokens[index].GetSpelling(Handle.TranslationUnit).ToString();

switch (punctuation)
{
case "!":
case "&":
case "*":
case "+":
case "-":
case "~":
{
if (parenDepth == 0)
{
operatorIndex = index;
isPrefix = true;
}
break;
}
bool isPrefix = tokens[0] != subExprTokens[0];
int operatorIndex = isPrefix ? 0 : subExprTokens.Length;

case "(":
{
parenDepth++;
break;
}

case ")":
{
parenDepth--;
break;
}

case "++":
case "--":
{
if (parenDepth == 0)
{
operatorIndex = index;
isPrefix = ((index + 1) != tokens.Length);
}
break;
}

default:
{
Debug.WriteLine($"Unhandled punctuation kind: {punctuation}.");
Debugger.Break();
break;
}
}
}

Debug.Assert(operatorIndex != -1);
Debug.Assert(tokens[operatorIndex].Kind == CXTokenKind.CXToken_Punctuation);

var opcode = tokens[operatorIndex].GetSpelling(Handle.TranslationUnit).ToString();
return (opcode, isPrefix);
}
Expand Down
30 changes: 29 additions & 1 deletion sources/ClangSharp/Interop.Extensions/CXToken.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
using System;

namespace ClangSharp.Interop
{
public unsafe partial struct CXToken
public unsafe partial struct CXToken : IEquatable<CXToken>
{
public CXTokenKind Kind => clang.getTokenKind(this);

public static bool operator ==(CXToken left, CXToken right)
{
return (left.int_data[0] == right.int_data[0]) &&
(left.int_data[1] == right.int_data[1]) &&
(left.int_data[2] == right.int_data[2]) &&
(left.int_data[3] == right.int_data[3]) &&
(left.ptr_data == right.ptr_data);
}

public static bool operator !=(CXToken left, CXToken right)
{
return (left.int_data[0] != right.int_data[0]) ||
(left.int_data[1] != right.int_data[1]) ||
(left.int_data[2] != right.int_data[2]) ||
(left.int_data[3] != right.int_data[3]) ||
(left.ptr_data != right.ptr_data);
}

public override bool Equals(object obj) => (obj is CXSourceRange other) && Equals(other);

public bool Equals(CXToken other) => this == other;

public CXSourceRange GetExtent(CXTranslationUnit translationUnit) => clang.getTokenExtent(translationUnit, this);

public override int GetHashCode() => HashCode.Combine(int_data[0], int_data[1], int_data[2], int_data[3], (IntPtr)ptr_data);

public CXSourceLocation GetLocation(CXTranslationUnit translationUnit) => clang.getTokenLocation(translationUnit, this);

public CXString GetSpelling(CXTranslationUnit translationUnit) => clang.getTokenSpelling(translationUnit, this);

public override string ToString() => "";
}
}
10 changes: 8 additions & 2 deletions sources/ClangSharp/Interop.Extensions/CXUnsavedFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
using System.Runtime.InteropServices;
using System.Text;

#if Windows_NT
using nulong = System.UInt32;
#else
using nulong = System.UIntPtr;
#endif

namespace ClangSharp.Interop
{
public unsafe partial struct CXUnsavedFile : IDisposable
Expand Down Expand Up @@ -43,7 +49,7 @@ public static CXUnsavedFile Create(string filename, string contents)
{
Filename = (sbyte*)pFilename,
Contents = (sbyte*)pContents,
Length = (uint)contentsLength
Length = (nulong)contentsLength
};
}

Expand All @@ -59,7 +65,7 @@ public void Dispose()
{
Marshal.FreeHGlobal((IntPtr)Contents);
Contents = null;
Length = 0;
Length = (nulong)0;
}
}

Expand Down
9 changes: 8 additions & 1 deletion sources/ClangSharp/Interop/CXTUResourceUsageEntry.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#if Windows_NT
using nulong = System.UInt32;
#else
using System;
using nulong = System.UIntPtr;
#endif

namespace ClangSharp.Interop
{
public partial struct CXTUResourceUsageEntry
Expand All @@ -6,6 +13,6 @@ public partial struct CXTUResourceUsageEntry
public CXTUResourceUsageKind kind;

[NativeTypeName("unsigned long")]
public uint amount;
public nulong amount;
}
}
9 changes: 8 additions & 1 deletion sources/ClangSharp/Interop/CXUnsavedFile.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#if Windows_NT
using nulong = System.UInt32;
#else
using System;
using nulong = System.UIntPtr;
#endif

namespace ClangSharp.Interop
{
public unsafe partial struct CXUnsavedFile
Expand All @@ -9,6 +16,6 @@ public unsafe partial struct CXUnsavedFile
public sbyte* Contents;

[NativeTypeName("unsigned long")]
public uint Length;
public nulong Length;
}
}
Loading

0 comments on commit 6684c9c

Please sign in to comment.