Browse Source

Merge pull request #13 from esdrubal/typerefs

C++/CLI Type references fixes
pull/14/head
João Matos 13 years ago
parent
commit
64c7a79fcf
  1. 4
      src/AST/Declaration.cs
  2. 34
      src/AST/Template.cs
  3. 178
      src/Generator/AST/ASTRecord.cs
  4. 1
      src/Generator/Driver.cs
  5. 207
      src/Generator/Generators/CLI/CLIForwardReferencePrinter.cs
  6. 41
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  7. 37
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  8. 1
      src/Generator/Generators/CLI/CLITextTemplate.cs
  9. 3
      src/Generator/Generators/CLI/CLITypePrinter.cs
  10. 162
      src/Generator/Generators/CLI/CLITypeReferences.cs
  11. 2
      src/Generator/Generators/CSharp/CSharpGenerator.cs
  12. 3
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  13. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  14. 30
      src/Generator/Passes/CheckTypeReferencesPass.cs
  15. 4
      src/Generator/Passes/ObjectOverridesPass.cs
  16. 2
      src/Generator/Types/CppTypePrinter.cs
  17. 5
      src/Generator/Types/TypeMap.cs
  18. 134
      src/Generator/Types/Types.cs
  19. 14
      src/Parser/Parser.cpp

4
src/AST/Declaration.cs

@ -44,7 +44,7 @@ namespace CppSharp.AST @@ -44,7 +44,7 @@ namespace CppSharp.AST
private string name;
// Name of the declaration.
public string Name
public virtual string Name
{
get { return name; }
set
@ -67,7 +67,7 @@ namespace CppSharp.AST @@ -67,7 +67,7 @@ namespace CppSharp.AST
}
// Name of the declaration.
public string OriginalName;
public virtual string OriginalName { get; set;}
public string QualifiedOriginalName
{

34
src/AST/Template.cs

@ -41,6 +41,40 @@ namespace CppSharp.AST @@ -41,6 +41,40 @@ namespace CppSharp.AST
{
return visitor.VisitClassTemplateDecl(this);
}
public override string Name
{
get
{
if(TemplatedDecl != null)
return TemplatedClass.Name;
return base.Name;
}
set
{
if(TemplatedDecl != null)
TemplatedClass.Name = value;
else
base.Name = value;
}
}
public override string OriginalName
{
get
{
if(TemplatedDecl != null)
return TemplatedClass.OriginalName;
return base.OriginalName;
}
set
{
if(TemplatedDecl != null)
TemplatedClass.OriginalName = value;
else
base.OriginalName = value;
}
}
}
public class ClassTemplateSpecialization : Class

178
src/Generator/AST/ASTRecord.cs

