Browse Source

Fixed the generated C# for members of types nested in templates.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1026/head
Dimitar Dobrev 8 years ago
parent
commit
fceb204a98
  1. 29
      src/AST/ClassExtensions.cs
  2. 2
      src/CLI/Generator.cs
  3. 18
      src/CppParser/AST.cpp
  4. 6
      src/CppParser/AST.h
  5. 10
      src/CppParser/Bindings/CLI/CppParser.cpp
  6. 6
      src/CppParser/Bindings/CLI/CppParser.h
  7. 18
      src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs
  8. 18
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
  9. 18
      src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs
  10. 18
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs
  11. 18
      src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs
  12. 18
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
  13. 1
      src/CppParser/CppParser.cpp
  14. 1
      src/CppParser/CppParser.h
  15. 6
      src/CppParser/Parser.cpp
  16. 2
      src/CppParser/ParserGen/ParserGen.cs
  17. 2
      src/Generator/Driver.cs
  18. 15
      src/Generator/Generators/CSharp/CSharpSources.cs
  19. 5
      src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs
  20. 11
      src/Generator/Options.cs
  21. 36
      src/Generator/Passes/ResolveIncompleteDeclsPass.cs
  22. 3
      src/Generator/Passes/TrimSpecializationsPass.cs
  23. 3
      src/Parser/ParserOptions.cs
  24. 2
      tests/CSharp/AnotherUnit.h
  25. 7
      tests/CSharp/CSharp.cs
  26. 2
      tests/Common/Common.cs

29
src/AST/ClassExtensions.cs

@ -148,21 +148,36 @@ namespace CppSharp.AST @@ -148,21 +148,36 @@ namespace CppSharp.AST
return units.Where(u => u.IsGenerated && (u.HasDeclarations || u.IsSystemHeader) && u.IsValid);
}
public static List<ClassTemplateSpecialization> GetSpecializationsToGenerate(
this Class classTemplate)
public static IEnumerable<Class> GetSpecializedClassesToGenerate(
this Class dependentClass)
{
if (classTemplate.HasDependentValueFieldInLayout())
return classTemplate.Specializations;
IEnumerable<Class> specializedClasses = GetSpecializedClassesOf(dependentClass);
if (!specializedClasses.Any() || dependentClass.HasDependentValueFieldInLayout())
return specializedClasses;
var specializations = new List<ClassTemplateSpecialization>();
var specialization = classTemplate.Specializations.FirstOrDefault(s => !s.Ignore);
var specializations = new List<Class>();
var specialization = specializedClasses.FirstOrDefault(s => s.IsGenerated);
if (specialization == null)
specializations.Add(classTemplate.Specializations[0]);
specializations.Add(specializedClasses.First());
else
specializations.Add(specialization);
return specializations;
}
private static IEnumerable<Class> GetSpecializedClassesOf(this Class dependentClass)
{
if (dependentClass.IsTemplate)
return dependentClass.Specializations;
Class template = dependentClass.Namespace as Class;
if (template == null || !template.IsTemplate)
// just one level of nesting supported for the time being
return Enumerable.Empty<Class>();
return template.Specializations.SelectMany(s => s.Classes.Where(
c => c.Name == dependentClass.Name)).ToList();
}
public static bool HasDependentValueFieldInLayout(this Class @class)
{
if (@class.Fields.Any(f => IsValueDependent(f.Type)))

2
src/CLI/Generator.cs

@ -189,7 +189,7 @@ namespace CppSharp @@ -189,7 +189,7 @@ namespace CppSharp
driverOptions.CompileCode = options.Compile;
driverOptions.OutputDir = options.OutputDir;
driverOptions.CheckSymbols = options.CheckSymbols;
driverOptions.UnityBuild = options.UnityBuild;
parserOptions.UnityBuild = options.UnityBuild;
driverOptions.Verbose = options.Verbose;
}

18
src/CppParser/AST.cpp

