From b41dc261ed528ddd5d7a1aeee4b48477449dd2fa Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sun, 22 May 2016 15:58:35 +0300 Subject: [PATCH] Added support for directly wrapping entire sets of interdependent libraries. It's realised by using modules. Users now have to define one module for each library they want wrapped while setting the driver up. Signed-off-by: Dimitar Dobrev --- examples/SDL/SDL.cs | 2 +- src/AST/Declaration.cs | 9 +- src/AST/Expression.cs | 51 ++++++++++ src/{Generator => AST}/Module.cs | 7 +- src/AST/SymbolContext.cs | 8 +- src/AST/TranslationUnit.cs | 9 ++ src/CppParser/Bindings/ParserGen.cs | 4 +- src/CppParser/Bootstrap/Bootstrap.cs | 12 +-- src/Generator.Tests/ASTTestFixture.cs | 4 +- src/Generator.Tests/GeneratorTest.cs | 2 +- .../ReadNativeDependenciesTest.cs | 4 +- src/Generator/Driver.cs | 93 +++++++++---------- src/Generator/Generator.cs | 74 ++++++++------- .../Generators/CLI/CLIHeadersTemplate.cs | 3 +- src/Generator/Generators/CLI/CLIMarshal.cs | 2 +- .../Generators/CLI/CLITextTemplate.cs | 5 +- .../Generators/CLI/CLITypePrinter.cs | 2 +- .../CSharp/CSharpExpressionPrinter.cs | 1 - .../Generators/CSharp/CSharpTextTemplate.cs | 30 +++--- .../Generators/CSharp/CSharpTypePrinter.cs | 2 +- src/Generator/Options.cs | 49 ++++++---- src/Generator/Passes/CleanUnitPass.cs | 16 +++- src/Generator/Passes/DelegatesPass.cs | 50 ++++++---- .../FixDefaultParamValuesOfOverridesPass.cs | 6 +- .../Passes/GenerateInlinesCodePass.cs | 17 ++-- .../Passes/GenerateTemplatesCodePass.cs | 21 +++-- .../GetterSetterToPropertyAdvancedPass.cs | 5 +- .../Passes/HandleDefaultParamValuesPass.cs | 7 +- .../Passes/MoveFunctionToClassPass.cs | 2 +- .../Passes/MoveOperatorToClassPass.cs | 9 +- src/Generator/Passes/RenameRootNamespaces.cs | 10 +- src/Generator/Types/Types.cs | 3 +- tests/NamespacesDerived/NamespacesDerived.cs | 11 --- 33 files changed, 318 insertions(+), 212 deletions(-) rename src/{Generator => AST}/Module.cs (89%) diff --git a/examples/SDL/SDL.cs b/examples/SDL/SDL.cs index 4b4968cc..d044577e 100644 --- a/examples/SDL/SDL.cs +++ b/examples/SDL/SDL.cs @@ -13,7 +13,7 @@ namespace CppSharp options.LibraryName = "SDL"; options.Headers.Add("SDL.h"); var sdlPath = Path.Combine(GetExamplesDirectory("SDL"), "SDL-2.0/include"); - options.Module.IncludeDirs.Add(sdlPath); + options.addIncludeDirs(sdlPath); options.OutputDir = "SDL"; } diff --git a/src/AST/Declaration.cs b/src/AST/Declaration.cs index 8442e8cb..9bc7f553 100644 --- a/src/AST/Declaration.cs +++ b/src/AST/Declaration.cs @@ -41,11 +41,7 @@ namespace CppSharp.AST /// /// Declaration is generated to be used internally. /// - Internal, - /// - /// Declaration was already generated in a linked assembly. - /// - Link, + Internal } /// @@ -252,8 +248,7 @@ namespace CppSharp.AST { var k = GenerationKind; return k == GenerationKind.Generate - || k == GenerationKind.Internal - || k == GenerationKind.Link; + || k == GenerationKind.Internal; } } diff --git a/src/AST/Expression.cs b/src/AST/Expression.cs index 5a9a2898..c95b801a 100644 --- a/src/AST/Expression.cs +++ b/src/AST/Expression.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.Linq; namespace CppSharp.AST { @@ -7,6 +9,8 @@ namespace CppSharp.AST public string DebugText; public abstract TV Visit(IExpressionVisitor visitor); + + public abstract Expression Clone(); } public class BuiltinTypeExpression : Expression @@ -39,6 +43,19 @@ namespace CppSharp.AST { return visitor.VisitExpression(this); } + + public override Expression Clone() + { + return new BuiltinTypeExpression + { + Value = this.Value, + Type = this.Type, + DebugText = this.DebugText, + Class = this.Class, + Declaration = this.Declaration, + String = this.String + }; + } } public class BinaryOperator : Expression @@ -59,6 +76,16 @@ namespace CppSharp.AST { return visitor.VisitExpression(this); } + + public override Expression Clone() + { + return new BinaryOperator(LHS.Clone(), RHS.Clone(), OpcodeStr) + { + DebugText = this.DebugText, + Declaration = this.Declaration, + String = this.String + }; + } } public class CallExpr : Expression @@ -75,6 +102,18 @@ namespace CppSharp.AST { return visitor.VisitExpression(this); } + + public override Expression Clone() + { + var clone = new CallExpr + { + DebugText = this.DebugText, + Declaration = this.Declaration, + String = this.String + }; + clone.Arguments.AddRange(Arguments.Select(a => a.Clone())); + return clone; + } } public class CXXConstructExpr : Expression @@ -91,6 +130,18 @@ namespace CppSharp.AST { return visitor.VisitExpression(this); } + + public override Expression Clone() + { + var clone = new CXXConstructExpr + { + DebugText = this.DebugText, + Declaration = this.Declaration, + String = this.String + }; + clone.Arguments.AddRange(Arguments.Select(a => a.Clone())); + return clone; + } } public interface IExpressionVisitor diff --git a/src/Generator/Module.cs b/src/AST/Module.cs similarity index 89% rename from src/Generator/Module.cs rename to src/AST/Module.cs index 8b345c5c..dc955ff1 100644 --- a/src/Generator/Module.cs +++ b/src/AST/Module.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace CppSharp +namespace CppSharp.AST { public class Module { @@ -12,6 +12,8 @@ namespace CppSharp Libraries = new List(); Defines = new List(); Undefines = new List(); + Units = new List(); + CodeFiles = new List(); } public List IncludeDirs { get; private set; } @@ -22,6 +24,9 @@ namespace CppSharp public List Undefines { get; set; } public string OutputNamespace { get; set; } + public List Units { get; private set; } + public List CodeFiles { get; private set; } + public string SharedLibraryName { get diff --git a/src/AST/SymbolContext.cs b/src/AST/SymbolContext.cs index c6beff8d..b20c97f5 100644 --- a/src/AST/SymbolContext.cs +++ b/src/AST/SymbolContext.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace CppSharp.AST { @@ -79,8 +80,9 @@ namespace CppSharp.AST { foreach (var symbol in library.Symbols) { - Symbols[symbol] = library; - if (symbol.StartsWith("__")) + if (!Symbols.ContainsKey(symbol)) + Symbols[symbol] = library; + if (symbol.StartsWith("__", StringComparison.Ordinal)) { string stripped = symbol.Substring(1); if (!Symbols.ContainsKey(stripped)) diff --git a/src/AST/TranslationUnit.cs b/src/AST/TranslationUnit.cs index 17e191ab..7610ee5d 100644 --- a/src/AST/TranslationUnit.cs +++ b/src/AST/TranslationUnit.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -24,6 +25,12 @@ namespace CppSharp.AST /// Contains the macros present in the unit. public List Macros; + public Module Module + { + get { return (Module) module.Target; } + set { module = new WeakReference(value); } + } + public bool IsSystemHeader { get; set; } public bool IsValid { get { return FilePath != ""; } } @@ -75,5 +82,7 @@ namespace CppSharp.AST (fileRelativePath = Path.Combine(FileRelativeDirectory, FileName)); } } + + private WeakReference module; } } \ No newline at end of file diff --git a/src/CppParser/Bindings/ParserGen.cs b/src/CppParser/Bindings/ParserGen.cs index e31b2dba..766c1e0c 100644 --- a/src/CppParser/Bindings/ParserGen.cs +++ b/src/CppParser/Bindings/ParserGen.cs @@ -71,8 +71,8 @@ namespace CppSharp SetupLinuxOptions(options); var basePath = Path.Combine(GetSourceDirectory("src"), "CppParser"); - options.Module.IncludeDirs.Add(basePath); - options.Module.LibraryDirs.Add("."); + options.addIncludeDirs(basePath); + options.addLibraryDirs("."); options.OutputDir = Path.Combine(GetSourceDirectory("src"), "CppParser", "Bindings", Kind.ToString()); diff --git a/src/CppParser/Bootstrap/Bootstrap.cs b/src/CppParser/Bootstrap/Bootstrap.cs index 2deba5c8..4198d277 100644 --- a/src/CppParser/Bootstrap/Bootstrap.cs +++ b/src/CppParser/Bootstrap/Bootstrap.cs @@ -42,16 +42,16 @@ namespace CppSharp options.MicrosoftMode = false; options.TargetTriple = "i686-apple-darwin12.4.0"; - options.Module.Defines.Add("__STDC_LIMIT_MACROS"); - options.Module.Defines.Add("__STDC_CONSTANT_MACROS"); + 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.Module.IncludeDirs.Add(Path.Combine(llvmPath, "include")); - options.Module.IncludeDirs.Add(Path.Combine(llvmPath, "build", "include")); - options.Module.IncludeDirs.Add(Path.Combine (llvmPath, "build", "tools", "clang", "include")); - options.Module.IncludeDirs.Add(Path.Combine(clangPath, "include")); + 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) diff --git a/src/Generator.Tests/ASTTestFixture.cs b/src/Generator.Tests/ASTTestFixture.cs index da810401..43ea5862 100644 --- a/src/Generator.Tests/ASTTestFixture.cs +++ b/src/Generator.Tests/ASTTestFixture.cs @@ -15,13 +15,11 @@ namespace CppSharp.Generator.Tests Options = new DriverOptions(); var testsPath = GeneratorTest.GetTestsDirectory("Native"); - Options.Module.IncludeDirs.Add(testsPath); + Options.addIncludeDirs(testsPath); Options.Headers.AddRange(files); Driver = new Driver(Options, new TextDiagnosticPrinter()); - foreach (var includeDir in Options.Module.IncludeDirs) - Options.addIncludeDirs(includeDir); Driver.SetupIncludes(); Driver.BuildParseOptions(); if (!Driver.ParseCode()) diff --git a/src/Generator.Tests/GeneratorTest.cs b/src/Generator.Tests/GeneratorTest.cs index 5509fede..62f4e499 100644 --- a/src/Generator.Tests/GeneratorTest.cs +++ b/src/Generator.Tests/GeneratorTest.cs @@ -46,7 +46,7 @@ namespace CppSharp.Utils options.TargetTriple = Environment.Is64BitProcess ? "x86_64-apple-darwin" : "i686-apple-darwin"; var path = Path.GetFullPath(GetTestsDirectory(name)); - options.Module.IncludeDirs.Add(path); + options.addIncludeDirs(path); // Remove this hardcoded path once we update our LLVM binary packages to bundle // the built-in Clang includes. diff --git a/src/Generator.Tests/ReadNativeDependenciesTest.cs b/src/Generator.Tests/ReadNativeDependenciesTest.cs index 84629eef..cad0497b 100644 --- a/src/Generator.Tests/ReadNativeDependenciesTest.cs +++ b/src/Generator.Tests/ReadNativeDependenciesTest.cs @@ -38,11 +38,9 @@ namespace CppSharp.Generator.Tests private static IList GetDependencies(string library) { var driverOptions = new DriverOptions(); - driverOptions.Module.LibraryDirs.Add(GeneratorTest.GetTestsDirectory("Native")); + driverOptions.addLibraryDirs(GeneratorTest.GetTestsDirectory("Native")); driverOptions.Libraries.Add(library); var driver = new Driver(driverOptions, new TextDiagnosticPrinter()); - foreach (var libraryDir in driverOptions.Module.LibraryDirs) - driverOptions.addLibraryDirs(libraryDir); Assert.IsTrue(driver.ParseLibraries()); var dependencies = driver.Symbols.Libraries[0].Dependencies; return dependencies; diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 5ad4bea2..ed65b101 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using System.Text; using CppSharp.AST; using CppSharp.Generators; @@ -15,6 +14,7 @@ using Microsoft.CSharp; using CppSharp.Parser; using System.CodeDom; using System; +using System.Reflection; namespace CppSharp { @@ -67,15 +67,18 @@ namespace CppSharp static void ValidateOptions(DriverOptions options) { - if (string.IsNullOrWhiteSpace(options.LibraryName)) - throw new InvalidOptionException(); + foreach (var module in options.Modules) + { + if (string.IsNullOrWhiteSpace(module.LibraryName)) + throw new InvalidOptionException("One of your modules has no library name."); + + if (string.IsNullOrWhiteSpace(module.OutputNamespace)) + module.OutputNamespace = module.LibraryName; + } if (options.NoGenIncludeDirs != null) foreach (var incDir in options.NoGenIncludeDirs) options.addIncludeDirs(incDir); - - if (string.IsNullOrWhiteSpace(options.OutputNamespace)) - options.OutputNamespace = options.LibraryName; } public void Setup() @@ -194,6 +197,21 @@ namespace CppSharp options.addLibraryDirs(lib); } + foreach (var module in Options.Modules.Where(m => m.Headers.Contains(file.Path))) + { + foreach (var include in module.IncludeDirs) + options.addIncludeDirs(include); + + foreach (var define in module.Defines) + options.addDefines(define); + + foreach (var undefine in module.Undefines) + options.addUndefines(undefine); + + foreach (var library in module.Libraries) + options.addLibraryDirs(library); + } + return options; } @@ -213,7 +231,7 @@ namespace CppSharp public void BuildParseOptions() { - foreach (var header in Options.Headers) + foreach (var header in Options.Modules.SelectMany(m => m.Headers)) { var source = Project.AddFile(header); source.Options = BuildParseOptions(source); @@ -224,7 +242,7 @@ namespace CppSharp public bool ParseLibraries() { - foreach (var library in Options.Libraries) + foreach (var library in Options.Modules.SelectMany(m => m.Libraries)) { if (this.Symbols.Libraries.Any(l => l.FileName == library)) continue; @@ -248,7 +266,6 @@ namespace CppSharp public void SetupPasses(ILibrary library) { - TranslationUnitPasses.AddPass(new CleanUnitPass(Options)); TranslationUnitPasses.AddPass(new SortDeclarationsPass()); TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass()); TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass()); @@ -290,8 +307,8 @@ namespace CppSharp TranslationUnitPasses.AddPass(new GenerateAbstractImplementationsPass()); if (Options.GenerateDefaultValuesForArguments) { - TranslationUnitPasses.AddPass(new HandleDefaultParamValuesPass()); TranslationUnitPasses.AddPass(new FixDefaultParamValuesOfOverridesPass()); + TranslationUnitPasses.AddPass(new HandleDefaultParamValuesPass()); } } @@ -331,7 +348,7 @@ namespace CppSharp return Generator.Generate(); } - public void SaveCode(List outputs) + public void SaveCode(IEnumerable outputs) { var outputPath = Path.GetFullPath(Options.OutputDir); @@ -352,32 +369,22 @@ namespace CppSharp if (Options.GenerateName != null) fileBase = Options.GenerateName(output.TranslationUnit); - if (Options.IsCSharpGenerator && Options.CompileCode) - { - compileUnits.AddRange( - output.Templates.Select(t => new CodeSnippetCompileUnit(t.Generate()))); - compileUnits.AddRange( - Options.CodeFiles.Select(c => new CodeSnippetCompileUnit(File.ReadAllText(c)))); - } - else + foreach (var template in output.Templates) { - foreach (var template in output.Templates) - { - var fileRelativePath = string.Format("{0}.{1}", fileBase, template.FileExtension); - Diagnostics.Message("Generated '{0}'", fileRelativePath); - - var file = Path.Combine(outputPath, fileRelativePath); - File.WriteAllText(file, template.Generate()); - Options.CodeFiles.Add(file); - } + var fileRelativePath = string.Format("{0}.{1}", fileBase, template.FileExtension); + Diagnostics.Message("Generated '{0}'", fileRelativePath); + + var file = Path.Combine(outputPath, fileRelativePath); + File.WriteAllText(file, template.Generate()); + output.TranslationUnit.Module.CodeFiles.Add(file); } } } - public void CompileCode() + public void CompileCode(AST.Module module) { - var assemblyFile = string.IsNullOrEmpty(Options.LibraryName) ? - "out.dll" : Options.LibraryName + ".dll"; + var assemblyFile = string.IsNullOrEmpty(module.LibraryName) ? + "out.dll" : module.LibraryName + ".dll"; var docFile = Path.ChangeExtension(Path.GetFileName(assemblyFile), ".xml"); @@ -414,8 +421,8 @@ namespace CppSharp using (var codeProvider = new CSharpCodeProvider( new Dictionary { { "CompilerVersion", "v4.0" } })) { - compilerResults = codeProvider.CompileAssemblyFromDom( - compilerParameters, compileUnits.ToArray()); + compilerResults = codeProvider.CompileAssemblyFromFile( + compilerParameters, module.CodeFiles.ToArray()); } var errors = compilerResults.Errors.Cast().Where(e => !e.IsWarning && @@ -429,7 +436,7 @@ namespace CppSharp { Diagnostics.Message("Compilation succeeded."); var wrapper = Path.Combine(outputDir, assemblyFile); - foreach (var library in Options.Libraries) + foreach (var library in module.Libraries) libraryMappings[library] = wrapper; } } @@ -444,7 +451,6 @@ namespace CppSharp GeneratorOutputPasses.AddPass(pass); } - private readonly List compileUnits = new List(); private bool hasParsingErrors; } @@ -459,18 +465,6 @@ namespace CppSharp library.Setup(driver); - foreach (var includeDir in options.Module.IncludeDirs) - options.addIncludeDirs(includeDir); - - foreach (var libraryDir in options.Module.LibraryDirs) - options.addLibraryDirs(libraryDir); - - foreach (var define in options.Module.Defines) - options.addDefines(define); - - foreach (var undefine in options.Module.Undefines) - options.addUndefines(undefine); - driver.Setup(); if(driver.Options.Verbose) @@ -498,6 +492,8 @@ namespace CppSharp return; } + new CleanUnitPass(options).VisitLibrary(driver.ASTContext); + if (!options.Quiet) Log.Message("Processing code..."); @@ -526,7 +522,8 @@ namespace CppSharp { driver.SaveCode(outputs); if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode) - driver.CompileCode(); + foreach (var module in driver.Options.Modules) + driver.CompileCode(module); } driver.Generator.Dispose(); diff --git a/src/Generator/Generator.cs b/src/Generator/Generator.cs index a31f023a..0f090d65 100644 --- a/src/Generator/Generator.cs +++ b/src/Generator/Generator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using CppSharp.AST; @@ -35,6 +36,8 @@ namespace CppSharp.Generators /// public abstract class Generator : IDisposable { + public static string CurrentOutputNamespace = string.Empty; + public Driver Driver { get; private set; } protected Generator(Driver driver) @@ -69,50 +72,59 @@ namespace CppSharp.Generators var outputs = new List(); var units = Driver.ASTContext.TranslationUnits.Where( - u => u.IsGenerated && u.HasDeclarations && !u.IsSystemHeader && u.IsValid); + u => u.IsGenerated && u.HasDeclarations && !u.IsSystemHeader && u.IsValid).ToList(); if (Driver.Options.IsCSharpGenerator && Driver.Options.GenerateSingleCSharpFile) - GenerateSingleTemplate(units, outputs); + GenerateSingleTemplate(outputs); else - foreach (var unit in units) - GenerateTemplate(unit, outputs); + GenerateTemplates(outputs, units); return outputs; } - private void GenerateSingleTemplate(IEnumerable units, ICollection outputs) + private void GenerateTemplates(List outputs, List units) { - var output = new GeneratorOutput + foreach (var unit in units) { - TranslationUnit = new TranslationUnit + var includeDir = Path.GetDirectoryName(unit.FilePath); + var templates = Generate(new[] { unit }); + if (templates.Count == 0) + return; + + CurrentOutputNamespace = unit.Module.OutputNamespace; + foreach (var template in templates) { - FilePath = string.Format("{0}.cs", Driver.Options.OutputNamespace ?? Driver.Options.LibraryName) - }, - Templates = Generate(units) - }; - output.Templates[0].Process(); - outputs.Add(output); - - OnUnitGenerated(output); - } + template.Process(); + } - private void GenerateTemplate(TranslationUnit unit, ICollection outputs) - { - var templates = Generate(new[] { unit }); - if (templates.Count == 0) - return; + var output = new GeneratorOutput + { + TranslationUnit = unit, + Templates = templates + }; + outputs.Add(output); - foreach (var template in templates) - { - template.Process(); + OnUnitGenerated(output); } + } - var output = new GeneratorOutput + private void GenerateSingleTemplate(ICollection outputs) + { + foreach (var module in Driver.Options.Modules) { - TranslationUnit = unit, - Templates = templates - }; - outputs.Add(output); - - OnUnitGenerated(output); + CurrentOutputNamespace = module.OutputNamespace; + var output = new GeneratorOutput + { + TranslationUnit = new TranslationUnit + { + FilePath = string.Format("{0}.cs", module.OutputNamespace ?? module.LibraryName), + Module = module + }, + Templates = Generate(module.Units) + }; + output.Templates[0].Process(); + outputs.Add(output); + + OnUnitGenerated(output); + } } /// diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index ed739be7..9d7ce3f3 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -99,6 +99,7 @@ namespace CppSharp.Generators.CLI { // Create a new tree of namespaces out of the type references found. var rootNamespace = new TranslationUnit(); + rootNamespace.Module = TranslationUnit.Module; var sortedRefs = typeReferences.ToList(); sortedRefs.Sort((ref1, ref2) => @@ -192,7 +193,7 @@ namespace CppSharp.Generators.CLI { PushBlock(CLIBlockKind.Namespace, @namespace); WriteLine("namespace {0}", isTopLevel - ? Options.OutputNamespace + ? @namespace.TranslationUnit.Module.OutputNamespace : @namespace.Name); WriteStartBraceIndent(); } diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index b8bac876..92d8e37f 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -313,7 +313,7 @@ namespace CppSharp.Generators.CLI public string QualifiedIdentifier(Declaration decl) { if (Context.Driver.Options.GenerateLibraryNamespace) - return string.Format("{0}::{1}", Context.Driver.Options.OutputNamespace, + return string.Format("{0}::{1}", decl.TranslationUnit.Module.OutputNamespace, decl.QualifiedName); return string.Format("{0}", decl.QualifiedName); } diff --git a/src/Generator/Generators/CLI/CLITextTemplate.cs b/src/Generator/Generators/CLI/CLITextTemplate.cs index be7092d3..733c08b4 100644 --- a/src/Generator/Generators/CLI/CLITextTemplate.cs +++ b/src/Generator/Generators/CLI/CLITextTemplate.cs @@ -84,9 +84,10 @@ namespace CppSharp.Generators.CLI if (Options.GenerateLibraryNamespace) { if (string.IsNullOrEmpty(decl.QualifiedName)) - return string.Format("{0}", Options.OutputNamespace); + return string.Format("{0}", decl.TranslationUnit.Module.OutputNamespace); - return string.Format("{0}::{1}", Options.OutputNamespace, decl.QualifiedName); + return string.Format("{0}::{1}", + decl.TranslationUnit.Module.OutputNamespace, decl.QualifiedName); } return decl.QualifiedName; diff --git a/src/Generator/Generators/CLI/CLITypePrinter.cs b/src/Generator/Generators/CLI/CLITypePrinter.cs index 659ddeb6..326f7b07 100644 --- a/src/Generator/Generators/CLI/CLITypePrinter.cs +++ b/src/Generator/Generators/CLI/CLITypePrinter.cs @@ -327,7 +327,7 @@ namespace CppSharp.Generators.CLI string rootNamespace = null; if (Options.GenerateLibraryNamespace) - names.Add(rootNamespace = Driver.Options.OutputNamespace); + names.Add(rootNamespace = decl.TranslationUnit.Module.OutputNamespace); if (!string.IsNullOrEmpty(decl.Namespace.QualifiedName)) { diff --git a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs index 6609f528..bda589c6 100644 --- a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs @@ -40,7 +40,6 @@ namespace CppSharp.Generators.CSharp switch (callExpr.Declaration.GenerationKind) { case GenerationKind.Generate: - case GenerationKind.Link: return new CSharpExpressionPrinterResult { Value = string.Format("{0}.{1}({2})", diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 18e17d0e..bdf82841 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -167,7 +167,7 @@ namespace CppSharp.Generators.CSharp if (Options.GenerateLibraryNamespace) { PushBlock(CSharpBlockKind.Namespace); - WriteLine("namespace {0}", Driver.Options.OutputNamespace); + WriteLine("namespace {0}", TranslationUnit.Module.OutputNamespace); WriteStartBraceIndent(); } @@ -829,9 +829,9 @@ namespace CppSharp.Generators.CSharp #endregion - private Tuple GetDeclarationLibrarySymbol(IMangledDecl decl) + private Tuple GetDeclarationLibrarySymbol(Variable decl) { - var library = Options.SharedLibraryName; + var library = decl.TranslationUnit.Module.SharedLibraryName; if (!Options.CheckSymbols) goto Out; @@ -1555,8 +1555,9 @@ namespace CppSharp.Generators.CSharp return; } var typeFullName = TypePrinter.VisitClassDecl(@class); - if (!string.IsNullOrEmpty(Driver.Options.OutputNamespace)) - typeFullName = string.Format("{0}.{1}", Driver.Options.OutputNamespace, typeFullName); + if (!string.IsNullOrEmpty(@class.TranslationUnit.Module.OutputNamespace)) + typeFullName = string.Format("{0}.{1}", + @class.TranslationUnit.Module.OutputNamespace, typeFullName); WriteLine("SetupVTables(GetType().FullName == \"{0}\");", typeFullName); } } @@ -1573,7 +1574,7 @@ namespace CppSharp.Generators.CSharp for (int i = 0; i < method.Parameters.Count; i++) { var param = method.Parameters[i]; - if (!param.IsGenerated && param.GenerationKind != GenerationKind.Link) + if (!param.IsGenerated) continue; if (param.Kind == ParameterKind.IndirectReturnType) @@ -1600,7 +1601,7 @@ namespace CppSharp.Generators.CSharp if (hasReturn) Write("var {0} = ", Helpers.ReturnIdentifier); - if (method.IsGenerated || method.GenerationKind == GenerationKind.Link) + if (method.IsGenerated) { WriteLine("{0}.{1}({2});", Helpers.TargetIdentifier, method.Name, string.Join(", ", marshals)); @@ -1682,7 +1683,8 @@ namespace CppSharp.Generators.CSharp var vTableMethodDelegateName = GetVTableMethodDelegateName(method); - WriteLine("private static {0} {1}Instance;", GetDelegateName(Driver.Delegates[method]), + WriteLine("private static {0} {1}Instance;", + GetDelegateName(method, @class.TranslationUnit.Module.OutputNamespace), vTableMethodDelegateName); NewLine(); @@ -2483,13 +2485,15 @@ namespace CppSharp.Generators.CSharp delegateId = Generator.GeneratedIdentifier(@delegate); WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));", - delegateId, GetDelegateName(Driver.Delegates[method]), Helpers.SlotIdentifier); + delegateId, GetDelegateName(method, method.TranslationUnit.Module.OutputNamespace), + Helpers.SlotIdentifier); } - private string GetDelegateName(DelegatesPass.DelegateDefinition @delegate) + private string GetDelegateName(Function function, string outputNamespace) { + var @delegate = Driver.Delegates[function]; if (string.IsNullOrWhiteSpace(@delegate.Namespace) || - Driver.Options.OutputNamespace == @delegate.Namespace) + outputNamespace == @delegate.Namespace) { return @delegate.Signature; } @@ -3086,7 +3090,7 @@ namespace CppSharp.Generators.CSharp PushBlock(CSharpBlockKind.InternalsClassMethod); WriteLine("[SuppressUnmanagedCodeSecurity]"); - string libName = Options.SharedLibraryName; + string libName = function.TranslationUnit.Module.SharedLibraryName; if (Options.CheckSymbols) { @@ -3102,7 +3106,7 @@ namespace CppSharp.Generators.CSharp libName = libName.Substring(3); } if (libName == null) - libName = Options.SharedLibraryName; + libName = function.TranslationUnit.Module.SharedLibraryName; if (Options.GenerateInternalImports) libName = "__Internal"; diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index b9344b67..518ad779 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -631,7 +631,7 @@ namespace CppSharp.Generators.CSharp } names.Reverse(); - if (names[0] == driver.Options.OutputNamespace) + if (names[0] == Generator.CurrentOutputNamespace) names.RemoveAt(0); return string.Join(".", names); } diff --git a/src/Generator/Options.cs b/src/Generator/Options.cs index 9adf3672..613ed72a 100644 --- a/src/Generator/Options.cs +++ b/src/Generator/Options.cs @@ -27,7 +27,7 @@ namespace CppSharp OutputDir = Directory.GetCurrentDirectory(); - Module = new Module(); + Modules = new List(); GeneratorKind = GeneratorKind.CSharp; GenerateLibraryNamespace = true; @@ -39,8 +39,6 @@ namespace CppSharp Encoding = Encoding.ASCII; - CodeFiles = new List(); - StripLibPrefix = true; ExplicitlyPatchedVirtualFunctions = new List(); @@ -59,24 +57,34 @@ namespace CppSharp /// public bool DryRun; + public List Modules { get; private set; } + + public Module MainModule + { + get + { + if (Modules.Count == 0) + Modules.Add(new Module()); + return Modules[0]; + } + } + // Parser options - public List Headers { get { return Module.Headers; } } + public List Headers { get { return MainModule.Headers; } } public bool IgnoreParseWarnings; public bool IgnoreParseErrors; - public Module Module { get; set; } - public bool IsItaniumLikeAbi { get { return Abi != CppAbi.Microsoft; } } public bool IsMicrosoftAbi { get { return Abi == CppAbi.Microsoft; } } // Library options - public List Libraries { get { return Module.Libraries; } } + public List Libraries { get { return MainModule.Libraries; } } public bool CheckSymbols; public string SharedLibraryName { - get { return Module.SharedLibraryName; } - set { Module.SharedLibraryName = value; } + get { return MainModule.SharedLibraryName; } + set { MainModule.SharedLibraryName = value; } } // Generator options @@ -84,16 +92,16 @@ namespace CppSharp public string OutputNamespace { - get { return Module.OutputNamespace; } - set { Module.OutputNamespace = value; } + get { return MainModule.OutputNamespace; } + set { MainModule.OutputNamespace = value; } } public string OutputDir; public string LibraryName { - get { return Module.LibraryName; } - set { Module.LibraryName = value; } + get { return MainModule.LibraryName; } + set { MainModule.LibraryName = value; } } public bool OutputInteropIncludes; @@ -129,7 +137,7 @@ namespace CppSharp /// /// If set to true the CLI generator will use ObjectOverridesPass to create - /// Equals, GetHashCode and (if the insertion operator << is overloaded) ToString + /// Equals, GetHashCode and (if the insertion operator << is overloaded) ToString /// methods. /// public bool GenerateObjectOverrides; @@ -158,14 +166,14 @@ namespace CppSharp public string InlinesLibraryName { - get { return Module.InlinesLibraryName; } - set { Module.InlinesLibraryName = value; } + get { return MainModule.InlinesLibraryName; } + set { MainModule.InlinesLibraryName = value; } } public string TemplatesLibraryName { - get { return Module.TemplatesLibraryName; } - set { Module.TemplatesLibraryName = value; } + get { return MainModule.TemplatesLibraryName; } + set { MainModule.TemplatesLibraryName = value; } } public bool IsCSharpGenerator @@ -178,7 +186,6 @@ namespace CppSharp get { return GeneratorKind == GeneratorKind.CLI; } } - public List CodeFiles { get; private set; } public readonly List DependentNameSpaces = new List(); public bool MarshalCharAsManagedChar { get; set; } /// @@ -201,5 +208,9 @@ namespace CppSharp public class InvalidOptionException : Exception { + public InvalidOptionException(string message) : + base(message) + { + } } } diff --git a/src/Generator/Passes/CleanUnitPass.cs b/src/Generator/Passes/CleanUnitPass.cs index e13c6257..ca0b4ac3 100644 --- a/src/Generator/Passes/CleanUnitPass.cs +++ b/src/Generator/Passes/CleanUnitPass.cs @@ -1,3 +1,6 @@ +using System; +using System.IO; +using System.Linq; using CppSharp.AST; namespace CppSharp.Passes @@ -13,9 +16,14 @@ namespace CppSharp.Passes public override bool VisitTranslationUnit(TranslationUnit unit) { - if (IsExternalDeclaration(unit) && unit.IsGenerated) - unit.GenerationKind = GenerationKind.Link; - + if (unit.IsValid && !unit.IsSystemHeader && unit.HasDeclarations) + { + var includeDir = Path.GetDirectoryName(unit.FilePath); + unit.Module = DriverOptions.Modules.FirstOrDefault( + m => m.IncludeDirs.Contains(includeDir)) ?? DriverOptions.MainModule; + unit.Module.Units.Add(unit); + } + // Try to get an include path that works from the original include // directories paths. if (unit.IsValid) @@ -64,7 +72,7 @@ namespace CppSharp.Passes foreach (var path in DriverOptions.NoGenIncludeDirs) { - if (translationUnit.FilePath.StartsWith(path)) + if (translationUnit.FilePath.StartsWith(path, StringComparison.Ordinal)) return true; } diff --git a/src/Generator/Passes/DelegatesPass.cs b/src/Generator/Passes/DelegatesPass.cs index e829a48f..1a9a4862 100644 --- a/src/Generator/Passes/DelegatesPass.cs +++ b/src/Generator/Passes/DelegatesPass.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Text; using CppSharp.AST; using CppSharp.AST.Extensions; +using CppSharp.Generators; using CppSharp.Generators.CSharp; -using System; namespace CppSharp.Passes { @@ -37,8 +37,8 @@ namespace CppSharp.Passes public override bool VisitLibrary(ASTContext context) { - foreach (var library in Driver.Options.Libraries.Where(l => !libsDelegates.ContainsKey(l))) - libsDelegates.Add(library, new Dictionary()); + foreach (var library in Driver.Options.Modules.SelectMany(m => m.Libraries)) + libsDelegates[library] = new Dictionary(); var unit = context.TranslationUnits.LastOrDefault(u => u.IsValid && u.IsGenerated && !u.IsSystemHeader && u.HasDeclarations); @@ -46,12 +46,10 @@ namespace CppSharp.Passes if (unit == null) return false; - namespaceDelegates = new Namespace { Name = DelegatesNamespace, Namespace = unit }; - var result = base.VisitLibrary(context); - if (namespaceDelegates.Declarations.Count > 0) - unit.Declarations.Add(namespaceDelegates); + foreach (var module in Driver.Options.Modules.Where(m => namespacesDelegates.ContainsKey(m))) + module.Units.Last().Declarations.Add(namespacesDelegates[module]); return result; } @@ -94,6 +92,21 @@ namespace CppSharp.Passes var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); + Namespace namespaceDelegates; + if (namespacesDelegates.ContainsKey(method.TranslationUnit.Module)) + { + namespaceDelegates = namespacesDelegates[method.TranslationUnit.Module]; + } + else + { + namespaceDelegates = new Namespace + { + Name = DelegatesNamespace, + Namespace = method.TranslationUnit.Module.Units.Last() + }; + namespacesDelegates.Add(method.TranslationUnit.Module, namespaceDelegates); + } + var @delegate = new TypedefDecl { Name = delegateName, @@ -110,17 +123,20 @@ namespace CppSharp.Passes Namespace = namespaceDelegates }; + Generator.CurrentOutputNamespace = method.TranslationUnit.Module.OutputNamespace; var delegateString = @delegate.Visit(TypePrinter).Type; - var existingDelegate = GetExistingDelegate(delegateString); + var existingDelegate = GetExistingDelegate( + method.TranslationUnit.Module.Libraries, delegateString); if (existingDelegate != null) { Driver.Delegates.Add(method, existingDelegate); return true; } - existingDelegate = new DelegateDefinition(Driver.Options.OutputNamespace, delegateString); + existingDelegate = new DelegateDefinition( + method.TranslationUnit.Module.OutputNamespace, delegateString); Driver.Delegates.Add(method, existingDelegate); - foreach (var library in Driver.Options.Libraries) + foreach (var library in method.TranslationUnit.Module.Libraries) libsDelegates[library].Add(delegateString, existingDelegate); namespaceDelegates.Declarations.Add(@delegate); @@ -128,16 +144,16 @@ namespace CppSharp.Passes return true; } - private DelegateDefinition GetExistingDelegate(string delegateString) + private DelegateDefinition GetExistingDelegate(IList libraries, string delegateString) { - if (Driver.Options.Libraries.Count == 0) + if (libraries.Count == 0) return Driver.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString); DelegateDefinition @delegate = null; - if (Driver.Options.Libraries.Union( - Driver.Symbols.Libraries.SelectMany(l => l.Dependencies)).Any( - l => libsDelegates.ContainsKey(l) && - libsDelegates[l].TryGetValue(delegateString, out @delegate))) + if (libraries.Union( + Driver.Symbols.Libraries.Where(l => libraries.Contains(l.FileName)).SelectMany( + l => l.Dependencies)).Any(l => libsDelegates.ContainsKey(l) && + libsDelegates[l].TryGetValue(delegateString, out @delegate))) return @delegate; return null; @@ -183,7 +199,7 @@ namespace CppSharp.Passes } } - private Namespace namespaceDelegates; + private Dictionary namespacesDelegates = new Dictionary(); private CSharpTypePrinter typePrinter; private static readonly Dictionary> libsDelegates = new Dictionary>(); diff --git a/src/Generator/Passes/FixDefaultParamValuesOfOverridesPass.cs b/src/Generator/Passes/FixDefaultParamValuesOfOverridesPass.cs index 7123b840..f6a4d090 100644 --- a/src/Generator/Passes/FixDefaultParamValuesOfOverridesPass.cs +++ b/src/Generator/Passes/FixDefaultParamValuesOfOverridesPass.cs @@ -11,7 +11,11 @@ namespace CppSharp.Passes Method rootBaseMethod = ((Class) method.Namespace).GetBaseMethod(method); for (int i = 0; i < method.Parameters.Count; i++) { - method.Parameters[i].DefaultArgument = rootBaseMethod.Parameters[i].DefaultArgument; + if (rootBaseMethod.Parameters[i].DefaultArgument != null) + { + method.Parameters[i].DefaultArgument = + rootBaseMethod.Parameters[i].DefaultArgument.Clone(); + } } } return base.VisitMethodDecl(method); diff --git a/src/Generator/Passes/GenerateInlinesCodePass.cs b/src/Generator/Passes/GenerateInlinesCodePass.cs index da5dbe44..2c8bfe13 100644 --- a/src/Generator/Passes/GenerateInlinesCodePass.cs +++ b/src/Generator/Passes/GenerateInlinesCodePass.cs @@ -14,13 +14,16 @@ namespace CppSharp.Passes private void WriteInlinesIncludes() { - var cppBuilder = new StringBuilder(); - foreach (var header in Driver.Options.Headers) - cppBuilder.AppendFormat("#include <{0}>\n", header); - var cpp = string.Format("{0}.cpp", Driver.Options.InlinesLibraryName); - Directory.CreateDirectory(Driver.Options.OutputDir); - var path = Path.Combine(Driver.Options.OutputDir, cpp); - File.WriteAllText(path, cppBuilder.ToString()); + foreach (var module in Driver.Options.Modules) + { + var cppBuilder = new StringBuilder(); + foreach (var header in module.Headers) + cppBuilder.AppendFormat("#include <{0}>\n", header); + var cpp = string.Format("{0}.cpp", module.InlinesLibraryName); + Directory.CreateDirectory(Driver.Options.OutputDir); + var path = Path.Combine(Driver.Options.OutputDir, cpp); + File.WriteAllText(path, cppBuilder.ToString()); + } } } } diff --git a/src/Generator/Passes/GenerateTemplatesCodePass.cs b/src/Generator/Passes/GenerateTemplatesCodePass.cs index c1548526..2e0287e3 100644 --- a/src/Generator/Passes/GenerateTemplatesCodePass.cs +++ b/src/Generator/Passes/GenerateTemplatesCodePass.cs @@ -34,15 +34,18 @@ namespace CppSharp.Passes private void WriteTemplateInstantiations() { - var cppBuilder = new StringBuilder(); - foreach (var header in Driver.Options.Headers) - cppBuilder.AppendFormat("#include <{0}>\n", header); - foreach (var templateInstantiation in templateInstantiations) - cppBuilder.AppendFormat("\ntemplate class {0};", templateInstantiation); - var cpp = string.Format("{0}.cpp", Driver.Options.TemplatesLibraryName); - Directory.CreateDirectory(Driver.Options.OutputDir); - var path = Path.Combine(Driver.Options.OutputDir, cpp); - File.WriteAllText(path, cppBuilder.ToString()); + foreach (var module in Driver.Options.Modules) + { + var cppBuilder = new StringBuilder(); + foreach (var header in module.Headers) + cppBuilder.AppendFormat("#include <{0}>\n", header); + foreach (var templateInstantiation in templateInstantiations) + cppBuilder.AppendFormat("\ntemplate class {0};", templateInstantiation); + var cpp = string.Format("{0}.cpp", module.TemplatesLibraryName); + Directory.CreateDirectory(Driver.Options.OutputDir); + var path = Path.Combine(Driver.Options.OutputDir, cpp); + File.WriteAllText(path, cppBuilder.ToString()); + } } private HashSet templateInstantiations = new HashSet(); diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index a82148a0..8fac269b 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -25,8 +25,7 @@ namespace CppSharp.Passes { this.log = log; foreach (var method in @class.Methods.Where( - m => !m.IsConstructor && !m.IsDestructor && !m.IsOperator && - (m.IsGenerated || m.GenerationKind == GenerationKind.Link))) + m => !m.IsConstructor && !m.IsDestructor && !m.IsOperator && m.IsGenerated)) DistributeMethod(method); } @@ -37,7 +36,7 @@ namespace CppSharp.Passes foreach (Method getter in from getter in getters - where (getter.IsGenerated || getter.GenerationKind == GenerationKind.Link) && + where getter.IsGenerated && ((Class) getter.Namespace).Methods.All(m => m == getter || !m.IsGenerated || m.Name != getter.Name) select getter) { diff --git a/src/Generator/Passes/HandleDefaultParamValuesPass.cs b/src/Generator/Passes/HandleDefaultParamValuesPass.cs index 40d51cf7..e1462d1f 100644 --- a/src/Generator/Passes/HandleDefaultParamValuesPass.cs +++ b/src/Generator/Passes/HandleDefaultParamValuesPass.cs @@ -37,9 +37,10 @@ namespace CppSharp.Passes public override bool VisitFunctionDecl(Function function) { - if (!base.VisitFunctionDecl(function)) + if (!base.VisitFunctionDecl(function) || function.TranslationUnit.IsSystemHeader) return false; + Generator.CurrentOutputNamespace = function.TranslationUnit.Module.OutputNamespace; var overloadIndices = new List(function.Parameters.Count); foreach (var parameter in function.Parameters.Where(p => p.DefaultArgument != null)) { @@ -199,14 +200,14 @@ namespace CppSharp.Passes switch (builtin.Type) { case PrimitiveType.Float: - if (statement.String.EndsWith(".F")) + if (statement.String.EndsWith(".F", System.StringComparison.Ordinal)) { result = statement.String.Replace(".F", ".0F"); return true; } break; case PrimitiveType.Double: - if (statement.String.EndsWith(".")) + if (statement.String.EndsWith(".", System.StringComparison.Ordinal)) { result = statement.String + '0'; return true; diff --git a/src/Generator/Passes/MoveFunctionToClassPass.cs b/src/Generator/Passes/MoveFunctionToClassPass.cs index 2949beb6..2b96cdac 100644 --- a/src/Generator/Passes/MoveFunctionToClassPass.cs +++ b/src/Generator/Passes/MoveFunctionToClassPass.cs @@ -17,7 +17,7 @@ namespace CppSharp.Passes return false; var @class = FindClassToMoveFunctionTo(function.Namespace); - if (@class != null) + if (@class != null && @class.TranslationUnit.Module == function.TranslationUnit.Module) { MoveFunction(function, @class); Log.Debug("Function moved to class: {0}::{1}", @class.Name, function.Name); diff --git a/src/Generator/Passes/MoveOperatorToClassPass.cs b/src/Generator/Passes/MoveOperatorToClassPass.cs index 252658ef..9fc0496e 100644 --- a/src/Generator/Passes/MoveOperatorToClassPass.cs +++ b/src/Generator/Passes/MoveOperatorToClassPass.cs @@ -18,13 +18,12 @@ namespace CppSharp.Passes Class @class = null; foreach (var param in function.Parameters) { - FunctionToInstanceMethodPass.GetClassParameter( - param, out @class); - - if (@class != null) break; + if (FunctionToInstanceMethodPass.GetClassParameter(param, out @class)) + break; } - if (@class == null) + if (@class == null || + @class.TranslationUnit.Module != function.TranslationUnit.Module) return false; // Create a new fake method so it acts as a static method. diff --git a/src/Generator/Passes/RenameRootNamespaces.cs b/src/Generator/Passes/RenameRootNamespaces.cs index 1643807c..e98eb075 100644 --- a/src/Generator/Passes/RenameRootNamespaces.cs +++ b/src/Generator/Passes/RenameRootNamespaces.cs @@ -11,21 +11,21 @@ namespace CppSharp.Passes { public override bool VisitTranslationUnit(TranslationUnit unit) { - if (!base.VisitTranslationUnit(unit)) + if (!base.VisitTranslationUnit(unit) || !unit.IsValid || + unit.IsSystemHeader || !unit.HasDeclarations) return false; var fileName = unit.TranslationUnit.FileName; if (rootNamespaceRenames.ContainsKey(fileName)) { var rootNamespace = rootNamespaceRenames[fileName]; - if (this.Driver.Options.OutputNamespace != rootNamespace) - unit.Name = rootNamespace; + unit.Name = rootNamespace; } else if (unit.GenerationKind == GenerationKind.Generate) { if (Driver.Options.IsCSharpGenerator) - unit.Name = Driver.Options.OutputNamespace; - rootNamespaceRenames.Add(fileName, Driver.Options.OutputNamespace); + unit.Name = unit.Module.OutputNamespace; + rootNamespaceRenames.Add(fileName, unit.Module.OutputNamespace); } return true; } diff --git a/src/Generator/Types/Types.cs b/src/Generator/Types/Types.cs index 1000198d..fbb9a86c 100644 --- a/src/Generator/Types/Types.cs +++ b/src/Generator/Types/Types.cs @@ -32,7 +32,8 @@ namespace CppSharp if (decl.CompleteDeclaration != null) return VisitDeclaration(decl.CompleteDeclaration); - if (decl.GenerationKind == GenerationKind.None) + if (!(decl is TypedefDecl) && (!decl.IsGenerated || + (decl is Class && decl.TranslationUnit.IsSystemHeader))) { Ignore(); return false; diff --git a/tests/NamespacesDerived/NamespacesDerived.cs b/tests/NamespacesDerived/NamespacesDerived.cs index 64869802..57ddf6db 100644 --- a/tests/NamespacesDerived/NamespacesDerived.cs +++ b/tests/NamespacesDerived/NamespacesDerived.cs @@ -19,17 +19,6 @@ namespace CppSharp.Tests driver.Options.GeneratePropertiesAdvanced = true; } - public override void Preprocess(Driver driver, ASTContext ctx) - { - foreach (TranslationUnit unit in ctx.TranslationUnits) - { - if (unit.FileName != "NamespacesDerived.h") - { - unit.GenerationKind = GenerationKind.Link; - } - } - } - public override void Postprocess(Driver driver, ASTContext ctx) { new CaseRenamePass(