@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using CppSharp.AST;
using Type = CppSharp.AST.Type;
namespace CppSharp.Generators.AST
{
public class ASTRecord
{
public ASTRecord Parent;
public object Object;
public bool GetParent<T>(out T @out)
{
@out = default(T);
if (Parent == null)
return false;
var v = Parent.Object;
if (!(v is T))
return false;
@out = (T) v;
return true;
}
// Pushes ancestors into the stack until it is found one of type T.
public bool GetAncestors<T>(ref Stack<object> ancestors)
{
ancestors.Push(this);
T value;
if (GetParent(out value))
{
ancestors.Push(value);
return true;
}
return Parent != null
&& Parent.GetAncestors<T>(ref ancestors);
}
}
public class ASTRecord<T> : ASTRecord
{
public T Value
{
get { return (T) Object; }
}
}
public class ASTRecordStack
{
private readonly Stack<ASTRecord> recordStack;
public ASTRecordStack()
{
recordStack = new Stack<ASTRecord>();
}
public ASTRecord<T> Push<T>(T value)
{
ASTRecord parent = null;
if (recordStack.Count > 0)
parent = recordStack.Peek();
var record = new ASTRecord<T>()
{
Parent = parent,
Object = value
};
recordStack.Push(record);
return record;
}
public void Pop()
{
recordStack.Pop();
}
}
static class ASTRecordExtensions
{
public static bool IsBaseClass(this ASTRecord record)
{
Class decl;
return record.GetParent(out decl) && decl.BaseClass == record.Object;
}
public static bool IsFieldValueType(this ASTRecord record)
{
var ancestors = new Stack<object>();
if(!record.GetAncestors<Field>(ref ancestors))
return false;
var field = (Field)ancestors.Pop();
Class decl;
if (!field.Type.Desugar().IsTagDecl(out decl))
return false;
return decl.IsValueType;
}
}
public class RecordCollector : AstVisitor
{
public readonly ISet<ASTRecord<Declaration>> Declarations;
private readonly ASTRecordStack recordStack;
public TranslationUnit translationUnit;
public ISet<object> Visited2 { get; private set; }
public bool AlreadyVisited2(object o)
{
return !Visited2.Add(o);
}
public RecordCollector(TranslationUnit translationUnit)
{
this.translationUnit = translationUnit;
Declarations = new HashSet<ASTRecord<Declaration>>();
recordStack = new ASTRecordStack();
Visited2 = new HashSet<object>();
}
public override bool VisitDeclaration(Declaration decl)
{
if(translationUnit.FileName.Contains("Font"))
Console.Write("");
if (decl.IsIncomplete && decl.CompleteDeclaration != null)
decl = decl.CompleteDeclaration;
if(AlreadyVisited2(decl))
return ShouldVisitChilds(decl);
Visited.Remove(decl); // So Class can be revisited
Declarations.Add(recordStack.Push(decl));
decl.Visit(this);
recordStack.Pop();
return false;
}
public override bool VisitType(Type type, TypeQualifiers quals)
{
type = type.Desugar();
if(AlreadyVisited2(type))
return true;
recordStack.Push(type);
type.Visit(this);
recordStack.Pop();
return false;
}
public bool ShouldVisitChilds(Declaration decl)
{
if(decl == translationUnit)
return true;
if (decl is TranslationUnit)
return false;
if (decl.Namespace == null)
return true;
// No need to continue visiting after a declaration of
// another translation unit is encountered.
return decl.Namespace.TranslationUnit == translationUnit;
}
}
}

1
src/Generator/Driver.cs