@ -350,7 +350,8 @@ Namespace* DeclarationContext::FindCreateNamespace(const std::string& Name) @@ -350,7 +350,8 @@ Namespace* DeclarationContext::FindCreateNamespace(const std::string& Name)
return _namespace;
}
Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete)
Class* DeclarationContext::FindClass(const void* OriginalPtr,
const std::string& Name, bool IsComplete)
{
if (Name.empty()) return nullptr;
@ -359,8 +360,9 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete) @@ -359,8 +360,9 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete)
if (entries.size() == 1)
{
auto _class = std::find_if(Classes.begin(), Classes.end(),
[&](Class* klass) { return klass->name == Name &&
(klass->isIncomplete == !IsComplete); });
[OriginalPtr, Name, IsComplete](Class* klass) {
return (OriginalPtr && klass->originalPtr == OriginalPtr) ||
(klass->name == Name && klass->isIncomplete == !IsComplete); });
return _class != Classes.end() ? *_class : nullptr;
}
@ -374,10 +376,10 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete) @@ -374,10 +376,10 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete)
if (!_namespace)
return nullptr;
return _namespace->FindClass(className, IsComplete);
return _namespace->FindClass(OriginalPtr, className, IsComplete);
}
Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete)
Class* DeclarationContext::CreateClass(const std::string& Name, bool IsComplete)
{
auto _class = new Class();
_class->name = Name;
@ -387,10 +389,10 @@ Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete) @@ -387,10 +389,10 @@ Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete)
return _class;
}
Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete,
bool Create)
Class* DeclarationContext::FindClass(const void* OriginalPtr,
const std::string& Name, bool IsComplete, bool Create)
{
auto _class = FindClass(Name, IsComplete);
auto _class = FindClass(OriginalPtr, Name, IsComplete);
if (!_class)
{

6
src/CppParser/AST.h

@ -516,9 +516,9 @@ public: @@ -516,9 +516,9 @@ public:
CS_IGNORE Namespace* FindNamespace(const std::vector<std::string>&);
CS_IGNORE Namespace* FindCreateNamespace(const std::string& Name);
CS_IGNORE Class* CreateClass(std::string Name, bool IsComplete);
CS_IGNORE Class* FindClass(const std::string& Name, bool IsComplete);
CS_IGNORE Class* FindClass(const std::string& Name, bool IsComplete,
CS_IGNORE Class* CreateClass(const std::string& Name, bool IsComplete);
CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete);
CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete,
bool Create);
CS_IGNORE template<typename T> T* FindTemplate(const std::string& USR);

10
src/CppParser/Bindings/CLI/CppParser.cpp

@ -480,6 +480,16 @@ void CppSharp::Parser::CppParserOptions::Verbose::set(bool value) @@ -480,6 +480,16 @@ void CppSharp::Parser::CppParserOptions::Verbose::set(bool value)
((::CppSharp::CppParser::CppParserOptions*)NativePtr)->verbose = value;
}
bool CppSharp::Parser::CppParserOptions::UnityBuild::get()
{
return ((::CppSharp::CppParser::CppParserOptions*)NativePtr)->unityBuild;
}
void CppSharp::Parser::CppParserOptions::UnityBuild::set(bool value)
{
((::CppSharp::CppParser::CppParserOptions*)NativePtr)->unityBuild = value;
}
unsigned int CppSharp::Parser::CppParserOptions::ArgumentsCount::get()
{
auto __ret = ((::CppSharp::CppParser::CppParserOptions*)NativePtr)->getArgumentsCount();

6
src/CppParser/Bindings/CLI/CppParser.h

@ -187,6 +187,12 @@ namespace CppSharp @@ -187,6 +187,12 @@ namespace CppSharp
void set(bool);
}
property bool UnityBuild
{
bool get();
void set(bool);
}
property unsigned int ArgumentsCount
{
unsigned int get();

18
src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs

@ -18051,7 +18051,7 @@ namespace CppSharp @@ -18051,7 +18051,7 @@ namespace CppSharp
public unsafe partial class CppParserOptions : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 148)]
[StructLayout(LayoutKind.Explicit, Size = 152)]
public partial struct __Internal
{
[FieldOffset(0)]
@ -18108,6 +18108,9 @@ namespace CppSharp @@ -18108,6 +18108,9 @@ namespace CppSharp
[FieldOffset(147)]
internal byte verbose;
[FieldOffset(148)]
internal byte unityBuild;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser16CppParserOptionsC2Ev")]
@ -18638,6 +18641,19 @@ namespace CppSharp @@ -18638,6 +18641,19 @@ namespace CppSharp
}
}
public bool UnityBuild
{
get
{
return ((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild != 0;
}
set
{
((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild = (byte) (value ? 1 : 0);
}
}
public uint ArgumentsCount
{
get

18
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs

@ -18051,7 +18051,7 @@ namespace CppSharp @@ -18051,7 +18051,7 @@ namespace CppSharp
public unsafe partial class CppParserOptions : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 184)]
[StructLayout(LayoutKind.Explicit, Size = 188)]
public partial struct __Internal
{
[FieldOffset(0)]
@ -18108,6 +18108,9 @@ namespace CppSharp @@ -18108,6 +18108,9 @@ namespace CppSharp
[FieldOffset(183)]
internal byte verbose;
[FieldOffset(184)]
internal byte unityBuild;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
EntryPoint="??0CppParserOptions@CppParser@CppSharp@@QAE@XZ")]
@ -18638,6 +18641,19 @@ namespace CppSharp @@ -18638,6 +18641,19 @@ namespace CppSharp
}
}
public bool UnityBuild
{
get
{
return ((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild != 0;
}
set
{
((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild = (byte) (value ? 1 : 0);
}
}
public uint ArgumentsCount
{
get

18
src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs

@ -18050,7 +18050,7 @@ namespace CppSharp @@ -18050,7 +18050,7 @@ namespace CppSharp
public unsafe partial class CppParserOptions : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 288)]
[StructLayout(LayoutKind.Explicit, Size = 296)]
public partial struct __Internal
{
[FieldOffset(0)]
@ -18107,6 +18107,9 @@ namespace CppSharp @@ -18107,6 +18107,9 @@ namespace CppSharp
[FieldOffset(287)]
internal byte verbose;
[FieldOffset(288)]
internal byte unityBuild;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser16CppParserOptionsC2Ev")]
@ -18637,6 +18640,19 @@ namespace CppSharp @@ -18637,6 +18640,19 @@ namespace CppSharp
}
}
public bool UnityBuild
{
get
{
return ((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild != 0;
}
set
{
((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild = (byte) (value ? 1 : 0);
}
}
public uint ArgumentsCount
{
get

18
src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs

@ -18050,7 +18050,7 @@ namespace CppSharp @@ -18050,7 +18050,7 @@ namespace CppSharp
public unsafe partial class CppParserOptions : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 312)]
[StructLayout(LayoutKind.Explicit, Size = 320)]
public partial struct __Internal
{
[FieldOffset(0)]
@ -18107,6 +18107,9 @@ namespace CppSharp @@ -18107,6 +18107,9 @@ namespace CppSharp
[FieldOffset(311)]
internal byte verbose;
[FieldOffset(312)]
internal byte unityBuild;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser16CppParserOptionsC2Ev")]
@ -18637,6 +18640,19 @@ namespace CppSharp @@ -18637,6 +18640,19 @@ namespace CppSharp
}
}
public bool UnityBuild
{
get
{
return ((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild != 0;
}
set
{
((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild = (byte) (value ? 1 : 0);
}
}
public uint ArgumentsCount
{
get

18
src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs

@ -18050,7 +18050,7 @@ namespace CppSharp @@ -18050,7 +18050,7 @@ namespace CppSharp
public unsafe partial class CppParserOptions : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 240)]
[StructLayout(LayoutKind.Explicit, Size = 248)]
public partial struct __Internal
{
[FieldOffset(0)]
@ -18107,6 +18107,9 @@ namespace CppSharp @@ -18107,6 +18107,9 @@ namespace CppSharp
[FieldOffset(239)]
internal byte verbose;
[FieldOffset(240)]
internal byte unityBuild;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="_ZN8CppSharp9CppParser16CppParserOptionsC2Ev")]
@ -18637,6 +18640,19 @@ namespace CppSharp @@ -18637,6 +18640,19 @@ namespace CppSharp
}
}
public bool UnityBuild
{
get
{
return ((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild != 0;
}
set
{
((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild = (byte) (value ? 1 : 0);
}
}
public uint ArgumentsCount
{
get

18
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs

@ -18051,7 +18051,7 @@ namespace CppSharp @@ -18051,7 +18051,7 @@ namespace CppSharp
public unsafe partial class CppParserOptions : IDisposable
{
[StructLayout(LayoutKind.Explicit, Size = 312)]
[StructLayout(LayoutKind.Explicit, Size = 320)]
public partial struct __Internal
{
[FieldOffset(0)]
@ -18108,6 +18108,9 @@ namespace CppSharp @@ -18108,6 +18108,9 @@ namespace CppSharp
[FieldOffset(311)]
internal byte verbose;
[FieldOffset(312)]
internal byte unityBuild;
[SuppressUnmanagedCodeSecurity]
[DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
EntryPoint="??0CppParserOptions@CppParser@CppSharp@@QEAA@XZ")]
@ -18638,6 +18641,19 @@ namespace CppSharp @@ -18638,6 +18641,19 @@ namespace CppSharp
}
}
public bool UnityBuild
{
get
{
return ((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild != 0;
}
set
{
((global::CppSharp.Parser.CppParserOptions.__Internal*) __Instance)->unityBuild = (byte) (value ? 1 : 0);
}
}
public uint ArgumentsCount
{
get

1
src/CppParser/CppParser.cpp

@ -18,6 +18,7 @@ CppParserOptions::CppParserOptions() @@ -18,6 +18,7 @@ CppParserOptions::CppParserOptions()
, noBuiltinIncludes(false)
, microsoftMode(false)
, verbose(false)
, unityBuild(false)
{
}

1
src/CppParser/CppParser.h

@ -44,6 +44,7 @@ struct CS_API CppParserOptions @@ -44,6 +44,7 @@ struct CS_API CppParserOptions
bool noBuiltinIncludes;
bool microsoftMode;
bool verbose;
bool unityBuild;
};
enum class ParserDiagnosticLevel

6
src/CppParser/Parser.cpp

@ -766,13 +766,15 @@ Class* Parser::GetRecord(const clang::RecordDecl* Record, bool& Process) @@ -766,13 +766,15 @@ Class* Parser::GetRecord(const clang::RecordDecl* Record, bool& Process)
}
else
{
RC = NS->FindClass(Name, isCompleteDefinition, /*Create=*/false);
RC = NS->FindClass(opts->unityBuild ? Record : 0, Name,
isCompleteDefinition, /*Create=*/false);
}
if (RC)
return RC;
RC = NS->FindClass(Name, isCompleteDefinition, /*Create=*/true);
RC = NS->FindClass(opts->unityBuild ? Record : 0, Name,
isCompleteDefinition, /*Create=*/true);
RC->isInjected = Record->isInjectedClassName();
HandleDeclaration(Record, RC);
EnsureCompleteRecord(Record, NS, RC);

2
src/CppParser/ParserGen/ParserGen.cs

@ -88,7 +88,7 @@ namespace CppSharp @@ -88,7 +88,7 @@ namespace CppSharp
options.CheckSymbols = false;
//options.Verbose = true;
options.UnityBuild = true;
parserOptions.UnityBuild = true;
}
private void SetupLinuxOptions(ParserOptions options)

2
src/Generator/Driver.cs

@ -124,7 +124,7 @@ namespace CppSharp @@ -124,7 +124,7 @@ namespace CppSharp
var sourceFiles = Options.Modules.SelectMany(m => m.Headers);
if (Options.UnityBuild)
if (ParserOptions.UnityBuild)
{
using (var parserOptions = ParserOptions.BuildForSourceFile(
Options.Modules))

15
src/Generator/Generators/CSharp/CSharpSources.cs

@ -303,16 +303,7 @@ namespace CppSharp.Generators.CSharp @@ -303,16 +303,7 @@ namespace CppSharp.Generators.CSharp
GenerateClassInternals(specialization);
foreach (var group in generated.SelectMany(s => s.Classes).Where(
// HACK: the distinction is needed to eliminate duplicate nested types
// Since all template specialisations are incomplete by default,
// so are classes nested in them.
// When such classes are also forwarded, there are two incomplete declarations
// with the same name and in the same scope. Our parser searches by name and
// completion and it can therefore not make a difference between the two.
// Consequently, it always returns the first type it finds even if it isn't the right one.
// When clang::Sema later completes the specialisations, it completes the nested
// types too which leads to two identical complete types in the same scope.
c => !c.IsIncomplete).Distinct().GroupBy(c => c.Name))
c => !c.IsIncomplete).GroupBy(c => c.Name))
GenerateNestedInternals(group.Key, group);
WriteCloseBraceIndent();
@ -546,8 +537,8 @@ namespace CppSharp.Generators.CSharp @@ -546,8 +537,8 @@ namespace CppSharp.Generators.CSharp
Class template;
if (currentSpecialization != null &&
(template = currentSpecialization.TemplatedDecl.TemplatedClass)
.GetSpecializationsToGenerate().Count == 1)
foreach (var specialization in template.Specializations.Where(s => !s.Ignore))
.GetSpecializedClassesToGenerate().Count() == 1)
foreach (var specialization in template.Specializations.Where(s => s.IsGenerated))
GatherClassInternalFunctions(specialization, includeCtors, functions);
else
GatherClassInternalFunctions(@class, includeCtors, functions);

5
src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs

@ -23,7 +23,8 @@ namespace CppSharp.Generators.CSharp @@ -23,7 +23,8 @@ namespace CppSharp.Generators.CSharp
{
var printedClass = @class.Visit(gen.TypePrinter);
if (@class.IsDependent)
foreach (var specialization in @class.GetSpecializationsToGenerate().Where(s => !s.Ignore))
foreach (var specialization in @class.GetSpecializedClassesToGenerate(
).Where(s => s.IsGenerated))
gen.GenerateNativeConstructorByValue(specialization, printedClass.Type);
else
gen.GenerateNativeConstructorByValue(@class, printedClass.Type);
@ -127,7 +128,7 @@ namespace CppSharp.Generators.CSharp @@ -127,7 +128,7 @@ namespace CppSharp.Generators.CSharp
var typePrinter = new CSharpTypePrinter(gen.Context);
var supportedTypes = string.Join(", ",
@class.Specializations.Where(s => !s.Ignore).Select(s => $@"<{string.Join(", ",
s.Arguments.Select(a => typePrinter.VisitTemplateArgument(a)))}>"));
s.Arguments.Select(typePrinter.VisitTemplateArgument))}>"));
var typeArguments = string.Join(", ", @class.TemplateParameters.Select(p => p.Name));
var managedTypes = string.Join(", ", @class.TemplateParameters.Select(p => $"typeof({p.Name}).FullName"));
gen.WriteLine($"throw new ArgumentOutOfRangeException(\"{typeArguments}\", "

11
src/Generator/Options.cs

@ -52,17 +52,6 @@ namespace CppSharp @@ -52,17 +52,6 @@ namespace CppSharp
#endregion
#region Parser options
/// <summary>
/// If this option is off (the default), each header is parsed separately
/// which is much slower but safer because of a clean state of the preprocessor
/// for each header.
/// </summary>
public bool UnityBuild { get; set; }
#endregion
#region Module options
public Module SystemModule { get; }

36
src/Generator/Passes/ResolveIncompleteDeclsPass.cs

@ -19,6 +19,11 @@ namespace CppSharp.Passes @@ -19,6 +19,11 @@ namespace CppSharp.Passes
EnsureCompleteDeclaration(@class);
if (@class.Namespace is ClassTemplateSpecialization &&
@class.IsIncomplete && @class.CompleteDeclaration == null &&
@class.IsGenerated)
@class.GenerationKind = GenerationKind.Internal;
return true;
}
@ -50,6 +55,18 @@ namespace CppSharp.Passes @@ -50,6 +55,18 @@ namespace CppSharp.Passes
return true;
}
public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)
{
if (!base.VisitClassTemplateSpecializationDecl(specialization))
return false;
if (specialization.IsIncomplete &&
specialization.CompleteDeclaration == null && specialization.IsGenerated)
specialization.GenerationKind = GenerationKind.Internal;
return true;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
if (!VisitDeclaration(@enum))
@ -86,16 +103,25 @@ namespace CppSharp.Passes @@ -86,16 +103,25 @@ namespace CppSharp.Passes
declaration.CompleteDeclaration =
ASTContext.FindCompleteClass(declaration.QualifiedName);
if (declaration.CompleteDeclaration != null)
return;
if (Context.ParserOptions.UnityBuild)
{
if (declaration.IsGenerated)
foreach (var redecl in declaration.Redeclarations)
redecl.GenerationKind = GenerationKind.None;
return;
}
var @class = declaration as Class;
if (CheckForDuplicateForwardClass(@class))
return;
if (declaration.CompleteDeclaration == null)
{
if (declaration.IsGenerated)
declaration.GenerationKind = GenerationKind.Internal;
Diagnostics.Debug("Unresolved declaration: {0}",
declaration.Name);
}
Diagnostics.Debug("Unresolved declaration: {0}",
declaration.Name);
}
bool CheckForDuplicateForwardClass(Class @class)

3
src/Generator/Passes/TrimSpecializationsPass.cs

@ -133,9 +133,6 @@ namespace CppSharp.Passes @@ -133,9 +133,6 @@ namespace CppSharp.Passes
if (template.Fields.Any(f => f.Type.Desugar() is TemplateParameterType))
MoveExternalSpecializations(template);
foreach (var @class in template.Specializations.SelectMany(s => s.Classes))
@class.ExplicitlyIgnore();
}
/// <summary>

3
src/Parser/ParserOptions.cs

@ -82,7 +82,8 @@ namespace CppSharp.Parser @@ -82,7 +82,8 @@ namespace CppSharp.Parser
NoBuiltinIncludes = this.NoBuiltinIncludes,
MicrosoftMode = this.MicrosoftMode,
Verbose = this.Verbose,
LanguageVersion = this.LanguageVersion
LanguageVersion = this.LanguageVersion,
UnityBuild = this.UnityBuild
};
// This eventually gets passed to Clang's MSCompatibilityVersion, which

2
tests/CSharp/AnotherUnit.h

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
#include "../Tests.h"
#include <string>
#pragma once
void DLL_API functionInAnotherUnit();
struct DLL_API ForwardDeclaredStruct;

7
tests/CSharp/CSharp.cs

@ -20,6 +20,13 @@ namespace CppSharp.Tests @@ -20,6 +20,13 @@ namespace CppSharp.Tests
{
}
public override void Setup(Driver driver)
{
base.Setup(driver);
driver.ParserOptions.UnityBuild = true;
}
public override void SetupPasses(Driver driver)
{
driver.Context.TranslationUnitPasses.AddPass(new TestAttributesPass());

2
tests/Common/Common.cs

@ -58,7 +58,7 @@ namespace CppSharp.Tests @@ -58,7 +58,7 @@ namespace CppSharp.Tests
file.FileNameWithoutExtension + "_GenerateName";
driver.Options.Modules[1].OutputNamespace = "CommonTest";
driver.Options.UnityBuild = true;
driver.ParserOptions.UnityBuild = true;
}
public override void SetupPasses(Driver driver)

Loading…
Cancel
Save