diff --git a/src/Generator/Options.cs b/src/Generator/Options.cs index ecfa20efc4..33ac5ecbdb 100644 --- a/src/Generator/Options.cs +++ b/src/Generator/Options.cs @@ -92,6 +92,13 @@ public Module AddModule(string libraryName) public bool OutputInteropIncludes; public bool GenerateFunctionTemplates; + /// + /// C# only: gets or sets a value indicating whether to generate class templates. + /// + /// + /// true to generate class templates; otherwise, false. + /// + public bool GenerateClassTemplates { get; set; } = false; public bool GenerateInternalImports; public bool GenerateSequentialLayout { get; set; } public bool UseHeaderDirectories; diff --git a/src/Generator/Passes/CheckIgnoredDecls.cs b/src/Generator/Passes/CheckIgnoredDecls.cs index 2773acd359..aa27c3f928 100644 --- a/src/Generator/Passes/CheckIgnoredDecls.cs +++ b/src/Generator/Passes/CheckIgnoredDecls.cs @@ -39,18 +39,12 @@ public override bool VisitClassDecl(Class @class) if (!@class.IsDependent) return false; - if (Options.IsCLIGenerator || @class.TranslationUnit.IsSystemHeader || - @class.Specializations.Count == 0) - { - bool hasExplicitlyGeneratedSpecializations = false; - foreach (var specialization in @class.Specializations) - if (specialization.IsExplicitlyGenerated) - hasExplicitlyGeneratedSpecializations = true; - else - specialization.ExplicitlyIgnore(); - if (!hasExplicitlyGeneratedSpecializations) - @class.ExplicitlyIgnore(); - } + if (Options.GenerateClassTemplates) + IgnoreUnsupportedTemplates(@class); + else + foreach (var specialization in @class.Specializations.Where( + s => !s.IsExplicitlyGenerated)) + specialization.ExplicitlyIgnore(); return true; } @@ -350,11 +344,11 @@ public override bool VisitASTContext(ASTContext c) #region Helpers - /// + /// /// Checks if a given type is invalid, which can happen for a number of /// reasons: incomplete definitions, being explicitly ignored, or also /// by being a type we do not know how to handle. - /// + /// private bool HasInvalidType(Type type, Module module, out string msg) { if (type == null) @@ -459,6 +453,22 @@ private bool IsDeclIgnored(Declaration decl) return TypeMaps.FindTypeMap(decl, out typeMap) ? typeMap.IsIgnored : decl.Ignore; } + private void IgnoreUnsupportedTemplates(Class @class) + { + if (!Options.IsCLIGenerator && !@class.TranslationUnit.IsSystemHeader && + @class.Specializations.Count > 0) + return; + + bool hasExplicitlyGeneratedSpecializations = false; + foreach (var specialization in @class.Specializations) + if (specialization.IsExplicitlyGenerated) + hasExplicitlyGeneratedSpecializations = true; + else + specialization.ExplicitlyIgnore(); + if (!hasExplicitlyGeneratedSpecializations) + @class.ExplicitlyIgnore(); + } + #endregion private HashSet injectedClasses = new HashSet(); diff --git a/src/Generator/Passes/ConstructorToConversionOperatorPass.cs b/src/Generator/Passes/ConstructorToConversionOperatorPass.cs index e099771b94..75ae6c32ae 100644 --- a/src/Generator/Passes/ConstructorToConversionOperatorPass.cs +++ b/src/Generator/Passes/ConstructorToConversionOperatorPass.cs @@ -26,7 +26,8 @@ public override bool VisitMethodDecl(Method method) { var nonDefaultParams = @params.Count(p => p.DefaultArgument == null || (p.DefaultArgument.Class == StatementClass.Call && - p.DefaultArgument.Declaration.Ignore)); + (p.DefaultArgument.Declaration == null || + p.DefaultArgument.Declaration.Ignore))); if (nonDefaultParams > 1) return false; } diff --git a/tests/CSharp/CSharp.cs b/tests/CSharp/CSharp.cs index 6f62ee5e16..d8f92ec66a 100644 --- a/tests/CSharp/CSharp.cs +++ b/tests/CSharp/CSharp.cs @@ -26,6 +26,7 @@ public override void SetupPasses(Driver driver) driver.Context.TranslationUnitPasses.AddPass(new TestAttributesPass()); driver.Options.MarshalCharAsManagedChar = true; driver.Options.GenerateDefaultValuesForArguments = true; + driver.Options.GenerateClassTemplates = true; } public override void Preprocess(Driver driver, ASTContext ctx)