using System; using System.Collections.Generic; using System.Linq; using CppSharp.AST; using CppSharp.Parser; using ASTContext = CppSharp.Parser.AST.ASTContext; using NativeLibrary = CppSharp.Parser.AST.NativeLibrary; namespace CppSharp { public class ClangParser { /// /// Context with translation units ASTs. /// public ASTContext ASTContext { get; private set; } /// /// Fired when source files are parsed. /// public Action, ParserResult> SourcesParsed = delegate {}; /// /// Fired when library files are parsed. /// public Action LibraryParsed = delegate {}; public ClangParser() { ASTContext = new ASTContext(); } public ClangParser(ASTContext context) { ASTContext = context; } /// /// Get info about that target /// /// /// public ParserTargetInfo GetTargetInfo(ParserOptions options) { options.ASTContext = ASTContext; return Parser.ClangParser.GetTargetInfo(options); } /// /// Parses a C++ source file to a translation unit. /// private ParserResult ParseSourceFile(SourceFile file) { var options = file.Options; options.ASTContext = ASTContext; options.AddSourceFiles(file.Path); var result = Parser.ClangParser.ParseHeader(options); SourcesParsed(new[] { file }, result); return result; } /// /// Parses C++ source files to a translation unit. /// private void ParseSourceFiles(IList files) { var options = files[0].Options; options.ASTContext = ASTContext; foreach (var file in files) options.AddSourceFiles(file.Path); using (var result = Parser.ClangParser.ParseHeader(options)) SourcesParsed(files, result); } /// /// Parses the project source files. /// public void ParseProject(Project project, bool unityBuild) { // TODO: Search for cached AST trees on disk // TODO: Do multi-threaded parsing of source files if (unityBuild) ParseSourceFiles(project.Sources); else foreach (var parserResult in project.Sources.Select(s => ParseSourceFile(s)).ToList()) parserResult.Dispose(); } /// /// Parses a library file with symbols. /// public ParserResult ParseLibrary(string file, ParserOptions options) { options.LibraryFile = file; var result = Parser.ClangParser.ParseLibrary(options); LibraryParsed(file, result); return result; } /// /// 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, ArchType = (ArchType) library.ArchType }; for (uint i = 0; i < library.SymbolsCount; ++i) { var symbol = library.GetSymbols(i); newLibrary.Symbols.Add(symbol); } for (uint i = 0; i < library.DependenciesCount; i++) { newLibrary.Dependencies.Add(library.GetDependencies(i)); } return newLibrary; } } }