Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Commit

Permalink
Merge pull request #13 from esdrubal/typerefs
Browse files Browse the repository at this point in the history
C++/CLI Type references fixes
  • Loading branch information
tritao committed Jul 22, 2013
2 parents 383bfdf + 06ab486 commit 64c7a79
Show file tree
Hide file tree
Showing 19 changed files with 433 additions and 432 deletions.
4 changes: 2 additions & 2 deletions src/AST/Declaration.cs
Expand Up @@ -44,7 +44,7 @@ public abstract class Declaration : INamedDecl
private string name;

// Name of the declaration.
public string Name
public virtual string Name
{
get { return name; }
set
Expand All @@ -67,7 +67,7 @@ public string QualifiedName
}

// Name of the declaration.
public string OriginalName;
public virtual string OriginalName { get; set;}

public string QualifiedOriginalName
{
Expand Down
34 changes: 34 additions & 0 deletions src/AST/Template.cs
Expand Up @@ -41,6 +41,40 @@ public override T Visit<T>(IDeclVisitor<T> visitor)
{
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
Expand Down
178 changes: 178 additions & 0 deletions src/Generator/AST/ASTRecord.cs
@@ -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 change: 0 additions & 1 deletion src/Generator/Driver.cs
Expand Up @@ -131,7 +131,6 @@ public void AddPostPasses()
{
Passes.CleanInvalidDeclNames();
Passes.CheckIgnoredDecls();
Passes.CheckTypeReferences();
Passes.CheckFlagEnums();
Passes.CheckAmbiguousOverloads();
Generator.SetupPasses(Passes);
Expand Down

0 comments on commit 64c7a79

Please sign in to comment.