diff --git a/src/Core/Parser/Parser.cs b/src/Core/Parser/Parser.cs new file mode 100644 index 00000000..62d76a41 --- /dev/null +++ b/src/Core/Parser/Parser.cs @@ -0,0 +1,94 @@ +using System; + +#if !OLD_PARSER +using CppSharp.Parser; +using CppSharp.Parser.AST; +#else +using CppSharp.AST; +#endif + +namespace CppSharp +{ + public class ClangParser + { + /// + /// Context with translation units ASTs. + /// + public ASTContext ASTContext { get; private set; } + + /// + /// Fired when source files are parsed. + /// + public Action SourceParsed = delegate {}; + + /// + /// Fire when library files are parsed. + /// + public Action LibraryParsed = delegate {}; + + public ClangParser() + { + ASTContext = new ASTContext(); + } + + /// + /// Parses a C++ source file to a translation unit. + /// + public ParserResult ParseSourceFile(SourceFile file, ParserOptions options) + { + //if (options.ASTContext == null) + options.ASTContext = ASTContext; + + options.FileName = file.Path; + var result = Parser.ClangParser.ParseHeader(options); + SourceParsed(file, result); + + return result; + } + + /// + /// Parses the project source files. + /// + public void ParseProject(Project project, ParserOptions options) + { + // TODO: Search for cached AST trees on disk + // TODO: Do multi-threaded parsing of source files + + foreach (var source in project.Sources) + ParseSourceFile(source, source.Options); + } + + /// + /// Parses a library file with symbols. + /// + public ParserResult ParseLibrary(string file, ParserOptions options) + { + options.FileName = file; + var result = Parser.ClangParser.ParseLibrary(options); + LibraryParsed(file, result); + + return result; + } + +#if !OLD_PARSER + /// + /// Converts a native parser AST to a managed AST. + /// + static public AST.ASTContext ConvertASTContext(ASTContext context) + { + var converter = new ASTConverter(context); + return converter.Convert(); + } + + public static AST.NativeLibrary ConvertLibrary(NativeLibrary library) + { + var newLibrary = new AST.NativeLibrary { FileName = library.FileName }; + + foreach (var symbol in library.Symbols) + newLibrary.Symbols.Add(symbol); + + return newLibrary; + } +#endif + } +} diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 834ec0f7..e2999a2b 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -1,14 +1,18 @@ -using System.Text; -using CppSharp.AST; +using CppSharp.AST; using CppSharp.Generators; using CppSharp.Generators.CLI; using CppSharp.Generators.CSharp; +using CppSharp.Parser; using CppSharp.Passes; using CppSharp.Types; using System; using System.Collections.Generic; using System.IO; +#if !OLD_PARSER +using Std; +#endif + namespace CppSharp { public class Driver @@ -107,22 +111,73 @@ namespace CppSharp } } + ParserOptions BuildParseOptions(SourceFile file) + { + var options = new ParserOptions + { + FileName = file.Path, +#if !OLD_PARSER + IncludeDirs = Options.IncludeDirs.ToStd(), + SystemIncludeDirs = Options.SystemIncludeDirs.ToStd(), + Defines = Options.Defines.ToStd(), + LibraryDirs = Options.LibraryDirs.ToStd(), +#else + IncludeDirs = Options.IncludeDirs, + SystemIncludeDirs = Options.SystemIncludeDirs, + Defines = Options.Defines, + LibraryDirs = Options.LibraryDirs, +#endif + Abi = Options.Parser.Abi, + ToolSetToUse = Options.Parser.ToolSetToUse, + TargetTriple = Options.Parser.TargetTriple, + NoStandardIncludes = Options.Parser.NoStandardIncludes, + NoBuiltinIncludes = Options.Parser.NoBuiltinIncludes, + MicrosoftMode = Options.Parser.MicrosoftMode, + Verbose = Options.Parser.Verbose, + }; + + return options; + } + public bool ParseCode() { - if (!Parser.ParseHeaders(Options.Headers)) - return false; + foreach (var header in Options.Headers) + { + var source = Project.AddFile(header); + source.Options = BuildParseOptions(source); + } - Library = Parser.Library; + var parser = new ClangParser(); + parser.SourceParsed += OnSourceFileParsed; + parser.LibraryParsed += OnFileParsed; + + parser.ParseProject(Project, Options.Parser); + +#if !OLD_PARSER + ASTContext = ClangParser.ConvertASTContext(parser.ASTContext); +#else + ASTContext = parser.ASTContext; +#endif return true; } public bool ParseLibraries() { - if (!Parser.ParseLibraries(Options.Libraries)) - return false; + foreach (var library in Options.Libraries) + { + var parser = new ClangParser(); + var res = parser.ParseLibrary(library, Options.Parser); - LibrarySymbols = Parser.Library; + if (res.Kind != ParserResultKind.Success) + continue; + +#if !OLD_PARSER + Symbols.Libraries.Add(ClangParser.ConvertLibrary(res.Library)); +#else + Symbols.Libraries.Add(res.Library); +#endif + } return true; } diff --git a/src/Generator/Parser.cs b/src/Generator/Parser.cs deleted file mode 100644 index e2ec1de6..00000000 --- a/src/Generator/Parser.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using CppSharp.AST; - -namespace CppSharp -{ - public class Parser - { - public Library Library { get; private set; } - private readonly DriverOptions options; - - public Parser(DriverOptions options) - { - this.options = options; - Library = new Library(); - } - - public bool ParseHeaders(IEnumerable headers) - { - var hasErrors = false; - - foreach (var header in headers) - { - var result = ParseHeader(header); - - // If we have some error, report to end-user. - if (!options.IgnoreParseErrors) - { - foreach (var diag in result.Diagnostics) - { - if (diag.Level == ParserDiagnosticLevel.Error || - diag.Level == ParserDiagnosticLevel.Fatal) - hasErrors = true; - } - } - } - - return !hasErrors; - } - - public ParserResult ParseHeader(string file) - { - var parserOptions = new ParserOptions - { - Library = Library, - FileName = file, - Verbose = options.Verbose, - IncludeDirs = options.IncludeDirs, - SystemIncludeDirs = options.SystemIncludeDirs, - Defines = options.Defines, - NoStandardIncludes = options.NoStandardIncludes, - NoBuiltinIncludes = options.NoBuiltinIncludes, - MicrosoftMode = options.MicrosoftMode, - ToolSetToUse = options.ToolsetToUse, - TargetTriple = options.TargetTriple, - Abi = options.Abi - }; - - var result = ClangParser.ParseHeader(parserOptions); - OnHeaderParsed(file, result); - - return result; - } - - public bool ParseLibraries(IEnumerable libraries) - { - var hasErrors = false; - - foreach (var lib in libraries) - { - var result = ParseLibrary(lib); - - // If we have some error, report to end-user. - if (!options.IgnoreParseErrors) - { - foreach (var diag in result.Diagnostics) - { - if (diag.Level == ParserDiagnosticLevel.Error || - diag.Level == ParserDiagnosticLevel.Fatal) - hasErrors = true; - } - } - } - - return !hasErrors; - } - - public ParserResult ParseLibrary(string file) - { - var parserOptions = new ParserOptions - { - Library = Library, - FileName = file, - Verbose = false, - LibraryDirs = options.LibraryDirs, - ToolSetToUse = options.ToolsetToUse - }; - - var result = ClangParser.ParseLibrary(parserOptions); - OnLibraryParsed(file, result); - - return result; - } - - public Action OnHeaderParsed = delegate {}; - public Action OnLibraryParsed = delegate { }; - - } -}