xoofx / CppAst.NET

CppAst is a .NET library providing a C/C++ parser for header files powered by Clang/libclang with access to the full AST, comments and macros
BSD 2-Clause "Simplified" License
501 stars 66 forks source link

Provide option for parsing function bodies #95

Open IsaacMarovitz opened 7 months ago

IsaacMarovitz commented 7 months ago

Hi there, I'm trying to use CppAst.NET to parse metal-cpp header files, which are a wrapper of the Objective-C API. The underlying Objective-C functions being called are contained within a macro within the function body.

Screenshot 2024-03-30 at 21 21 35

To generate valid C# code, I need to be able to access the string used to generate the selector inside the function bodies, however currently, function body parsing is disabled.

Could an option be added to enable function body parsing? I'm happy to PR it myself, however, I don't know what other modifications would be required.

xoofx commented 7 months ago

Could an option be added to enable function body parsing? I'm happy to PR it myself, however, I don't know what other modifications would be required.

Adding such an option would require also to parse the full content, handle all the syntax elements, create all the associated AST classes. Unfortunately, I don't want to support this as it would require a significant amount of work - and maintenance. This library is meant for parsing interfaces, signatures of methods and so mostly header files.

IsaacMarovitz commented 7 months ago

Adding such an option would require also to parse the full content, handle all the syntax elements, create all the associated AST classes. Unfortunately, I don't want to support this as it would require a significant amount of work - and maintenance. This library is meant for parsing interfaces, signatures of methods and so mostly header files.

If I'm not mistaken, if function body parsing was enabled, could I get this information from the generic CppToken? I don't need full function parsing; I just need to be able to get the _MTL_PRIVATE_SEL contained within.

xoofx commented 7 months ago

If I'm not mistaken, if function body parsing was enabled, could I get this information from the generic CppToken? I don't need full function parsing; I just need to be able to get the _MTL_PRIVATE_SEL contained within.

I would believe that the visitor would still go through lots of nodes - and generate several warnings or errors along the way, but maybe be that could be fine, you will have to try.

IsaacMarovitz commented 7 months ago

I conducted an inital test with the following code:

[Test]
        public void TestComplex()
        {
            ParseAssert(@"
#include <objc/runtime.h>

#define _NS_PRIVATE_SEL(accessor) (Private::Selector::s_k##accessor)
#define _NS_PRIVATE_DEF_SEL(accessor, symbol) extern SEL s_k##accessor

namespace Private
{
    namespace Selector
    {
        _NS_PRIVATE_DEF_SEL(test,
            ""test"");
    }
}

SEL method()
{
    return _NS_PRIVATE_SEL(test);
}
",
                compilation =>
                {
                    Assert.False(compilation.HasErrors);
                },
                new CppParserOptions
                {
                    SystemIncludeFolders =
                    {
                        "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1",
                        "/Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include"
                    },
                    AdditionalArguments =
                    {
                        "-isysroot",
                        "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk",
                    },
                    TargetCpu = CppTargetCpu.ARM64,
                    TargetSystem = "darwin",
                    TargetVendor = "apple",
                    ParseSystemIncludes = true,
                    ParseMacros = true
                });
        }

It seemed to run without errors, with the only problem being that the method's contents are not available in the AST yet. But I think it might be possible.