Browse Source

Replace the old transform code with the general AST visiting code, which was extended a bit to support the needed early out semantics for passes.

pull/1/head
triton 13 years ago
parent
commit
979c07bb77
  1. 72
      src/Bridge/ASTVisitor.cs
  2. 3
      src/Generator/Driver.cs
  3. 79
      src/Generator/Passes/Pass.cs
  4. 5
      src/Generator/Passes/PassBuilder.cs
  5. 143
      src/Generator/Transforms/Transform.cs

72
src/Bridge/ASTVisitor.cs

@ -71,7 +71,8 @@ namespace Cxxi @@ -71,7 +71,8 @@ namespace Cxxi
return pointer.Pointee.Visit(this, quals);
}
public virtual bool VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals)
public virtual bool VisitMemberPointerType(MemberPointerType member,
TypeQualifiers quals)
{
return member.Pointee.Visit(this, quals);
}
@ -86,7 +87,8 @@ namespace Cxxi @@ -86,7 +87,8 @@ namespace Cxxi
return typedef.Declaration.Visit(this);
}
public virtual bool VisitTemplateSpecializationType(TemplateSpecializationType template, TypeQualifiers quals)
public virtual bool VisitTemplateSpecializationType(TemplateSpecializationType template,
TypeQualifiers quals)
{
foreach (var arg in template.Arguments)
{
@ -106,7 +108,8 @@ namespace Cxxi @@ -106,7 +108,8 @@ namespace Cxxi
return template.Template.Visit(this);
}
public virtual bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals)
public virtual bool VisitTemplateParameterType(TemplateParameterType param,
TypeQualifiers quals)
{
return true;
}
@ -135,16 +138,44 @@ namespace Cxxi @@ -135,16 +138,44 @@ namespace Cxxi
if (AlreadyVisited(@class))
return true;
return VisitDeclaration(@class);
if (!VisitDeclaration(@class))
return false;
foreach (var baseClass in @class.Bases)
if (baseClass.IsClass)
baseClass.Class.Visit(this);
foreach (var field in @class.Fields)
VisitFieldDecl(field);
foreach (var property in @class.Properties)
VisitProperty(property);
foreach (var method in @class.Methods)
VisitMethodDecl(method);
return true;
}
public virtual bool VisitFieldDecl(Field field)
{
if (!VisitDeclaration(field))
return false;
return field.Type.Visit(this, field.QualifiedType.Qualifiers);
}
public virtual bool VisitProperty(Property property)
{
if (!VisitDeclaration(property))
return false;
return property.Type.Visit(this);
}
public virtual bool VisitFunctionDecl(Function function)
{
if (!VisitDeclaration(function))
return false;
if (function.ReturnType != null)
function.ReturnType.Visit(this);
@ -161,38 +192,65 @@ namespace Cxxi @@ -161,38 +192,65 @@ namespace Cxxi
public virtual bool VisitParameterDecl(Parameter parameter)
{
if (!VisitDeclaration(parameter))
return false;
return parameter.Type.Visit(this, parameter.QualifiedType.Qualifiers);
}
public virtual bool VisitTypedefDecl(TypedefDecl typedef)
{
if (!VisitDeclaration(typedef))
return false;
if (typedef.Type == null)
return false;
return typedef.Type.Visit(this, typedef.QualifiedType.Qualifiers);
}
public virtual bool VisitEnumDecl(Enumeration @enum)
{
return VisitDeclaration(@enum);
if (!VisitDeclaration(@enum))
return false;
foreach (var item in @enum.Items)
VisitEnumItem(item);
return true;
}
public virtual bool VisitEnumItem(Enumeration.Item item)
{
return true;
}
public virtual bool VisitClassTemplateDecl(ClassTemplate template)
{
if (!VisitDeclaration(template))
return false;
return template.TemplatedClass.Visit(this);
}
public virtual bool VisitFunctionTemplateDecl(FunctionTemplate template)
{
if (!VisitDeclaration(template))
return false;
return template.TemplatedFunction.Visit(this);
}
public virtual bool VisitMacroDefinition(MacroDefinition macro)
{
return true;
return VisitDeclaration(macro);
}
public virtual bool VisitNamespace(Namespace @namespace)
{
if (!VisitDeclaration(@namespace))
return false;
foreach (var decl in @namespace.Classes)
decl.Visit(this);
@ -216,7 +274,7 @@ namespace Cxxi @@ -216,7 +274,7 @@ namespace Cxxi
public virtual bool VisitEvent(Event @event)
{
return true;
return VisitDeclaration(@event);
}
#endregion

3
src/Generator/Driver.cs

@ -95,8 +95,7 @@ namespace Cxxi @@ -95,8 +95,7 @@ namespace Cxxi
passes.CleanInvalidDeclNames();
var transformer = new Transform() { Options = Options, Passes = passes };
transformer.TransformLibrary(Library);
passes.RunPasses();
if (Transform != null)
Transform.Postprocess(Library);

79
src/Generator/Passes/Pass.cs

@ -5,88 +5,43 @@ namespace Cxxi.Passes @@ -5,88 +5,43 @@ namespace Cxxi.Passes
/// Used to provide different types of code transformation on a module
/// declarations and types before the code generation process is started.
/// </summary>
public abstract class TranslationUnitPass
public abstract class TranslationUnitPass : AstVisitor
{
public Library Library { get; set; }
/// <summary>
/// Processes a library.
/// </summary>
public virtual bool ProcessLibrary(Library library)
public virtual bool VisitLibrary(Library library)
{
return false;
}
foreach (var unit in library.TranslationUnits)
VisitTranslationUnit(unit);
/// <summary>
/// Processes a translation unit.
/// </summary>
public virtual bool ProcessUnit(TranslationUnit unit)
{
return false;
return true;
}
/// <summary>
/// Processes a declaration.
/// </summary>
public virtual bool ProcessDeclaration(Declaration decl)
public virtual bool VisitTranslationUnit(TranslationUnit unit)
{
if (unit.Ignore)
return false;
}
/// <summary>
/// Processes a class.
/// </summary>
public virtual bool ProcessClass(Class @class)
{
if (unit.IsSystemHeader)
return false;
}
/// <summary>
/// Processes a field.
/// </summary>
public virtual bool ProcessField(Field field)
{
return false;
}
VisitNamespace(unit);
/// <summary>
/// Processes a function declaration.
/// </summary>
public virtual bool ProcessFunction(Function function)
{
return false;
}
/// <summary>
/// Processes a method declaration.
/// </summary>
public virtual bool ProcessMethod(Method method)
{
return false;
}
foreach (var @namespace in unit.Namespaces)
VisitNamespace(@namespace);
/// <summary>
/// Processes an enum declaration.
/// </summary>
public virtual bool ProcessEnum(Enumeration @enum)
{
return false;
return true;
}
/// <summary>
/// Processes an enum item.
/// </summary>
public virtual bool ProcessEnumItem(Enumeration.Item item)
public override bool VisitDeclaration(Declaration decl)
{
return false;
return !IsDeclExcluded(decl);
}
/// <summary>
/// Processes a typedef.
/// </summary>
public virtual bool ProcessTypedef(TypedefDecl typedef)
bool IsDeclExcluded(Declaration decl)
{
return false;
var type = this.GetType();
return decl.ExcludeFromPasses.Contains(type);
}
}
}

5
src/Generator/Passes/PassBuilder.cs

@ -28,10 +28,7 @@ namespace Cxxi @@ -28,10 +28,7 @@ namespace Cxxi
{
foreach (var pass in Passes)
{
foreach (var unit in Library.TranslationUnits)
{
pass.ProcessUnit(unit);
}
pass.VisitLibrary(Library);
}
}
}

