Browse Source

Added better support for wrapping of static variables.

pull/1/head
triton 13 years ago
parent
commit
23ca4b2614
  1. 2
      src/Bridge/Variable.cs
  2. 1
      src/Generator/Diagnostics.cs
  3. 120
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  4. 3
      src/Parser/Parser.cpp

2
src/Bridge/Variable.cs

@ -12,5 +12,7 @@ namespace Cxxi
public Type Type { get { return QualifiedType.Type; } } public Type Type { get { return QualifiedType.Type; } }
public QualifiedType QualifiedType { get; set; } public QualifiedType QualifiedType { get; set; }
public string Mangled { get; set; }
} }
} }

1
src/Generator/Diagnostics.cs

@ -5,6 +5,7 @@ namespace Cxxi
public enum DiagnosticId public enum DiagnosticId
{ {
InvalidOperatorOverload InvalidOperatorOverload
SymbolNotFound
} }
public enum DiagnosticKind public enum DiagnosticKind

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

@ -254,6 +254,7 @@ namespace Cxxi.Generators.CSharp
GenerateClassConstructors(@class); GenerateClassConstructors(@class);
GenerateClassFields(@class); GenerateClassFields(@class);
GenerateClassMethods(@class); GenerateClassMethods(@class);
GenerateClassVariables(@class);
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -478,18 +479,74 @@ namespace Cxxi.Generators.CSharp
WriteCloseBraceIndent(); WriteCloseBraceIndent();
} }
private string GetPropertyLocation<T>(T decl, Class @class) enum PropertyMethodKind
where T : Declaration, ITypedDecl {
Getter,
Setter
}
private string GetFieldLocation(Field field, string instance,
out bool isRefClass)
{
isRefClass = false;
var fieldType = field.Type.Desugar();
var type = field.Type.ToString() + "*";
Class fieldClass;
if (fieldType.IsTagDecl(out fieldClass) && fieldClass.IsRefType)
isRefClass = true;
TagType tagType;
if (fieldType.IsPointerTo(out tagType)
&& tagType.IsTagDecl(out fieldClass) && fieldClass.IsRefType)
isRefClass = true;
if (CSharpTypePrinter.IsConstCharString(field.QualifiedType))
isRefClass = true;
if (isRefClass)
type = "void**";
var location = string.Format("*({0}) ({1} + {2})",
type, instance, field.OffsetInBytes);
return location;
}
private string GetPropertyLocation<T>(T decl, PropertyMethodKind kind,
out bool isRefClass) where T : Declaration, ITypedDecl
{ {
isRefClass = false;
if (decl is Variable) if (decl is Variable)
{ {
return string.Format("::{0}::{1}", var @var = decl as Variable;
@class.QualifiedOriginalName, decl.OriginalName);
var symbol = @var.Mangled;
if (!Driver.LibrarySymbols.FindSymbol(ref symbol))
{
Driver.Diagnostics.EmitError(DiagnosticId.SymbolNotFound,
"symbol \"{0}\" was not found", symbol);
throw new SymbolNotFoundException(symbol);
}
NativeLibrary library;
Driver.LibrarySymbols.FindLibraryBySymbol(symbol, out library);
return string.Format("Cxxi.SymbolResolver.ResolveSymbol(\"{0}\", \"{1}\")",
Path.GetFileNameWithoutExtension(library.FileName), symbol);
} }
var field = decl as Field; var field = decl as Field;
return string.Format("*({0}*) (Instance + {1})", field.Type,
field.OffsetInBytes); var location = GetFieldLocation(field, "Instance",
out isRefClass);
if (isRefClass && kind == PropertyMethodKind.Getter)
location = string.Format("new System.IntPtr({0})", location);
return location;
} }
private void GeneratePropertySetter<T>(T decl, Class @class) private void GeneratePropertySetter<T>(T decl, Class @class)
@ -513,12 +570,19 @@ namespace Cxxi.Generators.CSharp
var marshal = new CSharpMarshalManagedToNativePrinter(ctx); var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
param.Visit(marshal); param.Visit(marshal);
var variable = GetPropertyLocation(decl, @class); bool isRefClass;
var variable = GetPropertyLocation(decl, PropertyMethodKind.Setter,
out isRefClass);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
WriteLine("{0} = {1};", variable, marshal.Context.Return); Write("{0} = {1}", variable, marshal.Context.Return);
if (isRefClass)
Write(".ToPointer()");
WriteLine(";");
WriteCloseBraceIndent(); WriteCloseBraceIndent();
} }
@ -529,7 +593,9 @@ namespace Cxxi.Generators.CSharp
WriteLine("get"); WriteLine("get");
WriteStartBraceIndent(); WriteStartBraceIndent();
var variable = GetPropertyLocation(decl, @class); bool isRefClass;
var variable = GetPropertyLocation(decl, PropertyMethodKind.Getter,
out isRefClass);
var ctx = new CSharpMarshalContext(Driver) var ctx = new CSharpMarshalContext(Driver)
{ {
@ -583,6 +649,36 @@ namespace Cxxi.Generators.CSharp
} }
} }
public void GenerateClassVariables(Class @class)
{
foreach (var variable in @class.Variables)
{
if (variable.Ignore) continue;
if (variable.Access != AccessSpecifier.Public)
continue;
var type = variable.Type;
NewLineIfNeeded();
GenerateVariable(@class, type, variable);
NeedNewLine();
}
}
private void GenerateVariable(Class @class, Type type, Variable variable)
{
WriteLine("public static {0} {1}", type, variable.Name);
WriteStartBraceIndent();
GeneratePropertyGetter(variable, @class);
if (!variable.QualifiedType.Qualifiers.IsConst)
GeneratePropertySetter(variable, @class);
WriteCloseBraceIndent();
}
#endregion #endregion
#region Constructors #region Constructors
@ -1280,4 +1376,10 @@ namespace Cxxi.Generators.CSharp
string.Join(", ", @params)); string.Join(", ", @params));
} }
} }
internal class SymbolNotFoundException : Exception
{
public SymbolNotFoundException(string msg) : base(msg)
{}
}
} }

3
src/Parser/Parser.cpp

@ -1353,6 +1353,9 @@ Cxxi::Variable^ Parser::WalkVariable(clang::VarDecl *VD)
auto TL = VD->getTypeSourceInfo()->getTypeLoc(); auto TL = VD->getTypeSourceInfo()->getTypeLoc();
Var->QualifiedType = GetQualifiedType(VD->getType(), WalkType(VD->getType(), &TL)); Var->QualifiedType = GetQualifiedType(VD->getType(), WalkType(VD->getType(), &TL));
auto Mangled = GetDeclMangledName(VD, TargetCXXABI::Microsoft, /*IsDependent=*/false);
Var->Mangled = marshalString<E_UTF8>(Mangled);
return Var; return Var;
} }

Loading…
Cancel
Save