From e1200bc5774c4c15aaaccb67565fa4a9b573fdf7 Mon Sep 17 00:00:00 2001 From: Joao Matos <joao@tritao.eu> Date: Wed, 30 Aug 2017 17:27:42 +0100 Subject: [PATCH] [parser] Refactor the parser layer. Removes some useless abstractions and unused code. Signed-off-by: Joao Matos <joao@tritao.eu> --- src/CppParser/Parser.cpp | 16 ---- src/Generator.Tests/ASTTestFixture.cs | 1 - src/Generator/Driver.cs | 53 ++++++----- src/Parser/Parser.cs | 46 +++------ src/Parser/ParserOptions.cs | 131 ++++++++++++++++---------- src/Parser/Project.cs | 119 ----------------------- 6 files changed, 122 insertions(+), 244 deletions(-) delete mode 100644 src/Parser/Project.cs diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 3a2dd2c0..f8552c1d 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -4210,22 +4210,6 @@ ParserTargetInfo* Parser::GetTargetInfo() AST = &c->getASTContext(); - // Initialize enough Clang codegen machinery so we can get at ABI details. - llvm::LLVMContext Ctx; - std::unique_ptr<llvm::Module> M(new llvm::Module("", Ctx)); - - M->setTargetTriple(AST->getTargetInfo().getTriple().getTriple()); - M->setDataLayout(AST->getTargetInfo().getDataLayout()); - - std::unique_ptr<clang::CodeGen::CodeGenModule> CGM( - new clang::CodeGen::CodeGenModule(c->getASTContext(), c->getHeaderSearchOpts(), - c->getPreprocessorOpts(), c->getCodeGenOpts(), *M, c->getDiagnostics())); - - std::unique_ptr<clang::CodeGen::CodeGenTypes> CGT( - new clang::CodeGen::CodeGenTypes(*CGM.get())); - - codeGenTypes = CGT.get(); - auto parserTargetInfo = new ParserTargetInfo(); auto& TI = AST->getTargetInfo(); diff --git a/src/Generator.Tests/ASTTestFixture.cs b/src/Generator.Tests/ASTTestFixture.cs index 2c5c771d..5df84b3d 100644 --- a/src/Generator.Tests/ASTTestFixture.cs +++ b/src/Generator.Tests/ASTTestFixture.cs @@ -30,7 +30,6 @@ namespace CppSharp.Generator.Tests }; Driver.Setup(); - Driver.BuildParseOptions(); if (!Driver.ParseCode()) throw new Exception("Error parsing the code"); diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 0fe95a5a..92fd76ff 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -20,7 +20,6 @@ namespace CppSharp { public DriverOptions Options { get; private set; } public ParserOptions ParserOptions { get; set; } - public Project Project { get; private set; } public BindingContext Context { get; private set; } public Generator Generator { get; private set; } @@ -29,7 +28,6 @@ namespace CppSharp public Driver(DriverOptions options) { Options = options; - Project = new Project(); ParserOptions = new ParserOptions(); } @@ -74,9 +72,9 @@ namespace CppSharp Generator = CreateGeneratorFromKind(Options.GeneratorKind); } - void OnSourceFileParsed(IList<SourceFile> files, ParserResult result) + void OnSourceFileParsed(IEnumerable<string> files, ParserResult result) { - OnFileParsed(files.Select(f => f.Path), result); + OnFileParsed(files, result); } void OnFileParsed(string file, ParserResult result) @@ -117,7 +115,7 @@ namespace CppSharp } } - public ParserOptions BuildParserOptions(SourceFile file = null) + public ParserOptions BuildParserOptions(string file = null) { var options = new ParserOptions { @@ -177,7 +175,7 @@ namespace CppSharp } foreach (var module in Options.Modules.Where( - m => file == null || m.Headers.Contains(file.Path))) + m => file == null || m.Headers.Contains(file))) { foreach (var include in module.IncludeDirs) options.AddIncludeDirs(include); @@ -197,30 +195,37 @@ namespace CppSharp public bool ParseCode() { - var parser = new ClangParser(new Parser.AST.ASTContext()); + var astContext = new Parser.AST.ASTContext(); + var parser = new ClangParser(astContext); parser.SourcesParsed += OnSourceFileParsed; - parser.ParseProject(Project, Options.UnityBuild); - foreach (var source in Project.Sources.Where(s => s.Options != null)) - source.Options.Dispose(); + var sourceFiles = Options.Modules.SelectMany(m => m.Headers); - Context.TargetInfo = parser.GetTargetInfo(ParserOptions); - Context.ASTContext = ClangParser.ConvertASTContext(parser.ASTContext); + if (Options.UnityBuild) + { + var parserOptions = BuildParserOptions(); + var result = parser.ParseSourceFiles(sourceFiles, parserOptions); + result.Dispose(); + } + else + { + var results = new List<ParserResult>(); - return !hasParsingErrors; - } + foreach (var sourceFile in sourceFiles) + { + var parserOptions = BuildParserOptions(sourceFile); + results.Add(parser.ParseSourceFile(sourceFile, parserOptions)); + } - public void BuildParseOptions() - { - foreach (var header in Options.Modules.SelectMany(m => m.Headers)) - { - var source = Project.AddFile(header); - if (!Options.UnityBuild) - source.Options = BuildParserOptions(source); + foreach (var result in results) + result.Dispose(); } - if (Options.UnityBuild) - Project.Sources[0].Options = BuildParserOptions(); + + Context.TargetInfo = parser.GetTargetInfo(ParserOptions); + Context.ASTContext = ClangParser.ConvertASTContext(astContext); + + return !hasParsingErrors; } public void SortModulesByDependencies() @@ -480,8 +485,6 @@ namespace CppSharp if (!options.Quiet) Diagnostics.Message("Parsing code..."); - driver.BuildParseOptions(); - if (!driver.ParseCode()) { Diagnostics.Error("CppSharp has encountered an error while parsing code."); diff --git a/src/Parser/Parser.cs b/src/Parser/Parser.cs index 4046788d..0a7fdbf0 100644 --- a/src/Parser/Parser.cs +++ b/src/Parser/Parser.cs @@ -18,7 +18,7 @@ namespace CppSharp /// <summary> /// Fired when source files are parsed. /// </summary> - public Action<IList<SourceFile>, ParserResult> SourcesParsed = delegate {}; + public Action<IEnumerable<string>, ParserResult> SourcesParsed = delegate {}; /// <summary> /// Fired when library files are parsed. @@ -36,10 +36,8 @@ namespace CppSharp } /// <summary> - /// Get info about that target + /// Gets target information for a specific target triple. /// </summary> - /// <param name="options"></param> - /// <returns></returns> public ParserTargetInfo GetTargetInfo(ParserOptions options) { options.ASTContext = ASTContext; @@ -48,47 +46,27 @@ namespace CppSharp } /// <summary> - /// Parses a C++ source file to a translation unit. + /// Parses a C++ source file as a translation unit. /// </summary> - private ParserResult ParseSourceFile(SourceFile file) + public ParserResult ParseSourceFile(string file, ParserOptions options) { - var options = file.Options; - options.ASTContext = ASTContext; - options.AddSourceFiles(file.Path); - - var result = Parser.ClangParser.ParseHeader(options); - SourcesParsed(new[] { file }, result); - - return result; + return ParseSourceFiles(new [] { file }, options); } /// <summary> - /// Parses C++ source files to a translation unit. + /// Parses a set of C++ source files as a single translation unit. /// </summary> - private void ParseSourceFiles(IList<SourceFile> files) + public ParserResult ParseSourceFiles(IEnumerable<string> files, ParserOptions options) { - 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); - } + options.AddSourceFiles(file); - /// <summary> - /// Parses the project source files. - /// </summary> - 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(); + var result = Parser.ClangParser.ParseHeader(options); + SourcesParsed(files, result); + + return result; } /// <summary> diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index 413c09a1..cd5d6fda 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -1,8 +1,45 @@ using CppSharp.Parser.AST; using System.Reflection; +using LanguageVersion = CppSharp.Parser.LanguageVersion; namespace CppSharp.Parser { + public enum LanguageVersion + { + /// <summary> + /// C programming language (year 1999). + /// </summary> + C99, + /// <summary> + /// C programming language (year 1999, GNU variant). + /// </summary> + C99_GNU, + /// <summary> + /// C++ programming language (year 1998). + /// </summary> + CPP98, + /// <summary> + /// C++ programming language (year 1998, GNU variant). + /// </summary> + CPP98_GNU, + /// <summary> + /// C++ programming language (year 2011). + /// </summary> + CPP11, + /// <summary> + /// C++ programming language (year 2011, GNU variant). + /// </summary> + CPP11_GNU, + /// <summary> + /// C++ programming language (year 2014). + /// </summary> + CPP14, + /// <summary> + /// C++ programming language (year 2014, GNU variant). + /// </summary> + CPP14_GNU + }; + public class ParserOptions : CppParserOptions { public ParserOptions() @@ -12,12 +49,12 @@ namespace CppSharp.Parser CurrentDir = Assembly.GetExecutingAssembly().Location; } - public bool IsItaniumLikeAbi { get { return Abi != CppAbi.Microsoft; } } - public bool IsMicrosoftAbi { get { return Abi == CppAbi.Microsoft; } } - public bool EnableRtti { get; set; } - public LanguageVersion LanguageVersion { get; set; } = LanguageVersion.GNUPlusPlus11; + public bool IsItaniumLikeAbi => Abi != CppAbi.Microsoft; + public bool IsMicrosoftAbi => Abi == CppAbi.Microsoft; + + public bool EnableRTTI { get; set; } + public LanguageVersion? LanguageVersion { get; set; } - /// Sets up the parser options to work with the given Visual Studio toolchain. public void SetupMSVC() { VisualStudioVersion vsVersion = VisualStudioVersion.Latest; @@ -43,9 +80,13 @@ namespace CppSharp.Parser #pragma warning restore 162 } + SetupMSVC(vsVersion); } + /// <summary> + /// Sets up the parser options to work with the given Visual Studio toolchain. + /// </summary> public void SetupMSVC(VisualStudioVersion vsVersion) { MicrosoftMode = true; @@ -57,6 +98,10 @@ namespace CppSharp.Parser var includes = MSVCToolchain.GetSystemIncludes(vsVersion, out foundVsVersion); foreach (var include in includes) AddSystemIncludeDirs(include); + + if (!LanguageVersion.HasValue) + LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU; + var clVersion = MSVCToolchain.GetCLVersion(foundVsVersion); ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000; @@ -85,15 +130,20 @@ namespace CppSharp.Parser public void Setup() { SetupArguments(); - SetupIncludes(); + + if (!NoBuiltinIncludes) + SetupIncludes(); } private void SetupArguments() { + if (!LanguageVersion.HasValue) + LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU; + switch (LanguageVersion) { - case LanguageVersion.C: - case LanguageVersion.GNUC: + case CppSharp.Parser.LanguageVersion.C99: + case CppSharp.Parser.LanguageVersion.C99_GNU: AddArguments("-xc"); break; default: @@ -103,64 +153,47 @@ namespace CppSharp.Parser switch (LanguageVersion) { - case LanguageVersion.C: + case CppSharp.Parser.LanguageVersion.C99: AddArguments("-std=c99"); break; - case LanguageVersion.GNUC: + case CppSharp.Parser.LanguageVersion.C99_GNU: AddArguments("-std=gnu99"); break; - case LanguageVersion.CPlusPlus98: + case CppSharp.Parser.LanguageVersion.CPP98: AddArguments("-std=c++98"); break; - case LanguageVersion.GNUPlusPlus98: + case CppSharp.Parser.LanguageVersion.CPP98_GNU: AddArguments("-std=gnu++98"); break; - case LanguageVersion.CPlusPlus11: - AddArguments(MicrosoftMode ? "-std=c++14" : "-std=c++11"); + case CppSharp.Parser.LanguageVersion.CPP11: + AddArguments("-std=c++11"); break; - default: - AddArguments(MicrosoftMode ? "-std=gnu++14" : "-std=gnu++11"); + case CppSharp.Parser.LanguageVersion.CPP11_GNU: + AddArguments("-std=gnu++11"); + break; + case CppSharp.Parser.LanguageVersion.CPP14: + AddArguments("-std=c++14"); + break; + case CppSharp.Parser.LanguageVersion.CPP14_GNU: + AddArguments("-std=gnu++14"); break; } - if (!EnableRtti) + if (!EnableRTTI) AddArguments("-fno-rtti"); } private void SetupIncludes() { - if (Platform.IsMacOS) - SetupXcode(); - else if (Platform.IsWindows && !NoBuiltinIncludes) - SetupMSVC(); + switch(Platform.Host) + { + case TargetPlatform.Windows: + SetupMSVC(); + break; + case TargetPlatform.MacOS: + SetupXcode(); + break; + } } } - - public enum LanguageVersion - { - /** - * The C programming language. - */ - C, - /** - * The C programming language (GNU version). - */ - GNUC, - /** - * The C++ programming language year 1998; supports deprecated constructs. - */ - CPlusPlus98, - /** - * The C++ programming language year 1998; supports deprecated constructs (GNU version). - */ - GNUPlusPlus98, - /** - * The C++ programming language year 2011. - */ - CPlusPlus11, - /** - * The C++ programming language year 2011 (GNU version). - */ - GNUPlusPlus11 - }; } diff --git a/src/Parser/Project.cs b/src/Parser/Project.cs deleted file mode 100644 index b679ed1a..00000000 --- a/src/Parser/Project.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System.Collections.Generic; -using CppSharp.AST; -using CppSharp.Parser; - -namespace CppSharp -{ - /// <summary> - /// Represents a reference to a source file. - /// </summary> - public class SourceFile - { - /// <summary> - /// Gets the file name. - /// </summary> - public string Name - { - get { return System.IO.Path.GetFileName(Path); } - } - - /// <summary> - /// Gets the file path. - /// </summary> - public string Path { get; private set; } - - /// <summary> - /// Gets/sets the parser options for the file. - /// </summary> - public ParserOptions Options { get; set; } - - /// <summary> - /// Gets/sets the AST representation of the file. - /// </summary> - public TranslationUnit Unit { get; set; } - - public SourceFile(string path) - { - Path = path; - } - - public override string ToString() - { - return Path; - } - } - - /// <summary> - /// Represents a C++ project with source and library files. - /// </summary> - public class Project - { - /// <summary> - /// List of per-project C/C++ preprocessor defines. - /// </summary> - public IList<string> Defines { get; private set; } - - /// <summary> - /// List of per-project C/C++ include directories. - /// </summary> - public IList<string> IncludeDirs { get; private set; } - - /// <summary> - /// List of per-project C/C++ system include directories. - /// </summary> - public IList<string> SystemIncludeDirs { get; private set; } - - /// <summary> - /// List of source files in the project. - /// </summary> - public IList<SourceFile> Sources { get; private set; } - - /// <summary> - /// Main AST context with translation units for the sources. - /// </summary> - public ASTContext ASTContext { get; private set; } - - /// <summary> - /// Main symbols context with indexed library symbols. - /// </summary> - public SymbolContext SymbolsContext { get; private set; } - - public Project() - { - Defines = new List<string>(); - IncludeDirs = new List<string>(); - SystemIncludeDirs = new List<string>(); - - Sources = new List<SourceFile>(); - } - - /// <summary> - /// Adds a new source file to the project. - /// </summary> - public SourceFile AddFile(string path) - { - var sourceFile = new SourceFile(path); - Sources.Add(sourceFile); - - return sourceFile; - } - - /// <summary> - /// Adds a group of source files to the project. - /// </summary> - public void AddFiles(IEnumerable<string> paths) - { - foreach (var path in paths) - AddFile(path); - } - - /// <summary> - /// Adds a new source file to the project. - /// </summary> - public void AddFolder(string path) - { - var sourceFile = new SourceFile(path); - Sources.Add(sourceFile); - } - } -}