diff --git a/src/CppParser/Bootstrap/Bootstrap.cs b/src/CppParser/Bootstrap/Bootstrap.cs new file mode 100644 index 00000000..5cb2cefc --- /dev/null +++ b/src/CppParser/Bootstrap/Bootstrap.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using CppSharp; +using CppSharp.AST; +using CppSharp.Generators; +using CppSharp.Passes; +using CppSharp.Types; +using CppAbi = CppSharp.Parser.AST.CppAbi; + +namespace CppSharp +{ + /// + /// Generates parser bootstrap code. + /// + class Bootstrap : ILibrary + { + static string GetSourceDirectory(string dir) + { + var directory = Directory.GetParent(Directory.GetCurrentDirectory()); + + while (directory != null) + { + var path = Path.Combine(directory.FullName, dir); + + if (Directory.Exists(path) && + Directory.Exists(Path.Combine(directory.FullName, "patches"))) + return path; + + directory = directory.Parent; + } + + throw new Exception("Could not find build directory: " + dir); + } + + public void Setup(Driver driver) + { + var options = driver.Options; + options.LibraryName = "CppSharp"; + options.DryRun = true; + options.Headers.AddRange(new string[] + { + "clang/AST/Expr.h", + }); + options.SetupXcode(); + options.MicrosoftMode = false; + options.TargetTriple = "i686-apple-darwin12.4.0"; + + options.addDefines ("__STDC_LIMIT_MACROS"); + options.addDefines ("__STDC_CONSTANT_MACROS"); + + var llvmPath = Path.Combine (GetSourceDirectory ("deps"), "llvm"); + var clangPath = Path.Combine(llvmPath, "tools", "clang"); + + options.addIncludeDirs(Path.Combine(llvmPath, "include")); + options.addIncludeDirs(Path.Combine(llvmPath, "build", "include")); + options.addIncludeDirs (Path.Combine (llvmPath, "build", "tools", "clang", "include")); + options.addIncludeDirs(Path.Combine(clangPath, "include")); + } + + public void SetupPasses(Driver driver) + { + } + + public void Preprocess(Driver driver, ASTContext ctx) + { + ctx.RenameNamespace("CppSharp::CppParser", "Parser"); + + var exprClass = ctx.FindCompleteClass ("clang::Expr"); + + var exprUnit = ctx.TranslationUnits [0]; + var subclassVisitor = new SubclassVisitor (exprClass); + exprUnit.Visit (subclassVisitor); + + var subclasses = subclassVisitor.Classes; + } + + public void Postprocess(Driver driver, ASTContext ctx) + { + } + + public static void Main(string[] args) + { + Console.WriteLine("Generating parser bootstrap code..."); + ConsoleDriver.Run(new Bootstrap()); + Console.WriteLine(); + } + } + + class SubclassVisitor : AstVisitor + { + public HashSet Classes; + Class expressionClass; + + public SubclassVisitor (Class expression) + { + expressionClass = expression; + Classes = new HashSet (); + } + + static bool IsDerivedFrom(Class subclass, Class superclass) + { + if (subclass == null) + return false; + + if (subclass == superclass) + return true; + + return IsDerivedFrom (subclass.BaseClass, superclass); + } + + public override bool VisitClassDecl (Class @class) + { + if (!@class.IsIncomplete && IsDerivedFrom (@class, expressionClass)) + Classes.Add (@class); + + return base.VisitClassDecl (@class); + } + } +} diff --git a/src/CppParser/Bootstrap/premake4.lua b/src/CppParser/Bootstrap/premake4.lua new file mode 100644 index 00000000..3ccb2ac2 --- /dev/null +++ b/src/CppParser/Bootstrap/premake4.lua @@ -0,0 +1,12 @@ +project "CppSharp.Parser.Bootstrap" + + kind "ConsoleApp" + language "C#" + SetupManagedProject() + debugdir "." + + files { "Bootstrap.cs", "*.lua" } + links { "CppSharp", "CppSharp.AST", "CppSharp.Generator", "System", "System.Core" } + + SetupParser() + \ No newline at end of file diff --git a/src/CppParser/premake4.lua b/src/CppParser/premake4.lua index b19d893f..c26ab6eb 100644 --- a/src/CppParser/premake4.lua +++ b/src/CppParser/premake4.lua @@ -36,3 +36,4 @@ project "CppSharp.CppParser" end include ("Bindings") +include ("Bootstrap")