@ -131,7 +131,6 @@ namespace CppSharp @@ -131,7 +131,6 @@ namespace CppSharp
{
Passes.CleanInvalidDeclNames();
Passes.CheckIgnoredDecls();
Passes.CheckTypeReferences();
Passes.CheckFlagEnums();
Passes.CheckAmbiguousOverloads();
Generator.SetupPasses(Passes);

207
src/Generator/Generators/CLI/CLIForwardReferencePrinter.cs

@ -1,207 +0,0 @@ @@ -1,207 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using CppSharp.AST;
namespace CppSharp.Generators.CLI
{
public struct CLIForwardReference
{
public Declaration Declaration;
public Namespace Namespace;
public string Text;
}
public class CLIForwardReferencePrinter : IDeclVisitor<bool>
{
public readonly IList<string> Includes;
public readonly IList<CLIForwardReference> Refs;
private readonly TypeRefsVisitor TypeRefs;
private TypeReference currentTypeReference;
public CLIForwardReferencePrinter(TypeRefsVisitor typeRefs)
{
Includes = new List<string>();
Refs = new List<CLIForwardReference>();
TypeRefs = typeRefs;
}
public void Process()
{
foreach (var typeRef in TypeRefs.References)
{
currentTypeReference = typeRef;
typeRef.Declaration.Visit(this);
}
foreach (var baseClass in TypeRefs.Bases)
VisitBaseClass(baseClass);
}
public void VisitBaseClass(Class @class)
{
if (@class.IsIncomplete)
@class = @class.CompleteDeclaration as Class;
if (@class == null)
return;
Includes.Add(GetHeaderFromDecl(@class));
}
public bool VisitDeclaration(Declaration decl)
{
throw new NotImplementedException();
}
public bool VisitClassDecl(Class @class)
{
var completeDecl = @class.CompleteDeclaration as Class;
if (@class.IsIncomplete && completeDecl != null)
return VisitClassDecl(completeDecl);
if (@class.IsValueType)
{
Refs.Add(new CLIForwardReference()
{
Declaration = @class,
Namespace = currentTypeReference.Namespace,
Text = string.Format("value struct {0};", @class.Name)
});
return true;
}
Refs.Add(new CLIForwardReference()
{
Declaration = @class,
Namespace = currentTypeReference.Namespace,
Text = string.Format("ref class {0};", @class.Name)
});
return true;
}
public bool VisitFieldDecl(Field field)
{
Class @class;
if (field.Type.IsTagDecl(out @class))
{
if (@class.IsValueType)
Includes.Add(GetHeaderFromDecl(@class));
else
VisitClassDecl(@class);
return true;
}
Enumeration @enum;
if (field.Type.IsTagDecl(out @enum))
return VisitEnumDecl(@enum);
Includes.Add(GetHeaderFromDecl(field));
return true;
}
public bool VisitFunctionDecl(Function function)
{
throw new NotImplementedException();
}
public bool VisitMethodDecl(Method method)
{
throw new NotImplementedException();
}
public bool VisitParameterDecl(Parameter parameter)
{
throw new NotImplementedException();
}
public string GetHeaderFromDecl(Declaration decl)
{
var @namespace = decl.Namespace;
var unit = @namespace.TranslationUnit;
if (unit.Ignore)
return string.Empty;
if (unit.IsSystemHeader)
return string.Empty;
return Path.GetFileNameWithoutExtension(unit.FileName);
}
public bool VisitTypedefDecl(TypedefDecl typedef)
{
FunctionType function;
if (typedef.Type.IsPointerTo<FunctionType>(out function))
{
Includes.Add(GetHeaderFromDecl(typedef));
return true;
}
throw new NotImplementedException();
}
public bool VisitEnumDecl(Enumeration @enum)
{
Includes.Add(GetHeaderFromDecl(@enum));
if (@enum.Type.IsPrimitiveType(PrimitiveType.Int32))
{
Refs.Add(new CLIForwardReference()
{
Declaration = @enum,
Namespace = currentTypeReference.Namespace,
Text = string.Format("enum struct {0};", @enum.Name)
});
return true;
}
Refs.Add(new CLIForwardReference()
{
Declaration = @enum,
Namespace = currentTypeReference.Namespace,
Text = string.Format("enum struct {0} : {1};", @enum.Name, @enum.Type)
});
return true;
}
public bool VisitVariableDecl(Variable variable)
{
throw new NotImplementedException();
}
public bool VisitClassTemplateDecl(ClassTemplate template)
{
throw new NotImplementedException();
}
public bool VisitFunctionTemplateDecl(FunctionTemplate template)
{
throw new NotImplementedException();
}
public bool VisitMacroDefinition(MacroDefinition macro)
{
throw new NotImplementedException();
}
public bool VisitNamespace(Namespace @namespace)
{
throw new NotImplementedException();
}
public bool VisitEvent(Event @event)
{
throw new NotImplementedException();
}
public bool VisitProperty(Property property)
{
throw new NotImplementedException();
}
}
}

41
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -46,47 +46,38 @@ namespace CppSharp.Generators.CLI @@ -46,47 +46,38 @@ namespace CppSharp.Generators.CLI
public void GenerateIncludeForwardRefs()
{
var typeRefs = TranslationUnit.TypeReferences as TypeRefsVisitor;
var forwardRefsPrinter = new CLIForwardReferencePrinter(typeRefs);
forwardRefsPrinter.Process();
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase);
typeReferenceCollector.Process(TranslationUnit);
var includes = new SortedSet<string>(StringComparer.InvariantCulture);
foreach (var include in forwardRefsPrinter.Includes)
{
if (string.IsNullOrWhiteSpace(include))
continue;
if (include == Path.GetFileNameWithoutExtension(TranslationUnit.FileName))
foreach (var typeRef in typeReferenceCollector.TypeReferences)
{
if (typeRef.Include.File == TranslationUnit.FileName)
continue;
includes.Add(string.Format("#include \"{0}.h\"", include));
var include = typeRef.Include;
if(!string.IsNullOrEmpty(include.File) && include.InHeader)
includes.Add(include.ToString());
}
foreach (var include in Includes)
includes.Add(include.ToString());
foreach (var include in includes)
WriteLine(include);
}
public void GenerateForwardRefs(Namespace @namespace)
{
var typeRefs = TranslationUnit.TypeReferences as TypeRefsVisitor;
var forwardRefsPrinter = new CLIForwardReferencePrinter(typeRefs);
forwardRefsPrinter.Process();
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase);
typeReferenceCollector.Process(@namespace);
// Use a set to remove duplicate entries.
var forwardRefs = new SortedSet<string>(StringComparer.InvariantCulture);
foreach (var forwardRef in forwardRefsPrinter.Refs)
foreach (var typeRef in typeReferenceCollector.TypeReferences)
{
if (forwardRef.Namespace != @namespace)
continue;
forwardRefs.Add(forwardRef.Text);
var @ref = typeRef.FowardReference;
if(!string.IsNullOrEmpty(@ref) && !typeRef.Include.InHeader)
forwardRefs.Add(@ref);
}
foreach (var forwardRef in forwardRefs)
@ -259,8 +250,8 @@ namespace CppSharp.Generators.CLI @@ -259,8 +250,8 @@ namespace CppSharp.Generators.CLI
PushIndent();
WriteLine("property System::IntPtr Instance");
WriteStartBraceIndent();
WriteLine("virtual System::IntPtr get();");
WriteLine("virtual void set(System::IntPtr instance);");
WriteLine("virtual System::IntPtr get() override;");
WriteLine("virtual void set(System::IntPtr instance) override;");
WriteCloseBraceIndent();
NewLine();

37
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -52,38 +52,22 @@ namespace CppSharp.Generators.CLI @@ -52,38 +52,22 @@ namespace CppSharp.Generators.CLI
public void GenerateForwardReferenceHeaders()
{
PushBlock(CLIBlockKind.IncludesForwardReferences);
var includes = new SortedSet<string>(StringComparer.InvariantCulture);
var typeRefs = TranslationUnit.TypeReferences as TypeRefsVisitor;
// Generate the forward references.
foreach (var forwardRef in typeRefs.References)
{
var decl = forwardRef.Declaration;
if (decl.IsIncomplete && decl.CompleteDeclaration != null)
decl = decl.CompleteDeclaration;
var @namespace = decl.Namespace;
var translationUnit = @namespace.TranslationUnit;
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase);
typeReferenceCollector.Process(TranslationUnit);
if (translationUnit.Ignore)
continue;
if (translationUnit.IsSystemHeader)
continue;
var includeName = Path.GetFileNameWithoutExtension(translationUnit.FileName);
var includes = new SortedSet<string>(StringComparer.InvariantCulture);
if (includeName == Path.GetFileNameWithoutExtension(TranslationUnit.FileName))
foreach (var typeRef in typeReferenceCollector.TypeReferences)
{
if (typeRef.Include.File == TranslationUnit.FileName)
continue;
includes.Add(string.Format("#include \"{0}.h\"", includeName.Replace('\\', '/')));
var include = typeRef.Include;
if(!string.IsNullOrEmpty(include.File) && !include.InHeader)
includes.Add(include.ToString());
}
foreach (var include in Includes)
includes.Add(include.ToString());
foreach (var include in includes)
WriteLine(include);
@ -726,8 +710,7 @@ namespace CppSharp.Generators.CLI @@ -726,8 +710,7 @@ namespace CppSharp.Generators.CLI
if (IsNativeFunctionOrStaticMethod(function))
{
Write("::");
Write("{0}(", function.QualifiedOriginalName);
Write("::{0}(", function.QualifiedOriginalName);
}
else
{

1
src/Generator/Generators/CLI/CLITextTemplate.cs

@ -15,6 +15,7 @@ namespace CppSharp.Generators.CLI @@ -15,6 +15,7 @@ namespace CppSharp.Generators.CLI
public string File;
public IncludeKind Kind;
public bool InHeader;
public override string ToString()
{

3
src/Generator/Generators/CLI/CLITypePrinter.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.Types;
using Type = CppSharp.AST.Type;
namespace CppSharp.Generators.CLI
{
@ -340,7 +341,7 @@ namespace CppSharp.Generators.CLI @@ -340,7 +341,7 @@ namespace CppSharp.Generators.CLI
throw new NotImplementedException();
}
public string ToString(AST.Type type)
public string ToString(Type type)
{
return type.Visit(this);
}

162
src/Generator/Generators/CLI/CLITypeReferences.cs

@ -0,0 +1,162 @@ @@ -0,0 +1,162 @@
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.Generators.AST;
using CppSharp.Types;
namespace CppSharp.Generators.CLI
{
public class CLITypeReference
{
public Include Include;
public string FowardReference;
}
public class CLITypeReferenceCollector : AstVisitor
{
private Dictionary<Declaration, CLITypeReference> typeReferences;
private readonly ITypeMapDatabase TypeMapDatabase;
private TranslationUnit TranslationUnit;
public IEnumerable<CLITypeReference> TypeReferences
{
get { return typeReferences.Values; }
}
public CLITypeReferenceCollector(ITypeMapDatabase typeMapDatabase)
{
TypeMapDatabase = typeMapDatabase;
typeReferences = new Dictionary<Declaration,CLITypeReference>();
}
public CLITypeReference GetTypeReference(Declaration decl)
{
if(typeReferences.ContainsKey(decl))
return typeReferences[decl];
var @ref = new CLITypeReference();
typeReferences.Add(decl, @ref);
return @ref;
}
public void Process(Namespace @namespace)
{
var collector = new RecordCollector(@namespace.TranslationUnit);
@namespace.Visit(collector);
TranslationUnit = @namespace.TranslationUnit;
foreach (var record in collector.Declarations)
{
record.Value.Visit(this);
GenerateInclude(record);
ProcessTypeMap(record);
}
}
private void ProcessTypeMap(ASTRecord<Declaration> record)
{
TypeMap typeMap;
if (!TypeMapDatabase.FindTypeMap(record.Value, out typeMap)) return;
// Typemap must explicitly set the include file when one is required.
GetTypeReference(record.Value).Include.File = "";
typeMap.Declaration = record.Value;
typeMap.CLITypeReference(this, record);
}
private void GenerateInclude(ASTRecord<Declaration> record)
{
var decl = record.Value;
if(decl.Namespace == null)
return;
var declFile = decl.Namespace.TranslationUnit.FileName;
if(decl.Namespace.TranslationUnit.IsSystemHeader)
return;
if(decl.Ignore)
return;
if(IsBuiltinTypedef(decl))
return;
if (declFile.Contains("String"))
return;
GetTypeReference(decl).Include = new Include()
{
File = declFile,
Kind = Include.IncludeKind.Quoted,
InHeader = IsIncludeInHeader(record)
};
}
private bool IsBuiltinTypedef(Declaration decl)
{
var typedefDecl = decl as TypedefDecl;
if(typedefDecl == null) return false;
if(typedefDecl.Type is BuiltinType) return true;
var typedefType = typedefDecl.Type as TypedefType;
if(typedefType == null) return false;
if(typedefType.Declaration == null) return false;
return typedefType.Declaration.Type is BuiltinType;
}
private bool IsIncludeInHeader(ASTRecord<Declaration> record)
{
return record.IsBaseClass() || record.IsFieldValueType();
}
public override bool VisitDeclaration(Declaration decl)
{
return ShouldVisitDecl(decl);
}
public override bool VisitClassDecl(Class @class)
{
if(!ShouldVisitDecl(@class))
return false;
if (@class.IsIncomplete && @class.CompleteDeclaration != null)
@class = (Class) @class.CompleteDeclaration;
var keywords = @class.IsValueType? "value struct" : "ref class";
var @ref = string.Format("{0} {1};", keywords, @class.Name);
GetTypeReference(@class).FowardReference = @ref;
return false;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
if(!ShouldVisitDecl(@enum))
return false;
var @base = "";
if(!@enum.Type.IsPrimitiveType(PrimitiveType.Int32))
@base = string.Format(" : {0}", @enum.Type);
var @ref = string.Format("enum struct {0}{1};", @enum.Name, @base);
GetTypeReference(@enum).FowardReference = @ref;
return false;
}
private bool ShouldVisitDecl(Declaration decl)
{
if(decl.Namespace != null && decl.Namespace.TranslationUnit.IsSystemHeader)
return false;
if (decl.Ignore)
return false;
return true;
}
}
}

2
src/Generator/Generators/CSharp/CSharpGenerator.cs

@ -13,7 +13,7 @@ namespace CppSharp.Generators.CSharp @@ -13,7 +13,7 @@ namespace CppSharp.Generators.CSharp
public CSharpGenerator(Driver driver) : base(driver)
{
typePrinter = new CSharpTypePrinter(driver.TypeDatabase, driver.Library);
AST.Type.TypePrinterDelegate += type => type.Visit(typePrinter).Type;
CppSharp.AST.Type.TypePrinterDelegate += type => type.Visit(typePrinter).Type;
}
public override List<Template> Generate(TranslationUnit unit)

3
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -4,6 +4,7 @@ using System.Globalization; @@ -4,6 +4,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using CppSharp.AST;
using Type = CppSharp.AST.Type;
namespace CppSharp.Generators.CSharp
{
@ -845,7 +846,7 @@ namespace CppSharp.Generators.CSharp @@ -845,7 +846,7 @@ namespace CppSharp.Generators.CSharp
}
}
private void GenerateVariable(Class @class, AST.Type type, Variable variable)
private void GenerateVariable(Class @class, Type type, Variable variable)
{
PushBlock(CSharpBlockKind.Variable);
WriteLine("public static {0} {1}", type, variable.Name);

3
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.Types;
using Type = CppSharp.AST.Type;
namespace CppSharp.Generators.CSharp
{
@ -463,7 +464,7 @@ namespace CppSharp.Generators.CSharp @@ -463,7 +464,7 @@ namespace CppSharp.Generators.CSharp
VisitParameters(function.Parameters, hasNames: true));
}
public string ToString(AST.Type type)
public string ToString(Type type)
{
return type.Visit(this).Type;
}

30
src/Generator/Passes/CheckTypeReferencesPass.cs

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
using CppSharp.AST;
namespace CppSharp.Passes
{
public class CheckTypeReferencesPass : TranslationUnitPass
{
TypeRefsVisitor typeRefs;
public override bool VisitTranslationUnit(TranslationUnit unit)
{
if (unit.Ignore)
return false;
if (unit.IsSystemHeader)
return false;
typeRefs = new TypeRefsVisitor();
return typeRefs.VisitTranslationUnit(unit);
}
}
public static class CheckTypeReferencesExtensions
{
public static void CheckTypeReferences(this PassBuilder builder)
{
var pass = new CheckTypeReferencesPass();
builder.AddPass(pass);
}
}
}

4
src/Generator/Passes/ObjectOverridesPass.cs

@ -16,12 +16,16 @@ namespace CppSharp @@ -16,12 +16,16 @@ namespace CppSharp
foreach (var block in template.FindBlocks(CLIBlockKind.MethodBody))
{
var method = block.Declaration as Method;
if (!method.IsSynthetized)
continue;
switch (method.Name)
{
case "GetHashCode":
block.Write("return (int)NativePtr;");
break;
case "Equals":
block.WriteLine("if (!object) return false;");
block.Write("return Instance == safe_cast<ICppInstance^>({0})->Instance;",
method.Parameters[0].Name);

2
src/Generator/Types/CppTypePrinter.cs

@ -222,7 +222,7 @@ namespace CppSharp.Types @@ -222,7 +222,7 @@ namespace CppSharp.Types
public string VisitEnumDecl(Enumeration @enum)
{
return @enum.Name;
return string.Format("::{0}", @enum.QualifiedOriginalName);
}
public string VisitVariableDecl(Variable variable)

5
src/Generator/Types/TypeMap.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.Generators;
using CppSharp.Generators.AST;
using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp;
using Type = CppSharp.AST.Type;
@ -65,6 +66,10 @@ namespace CppSharp.Types @@ -65,6 +66,10 @@ namespace CppSharp.Types
throw new NotImplementedException();
}
public virtual void CLITypeReference(CLITypeReferenceCollector collector, ASTRecord<Declaration> loc)
{
}
public virtual void CLIMarshalToNative(MarshalContext ctx)
{
throw new NotImplementedException();

134
src/Generator/Types/Types.cs

@ -117,138 +117,4 @@ namespace CppSharp @@ -117,138 +117,4 @@ namespace CppSharp
}
}
public struct TypeReference
{
public Declaration Declaration;
public Namespace Namespace;
}
/// <summary>
/// This is used to get the declarations that each file needs to forward
/// reference or include from other header files. Since in C++ everything
/// that is referenced needs to have been declared previously, it can happen
/// that a file needs to be reference something that has not been declared
/// yet. In that case, we need to declare it before referencing it.
/// </summary>
public class TypeRefsVisitor : AstVisitor
{
public ISet<TypeReference> References;
public ISet<Class> Bases;
private TranslationUnit unit;
private Namespace currentNamespace;
public TypeRefsVisitor()
{
References = new HashSet<TypeReference>();
Bases = new HashSet<Class>();
}
public void Collect(Declaration declaration)
{
var @namespace = declaration.Namespace;
if (@namespace != null)
if (@namespace.TranslationUnit.IsSystemHeader)
return;
References.Add(new TypeReference()
{
Declaration = declaration,
Namespace = currentNamespace
});
}
public bool VisitTranslationUnit(TranslationUnit unit)
{
this.unit = unit;
unit.TypeReferences = this;
VisitNamespace(unit);
foreach (var @namespace in unit.Namespaces)
VisitNamespace(@namespace);
return true;
}
public override bool VisitNamespace(Namespace @namespace)
{
currentNamespace = @namespace;
return base.VisitNamespace(@namespace);
}
public override bool VisitClassDecl(Class @class)
{
if (@class.Ignore)
{
Visited.Add(@class);
return false;
}
if (Visited.Contains(@class))
return References.Any(reference => reference.Declaration == @class);
Collect(@class);
// If the class is incomplete, then we cannot process the record
// members, else it will add references to declarations that
// should have not been found.
if (@class.IsIncomplete)
goto OutVisited;
if (string.IsNullOrWhiteSpace(@class.Name))
goto OutVisited;
var unitClass = unit.FindClass(@class.Name);
if (unitClass == null || unitClass.IsIncomplete)
goto OutVisited;
foreach (var @base in @class.Bases)
{
if (!@base.IsClass)
continue;
Bases.Add(@base.Class);
}
return base.VisitClassDecl(@class);
OutVisited:
Visited.Add(@class);
return true;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
Collect(@enum);
return true;
}
public override bool VisitFieldDecl(Field field)
{
if (base.VisitFieldDecl(field))
Collect(field);
return true;
}
public override bool VisitTypedefType(TypedefType typedef,
TypeQualifiers quals)
{
var decl = typedef.Declaration;
if (decl.Type == null)
return false;
FunctionType function;
if (decl.Type.IsPointerTo<FunctionType>(out function))
{
Collect(decl);
return true;
}
return decl.Type.Visit(this);
}
}
}

14
src/Parser/Parser.cpp

@ -499,6 +499,17 @@ CppSharp::AST::ClassTemplate^ Parser::WalkClassTemplate(clang::ClassTemplateDecl @@ -499,6 +499,17 @@ CppSharp::AST::ClassTemplate^ Parser::WalkClassTemplate(clang::ClassTemplateDecl
auto Class = WalkRecordCXX(TD->getTemplatedDecl());
CppSharp::AST::ClassTemplate^ CT = gcnew CppSharp::AST::ClassTemplate(Class);
auto TPL = TD->getTemplateParameters();
for(auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
auto TP = CppSharp::AST::TemplateParameter();
TP.Name = clix::marshalString<clix::E_UTF8>(ND->getNameAsString());
CT->Parameters->Add(TP);
}
return CT;
}
@ -1335,9 +1346,10 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F, @@ -1335,9 +1346,10 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F,
TypeLoc PTL;
if (auto TSI = VD->getTypeSourceInfo())
PTL = VD->getTypeSourceInfo()->getTypeLoc();
P->QualifiedType = GetQualifiedType(VD->getType(), WalkType(VD->getType(), &PTL));
P->HasDefaultValue = VD->hasDefaultArg();
P->Namespace = NS;
F->Parameters->Add(P);
}

Loading…
Cancel
Save