143
src/Generator/Transforms/Transform.cs

@ -1,143 +0,0 @@ @@ -1,143 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Cxxi.Passes
{
public class Transform
{
public DriverOptions Options;
public PassBuilder Passes;
public void TransformLibrary(Library library)
{
if (string.IsNullOrEmpty(library.Name))
library.Name = string.Empty;
// Process everything in the global namespace for now.
foreach (var module in library.TranslationUnits)
TransformModule(module);
}
string GetIncludePath(string filePath)
{
string includePath = filePath;
string shortestIncludePath = filePath;
foreach (var path in Options.IncludeDirs)
{
int idx = filePath.IndexOf(path, System.StringComparison.Ordinal);
if (idx == -1) continue;
string inc = filePath.Substring(path.Length);
if (inc.Length < includePath.Length && inc.Length < shortestIncludePath.Length)
shortestIncludePath = inc;
}
return Options.IncludePrefix + shortestIncludePath.TrimStart(new char[] { '\\', '/' });
}
void TransformModule(TranslationUnit unit)
{
// Try to get an include path that works from the original include
// directories paths.
unit.IncludePath = GetIncludePath(unit.FilePath);
foreach (var pass in Passes.Passes)
pass.ProcessUnit(unit);
foreach (var @enum in unit.Enums)
TransformEnum(@enum);
foreach (var function in unit.Functions)
TransformFunction(function);
foreach (var @class in unit.Classes)
TransformClass(@class);
foreach (var typedef in unit.Typedefs)
TransformTypedef(typedef);
}
void TransformDeclaration(Declaration decl)
{
foreach (var pass in Passes.Passes)
{
if (IsPassExcluded(decl, pass)) continue;
pass.ProcessDeclaration(decl);
}
}
void TransformTypedef(TypedefDecl typedef)
{
foreach (var pass in Passes.Passes)
pass.ProcessTypedef(typedef);
TransformDeclaration(typedef);
}
void TransformClass(Class @class)
{
foreach (var pass in Passes.Passes)
{
if (IsPassExcluded(@class, pass)) continue;
pass.ProcessClass(@class);
}
TransformDeclaration(@class);
foreach (var method in @class.Methods)
{
foreach (var pass in Passes.Passes)
{
if (IsPassExcluded(method, pass)) continue;
pass.ProcessMethod(method);
}
}
foreach (var field in @class.Fields)
{
foreach (var pass in Passes.Passes)
{
if (IsPassExcluded(field, pass)) continue;
pass.ProcessField(field);
}
TransformDeclaration(field);
}
}
void TransformFunction(Function function)
{
foreach (var pass in Passes.Passes)
{
if (IsPassExcluded(function, pass)) continue;
pass.ProcessFunction(function);
}
TransformDeclaration(function);
foreach (var param in function.Parameters)
TransformDeclaration(param);
}
void TransformEnum(Enumeration @enum)
{
TransformDeclaration(@enum);
foreach (var item in @enum.Items)
{
foreach (var pass in Passes.Passes)
pass.ProcessEnumItem(item);
}
}
static bool IsPassExcluded(Declaration decl, TranslationUnitPass pass)
{
var type = pass.GetType();
return decl.ExcludeFromPasses.Contains(type);
}
}
}
Loading…
Cancel
Save