Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a helper library, libClangSharp, for exposing functionality not in libClang #94

Merged
merged 4 commits into from
Nov 18, 2019

Conversation

tannergooding
Copy link
Member

This exposes a new helper library named libClangSharp. This library exposes functionality not yet in libClang for use in ClangSharp.

@tannergooding
Copy link
Member Author

A NuGet package hasn't been published for libClangSharp yet as I'd like to get some feedback first.

Ideally, all functionality being exposed here would also be ported back to libClang. At least one of the APIs (for getting the binary operator opcode: https://reviews.llvm.org/D10833) is actively in PR against libClang as well; however, it has been a WIP for 4 years now and I'm not confident it will get in any time soon (the same would go for other tweaks/changes).

private const string libraryPath = "libClangSharp";

[DllImport(libraryPath, EntryPoint = "clangsharp_Cursor_getBinaryOpcode", CallingConvention = CallingConvention.Cdecl)]
public static extern CX_BinaryOperatorKind Cursor_getBinaryOpcode(CXCursor C);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An API for explicitly getting the opcode of a binary operator. This avoids the need to try and manually process tokens.

public static extern CXString Cursor_getBinaryOpcodeStr(CX_BinaryOperatorKind Op);

[DllImport(libraryPath, EntryPoint = "clangsharp_Cursor_getUnaryOpcode", CallingConvention = CallingConvention.Cdecl)]
public static extern CX_UnaryOperatorKind Cursor_getUnaryOpcode(CXCursor C);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An API for explicitly getting the opcode of a unary operator. This avoids the need to try and manually process tokens.

public static extern CXString Cursor_getUnaryOpcodeStr(CX_UnaryOperatorKind Op);

[DllImport(libraryPath, EntryPoint = "clangsharp_getCursorExtent", CallingConvention = CallingConvention.Cdecl)]
public static extern CXSourceRange getCursorExtent(CXCursor param0);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clang_getCursorExtent API keeps the start location "as-is". However, it transforms the end location to its expansion location. This means that if the actual extent is in a macro, you get macro start location, expansion end location.

That transformation is what was blocking the token processing logic from working in some cases (namely when macros were involved).

This API just gives you the raw extent (macro start location, macro end location) and the consumer, if desired, can manually transform each location to the expansion location or any other location as needed. This allows token processing to work as needed and allows the consumer to customize as necessary.

public static extern CXSourceRange getNullRange();

[DllImport(libraryPath, EntryPoint = "clangsharp_getRange", CallingConvention = CallingConvention.Cdecl)]
public static extern CXSourceRange getRange(CXSourceLocation begin, CXSourceLocation end);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same scenario as in getCursorExtent.

public static extern CXSourceRange getRange(CXSourceLocation begin, CXSourceLocation end);

[DllImport(libraryPath, EntryPoint = "clangsharp_getSpellingLocation", CallingConvention = CallingConvention.Cdecl)]
public static extern void getSpellingLocation(CXSourceLocation location, [NativeTypeName("CXFile *")] void** file, [NativeTypeName("unsigned int *")] uint* line, [NativeTypeName("unsigned int *")] uint* column, [NativeTypeName("unsigned int *")] uint* offset);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The libClang API was actually doing getFileLocation. The API, when added, was correctly getting the spelling location; but then at some point later there were CI failures and someone changed it to be functionally getFileLocation with a FIXME comment.

This version of the API correctly gets the spelling location, which allows users to get the line/column/offset as it exists in the raw header files. This is useful for when processing macros.


[DllImport(libraryPath, EntryPoint = "clangsharp_isAttribute", CallingConvention = CallingConvention.Cdecl)]
[return: NativeTypeName("unsigned int")]
public static extern uint isAttribute([NativeTypeName("enum CXCursorKind")] CXCursorKind param0);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other APIs here, that I've not commented on, are the exact same as the libClang versions. They ended up being redeclared to avoid static linking errors (I could probably remove the exports, however).

@tannergooding
Copy link
Member Author

CC. @mjsabby for thoughts/opinions on this approach.

public static extern CXString Cursor_getBinaryOpcodeSpelling(CX_BinaryOperatorKind Op);

[DllImport(libraryPath, EntryPoint = "clangsharp_Cursor_getDeclKind", CallingConvention = CallingConvention.Cdecl)]
public static extern CX_DeclKind Cursor_getDeclKind(CXCursor C);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDeclKind, getAttrKind, and getStmtKind lets you determine the type of unexposed cursors.

@tannergooding
Copy link
Member Author

Added a commit which exposes all of the attr, decl, stmt, and expr kinds.

@tannergooding tannergooding force-pushed the libclangsharp branch 6 times, most recently from 00a55a4 to e98db34 Compare November 16, 2019 23:24
@tannergooding tannergooding merged commit ff9e62f into dotnet:master Nov 18, 2019
@tannergooding tannergooding deleted the libclangsharp branch November 18, 2019 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant