Esempio n. 1
0
        public void ParseAssert(string text, Action <CppCompilation> assertCompilation, CppParserOptions options = null, bool asFile = true)
        {
            if (assertCompilation == null)
            {
                throw new ArgumentNullException(nameof(assertCompilation));
            }

            options = options ?? new CppParserOptions();
            var currentDirectory = Environment.CurrentDirectory;
            var headerFilename   = $"{TestContext.CurrentContext.Test.FullName}-{TestContext.CurrentContext.Test.ID}.h";
            var headerFile       = Path.Combine(currentDirectory, headerFilename);

            // Parse in memory
            var compilation = CppParser.Parse(text, options, headerFilename);

            foreach (var diagnosticsMessage in compilation.Diagnostics.Messages)
            {
                Console.WriteLine(diagnosticsMessage);
            }

            assertCompilation(compilation);

            if (asFile)
            {
                // Parse single file from disk
                File.WriteAllText(headerFile, text);
                compilation = CppParser.ParseFile(headerFile, options);
                assertCompilation(compilation);
            }
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            var flavors = new string[] { "Dawn", "Browser" };

            foreach (var flavor in flavors)
            {
                var headerFile = Path.Combine(AppContext.BaseDirectory, "Headers", flavor, "webgpu.h");
                var options    = new CppParserOptions
                {
                    ParseMacros = true,
                    Defines     =
                    {
                        "WGPU_SHARED_LIBRARY",
                        "_WIN32",
                        "WGPU_SKIP_PROCS"
                    }
                };

                var compilation = CppParser.ParseFile(headerFile, options);

                // Print diagnostic messages
                if (compilation.HasErrors)
                {
                    foreach (var message in compilation.Diagnostics.Messages)
                    {
                        Debug.WriteLine(message);
                    }
                }
                else
                {
                    string basePath = "..\\..\\..\\..\\WaveEngine.Bindings.WebGPU";
                    CsCodeGenerator.Instance.Generate(compilation, basePath, flavor);
                }
            }
        }
Esempio n. 3
0
        static void Main(string[] args)
        {
            var headerFile = Path.Combine(AppContext.BaseDirectory, "Headers", "renderdoc_app.h");
            var options    = new CppParserOptions
            {
                ParseMacros = true,
                Defines     =
                {
                    "_WIN32",
                }
            };

            var compilation = CppParser.ParseFile(headerFile, options);

            // Print diagnostic messages
            if (compilation.HasErrors)
            {
                foreach (var message in compilation.Diagnostics.Messages)
                {
                    Debug.WriteLine(message);
                }
            }
            else
            {
                string outputPath = "..\\..\\..\\..\\WaveEngine.Bindings.RenderDoc\\Generated";
                CsCodeGenerator.Instance.Generate(compilation, outputPath);
            }
        }
Esempio n. 4
0
        private static CppCompilation Parse(string vlcDir)
        {
            var parserOptions = new CppParserOptions
            {
                ParseComments = NoComment
            };

            parserOptions.IncludeFolders.Add(Path.Combine(vlcDir, include));
            return(CppParser.ParseFile(BuildPath(vlcDir, vlch), parserOptions));
        }
Esempio n. 5
0
        static CppCompilation Do(String file, ClConfig cfg)
        {
            var options = new CppParserOptions()
            {
                // Pass the defines -DMYDEFINE to the C++ parser
                Defines        = { },
                IncludeFolders = { },
                TargetCpu      = CppTargetCpu.X86_64,
            };

            options.ParseSystemIncludes = false;
            options.ParseComments       = false;
            options.AdditionalArguments.Add("-fno-complete-member-pointers");
            options.AdditionalArguments.Add("/TC");
            options.AdditionalArguments.Add("-std c99");
            options.AdditionalArguments.Add("/c");
            options.AdditionalArguments.Add("-fms-extensions");
            options.AdditionalArguments.Add("-fms-compatibility");
            options.AdditionalArguments.Add(" -fms-compatibility-version=19");
            options.ParseAsCpp = false;

            options.EnableFunctionBodies();

            foreach (KeyValuePair <string, string> kv in cfg.define)
            {
                String d = kv.Value == null ? (kv.Key) : (kv.Key + "=" + kv.Value);
                options.Defines.Add(d);
            }
            options.Defines.Add("CPP_AST_FIXED");

            foreach (String include in cfg.include)
            {
                options.IncludeFolders.Add(include);
            }

            options.ConfigureForWindowsMsvc();

            var compilation = CppParser.ParseFile(file, options);

            return(compilation);
        }
Esempio n. 6
0
        static void Main(string[] args)
        {
            var headerFile = Path.Combine(AppContext.BaseDirectory, "ImGUI", "cimgui.h");
            var options    = new CppParserOptions
            {
                ParseMacros = true,
                Defines     =
                {
                    "CIMGUI_DEFINE_ENUMS_AND_STRUCTS"
                }
            };

            var compilation = CppParser.ParseFile(headerFile, options);

            if (compilation.HasErrors)
            {
                foreach (var message in compilation.Diagnostics.Messages)
                {
                    Console.WriteLine(message);
                }
            }

            CsCodeGenerator.Generate(compilation, "../../../../src/SharpImGUI/Generated/");
        }
Esempio n. 7
0
        public static void Main(string[] args)
        {
            // In this sample we are going to bind a few C++ classes from https://github.com/lemire/simdjson
            // the library has "singleheader" file so we don't have to collect all needed files + includes
            // see https://github.com/lemire/simdjson/tree/master/singleheader


            string outputFolder = "../../../Output/";

            if (!Directory.Exists(outputFolder))
            {
                Directory.CreateDirectory(outputFolder);
            }

            Console.WriteLine("Downloading simdjson sources...");

            HttpClient httpClient           = new HttpClient();
            string     simdJsonSingleHeader = httpClient.GetStringAsync("https://raw.githubusercontent.com/lemire/simdjson/master/singleheader/simdjson.h").Result;

            File.WriteAllText(Path.Combine(outputFolder, @"simdjson.h"), simdJsonSingleHeader);

            Console.WriteLine("Downloaded! Parsing...");

            var options = new CppParserOptions();

            // TODO: test on macOS
            options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64);
            options.AdditionalArguments.Add("-std=c++17");
            CppCompilation compilation = CppParser.ParseFile(Path.Combine(outputFolder, @"simdjson.h"), options);

            if (compilation.DumpErrorsIfAny())
            {
                Console.ReadKey();
                return;
            }

            var mapper = new TypeMapper(compilation);

            // Register native types we don't want to bind (or any method with them in parameters)
            mapper.RegisterUnsupportedTypes(
                "simdjson",          // it's empty - we don't need it
                "basic_string",      // TODO:
                "basic_string_view", // TODO
                "basic_ostream");    // TODO:

            var templateManager = new TemplateManager();

            // Add additional stuff we want to see in the bindings.c
            templateManager
            .AddToCHeader(@"#include ""simdjson.h""")
            .SetGlobalFunctionsClassName("GlobalFunctions");

            PinvokeGenerator.Generate(mapper,
                                      templateManager,
                                      @namespace: "MyNamespace",
                                      dllImportPath: @"""simdjson.dll""",
                                      outCFile:  Path.Combine(outputFolder, "Bindings.c"),
                                      outCsFile: Path.Combine(outputFolder, "Bindings.cs"));

            Console.WriteLine("Done. See Output folder.");
        }
Esempio n. 8
0
    public static int Main(string[] args)
    {
        string outputPath = AppContext.BaseDirectory;

        if (args.Length > 0)
        {
            outputPath = args[0];
        }

        if (!Path.IsPathRooted(outputPath))
        {
            outputPath = Path.Combine(AppContext.BaseDirectory, outputPath);
        }

        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }

        string?headerFile = Path.Combine(AppContext.BaseDirectory, "vulkan", "vulkan.h");
        var    options    = new CppParserOptions
        {
            ParseMacros = true,
            Defines     =
            {
                "VK_USE_PLATFORM_ANDROID_KHR",
                "VK_USE_PLATFORM_IOS_MVK",
                "VK_USE_PLATFORM_MACOS_MVK",
                "VK_USE_PLATFORM_METAL_EXT",
                "VK_USE_PLATFORM_VI_NN",
                //"VK_USE_PLATFORM_WAYLAND_KHR",
                //"VK_USE_PLATFORM_WIN32_KHR",
                //"VK_USE_PLATFORM_SCREEN_QNX",
                "VK_ENABLE_BETA_EXTENSIONS"
            }
        };

        var compilation = CppParser.ParseFile(headerFile, options);

        // Print diagnostic messages
        if (compilation.HasErrors)
        {
            foreach (var message in compilation.Diagnostics.Messages)
            {
                if (message.Type == CppLogMessageType.Error)
                {
                    var currentColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(message);
                    Console.ForegroundColor = currentColor;
                }
            }

            return(0);
        }

        bool generateFuncFile = false;

        if (generateFuncFile)
        {
            File.Delete("Vk.txt");
            foreach (var func in compilation.Functions)
            {
                var signature    = new System.Text.StringBuilder();
                var argSignature = CsCodeGenerator.GetParameterSignature(func, true);
                signature
                .Append(func.ReturnType.GetDisplayName())
                .Append(" ")
                .Append(func.Name)
                .Append("(")
                .Append(argSignature)
                .Append(")");
                File.AppendAllText("Vk.txt", signature.ToString() + Environment.NewLine);
            }
        }

        CsCodeGenerator.Generate(compilation, outputPath);
        return(0);
    }
Esempio n. 9
0
        public static void Main(string[] args)
        {
            // input (single header)
            string headerPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/simdjson.h");

            // output
            string cgluePath    = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/bindings.cpp");
            string bindingsPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonSharp.Bindings/Bindings.Generated.cs");

            var options = new CppParserOptions();

            // TODO: test on macOS
            options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64);
            options.AdditionalArguments.Add("-std=c++17");
            CppCompilation compilation = CppParser.ParseFile(headerPath, options);

            if (compilation.DumpErrorsIfAny())
            {
                Console.ReadKey();
                return;
            }

            var mapper = new TypeMapper(compilation);

            mapper.RenamingForApi += (nativeName, isMethod) =>
            {
                if (nativeName == "iterator")
                {
                    return("ParsedJsonIteratorN");
                }
                if (!isMethod)
                {
                    return(nativeName + "N"); // SimdJsonSharp has two C# APIs: 1) managed 2) bindings - postfixed with 'N'
                }
                if (nativeName == "get_type")
                {
                    return("GetTokenType");
                }
                if (nativeName == "get_string")
                {
                    return("GetUtf8String");
                }
                return(nativeName);
            };

            // init_state_machine requires external linkage (impl)
            mapper.RegisterUnsupportedMethod(null, "init_state_machine");

            // Register native types we don't want to bind (or any method with them in parameters)
            mapper.RegisterUnsupportedTypes(
                "simdjson", // it's empty - we don't need it
                "__m128i",
                "simd_input",
                "utf8_checking_state",
                "basic_string",      // TODO:
                "basic_string_view", // TODO
                "basic_ostream");    // TODO:

            var templateManager = new TemplateManager();

            // Add additional stuff we want to see in the bindings.c
            templateManager
            .AddToCHeader(@"#include ""simdjson.h""")
            .AddToCHeader(@"using namespace simdjson;")
            .SetGlobalFunctionsClassName("SimdJsonN");

            PinvokeGenerator.Generate(mapper,
                                      templateManager,
                                      @namespace: "SimdJsonSharp",
                                      dllImportPath: @"SimdJsonN.NativeLib",
                                      outCFile: cgluePath,
                                      outCsFile: bindingsPath);

            Console.WriteLine("Done.");
        }
Esempio n. 10
0
        public static unsafe void Main(string[] args)
        {
            // input (single header)
            string headerPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/simdjson.h");

            // output
            string cgluePath    = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/bindings.cpp");
            string bindingsPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonSharp.Bindings/Bindings.Generated.cs");


            var options = new CppParserOptions();

            options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64);
            options.EnableMacros();
            options.AdditionalArguments.Add("-std=c++17");
            // TODO: test on macOS
            CppCompilation compilation = CppParser.ParseFile(headerPath, options);

            var csSb = new StringBuilder();

            csSb.AppendLine("// THIS FILE IS AUTOGENERATED!");
            csSb.AppendLine();
            csSb.AppendLine("using System;");
            csSb.AppendLine("using System.Runtime.InteropServices;");
            csSb.AppendLine();
            csSb.Append($"namespace {Namespace}\n{{");

            // Since we bind C++ we need to generate a DllImport-friendly C glue
            var cSb = new StringBuilder();

            cSb.AppendLine("// THIS FILE IS AUTOGENERATED!");
            cSb.AppendLine("#include \"simdjson.h\"");
            cSb.AppendLine();
            cSb.AppendLine("#if (defined WIN32 || defined _WIN32)");
            cSb.AppendLine("#define EXPORTS(returntype) extern \"C\" __declspec(dllexport) returntype __cdecl");
            cSb.AppendLine("#else");
            cSb.AppendLine("#define EXPORTS(returntype) extern \"C\" __attribute__((visibility(\"default\"))) returntype");
            cSb.AppendLine("#endif");

            List <CppClass> allClasses = compilation.GetAllClassesRecursively();

            _allClassNames = allClasses.Select(c => c.GetDisplayName()).ToList();

            foreach (CppClass cppClass in allClasses)
            {
                var csApiMethodsSb = new StringBuilder();
                var csDllImportsSb = new StringBuilder();

                string className = cppClass.Name;
                if (cppClass.Parent is CppClass parentClass)
                {
                    className = $"{parentClass.Name}::{className}";
                }

                if (_typesToIgnore.Contains(className))
                {
                    continue;
                }

                // prefix for all members
                string prefix = cppClass.Name + "_";

                cSb.AppendLine();
                cSb.AppendLine($"/* {className} */");


                IEnumerable <CppFunction> allFunctions = cppClass.Constructors.Take(1 /* HACK: take only first available ctors for now :) */).Concat(cppClass.Functions);
                foreach (CppFunction cppFunc in allFunctions)
                {
                    var argDefinitions = new List <string>();
                    var argInvocations = new List <string>();

                    // skip operators for now
                    if (cppFunc.IsOperator())
                    {
                        continue;
                    }

                    bool isStatic = cppFunc.StorageQualifier == CppStorageQualifier.Static;

                    string funcPrefix = prefix; // Class_function()
                    if (isStatic)
                    {
                        funcPrefix += "s_"; // Class_s_staticFunction()
                    }
                    if (!cppFunc.IsConstructor && !isStatic)
                    {
                        argDefinitions.Add($"{className}* target");
                    }

                    foreach (CppParameter cppParam in cppFunc.Parameters)
                    {
                        var type = cppParam.Type.GetDisplayName();

                        // method contains a parameter of type we don't support - skip the whole method (goto)
                        if (_typesToIgnore.Any(t => type.Contains(t)))
                        {
                            goto SKIP_FUNC;
                        }

                        string invocation = cppParam.Name;

                        // HACK: replace references with pointers (for classes)
                        if (type.EndsWith("&"))
                        {
                            type       = type.Remove(type.Length - 1) + "*";
                            invocation = "*" + invocation;
                        }

                        argDefinitions.Add($"{type} {cppParam.Name}");
                        argInvocations.Add(invocation);
                    }

                    string funcReturnType = cppFunc.IsConstructor ? $"{className}*" : cppFunc.ReturnType.GetDisplayName();
                    string finalFuncName  = $"{funcPrefix}{cppFunc.Name}";

                    // Func declaration
                    cSb.Append($"EXPORTS({funcReturnType}) {finalFuncName}({argDefinitions.AsCommaSeparatedStr()})");
                    cSb.Append(" {");

                    // Body
                    if (cppFunc.IsConstructor)
                    {
                        cSb.Append($" return new {className}({argInvocations.AsCommaSeparatedStr()});");
                    }
                    else
                    {
                        string returnStr    = cppFunc.ReturnType.IsVoid() ? " " : " return ";
                        string invokeTarget = "target->";
                        if (isStatic)
                        {
                            invokeTarget = className + "::";
                        }

                        cSb.Append($"{returnStr}{invokeTarget}{cppFunc.Name}({argInvocations.AsCommaSeparatedStr()});");
                    }

                    cSb.Append(" }");
                    cSb.AppendLine();

                    var(dllImports, apiMethods) = GenerateMethodCSharp(cppFunc, finalFuncName);
                    csDllImportsSb.AppendLine(dllImports);
                    csApiMethodsSb.AppendLine(apiMethods);

SKIP_FUNC:
                    continue;
                }

                // destructor
                cSb.Append($"EXPORTS(void) {prefix}Dispose({className}* target) {{ delete target; }}");
                cSb.AppendLine();

                // generate C# for this method:
                csSb.AppendLine(GenerateClassCSharp(cppClass, csDllImportsSb.ToString(), csApiMethodsSb.ToString()));
            }

            csSb.Append("}"); // end of namespace

            File.WriteAllText(cgluePath, cSb.ToString());
            File.WriteAllText(bindingsPath, csSb.ToString());
        }