Skip to content

Commit

Permalink
Updated Qt# to the latest C++#.
Browse files Browse the repository at this point in the history
Signed-off-by: Dimitar Dobrev <[email protected]>
  • Loading branch information
ddobrev committed Sep 13, 2016
1 parent fd6b15b commit fc165fa
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 87 deletions.
2 changes: 1 addition & 1 deletion QtSharp.CLI/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Baseclass.Contrib.Nuget.Output" version="2.1.0" targetFramework="net451" />
<package id="CppSharp" version="0.5.2" targetFramework="net451" developmentDependency="true" />
<package id="CppSharp" version="0.7.0" targetFramework="net451" developmentDependency="true" />
</packages>
18 changes: 9 additions & 9 deletions QtSharp/CompileInlinesPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using System.Linq;
using System.Text;
using CppSharp.AST;
using CppSharp.Parser;
using CppSharp.Passes;
using CppSharp;
using CppSharp.Parser;

namespace QtSharp
{
Expand All @@ -22,13 +22,13 @@ public CompileInlinesPass(string qmake, string make)

public override bool VisitLibrary(ASTContext context)
{
foreach (var module in Driver.Options.Modules)
foreach (var module in this.Context.Options.Modules)
{
string error;
const string qtVersionVariable = "QT_VERSION";
var qtVersion = ProcessHelper.Run(this.qmake, string.Format("-query {0}", qtVersionVariable), out error);
var qtVersionFile = Path.Combine(this.Driver.Options.OutputDir, qtVersionVariable);
var dir = Platform.IsMacOS ? this.Driver.Options.OutputDir : Path.Combine(this.Driver.Options.OutputDir, "release");
var qtVersionFile = Path.Combine(this.Context.Options.OutputDir, qtVersionVariable);
var dir = Platform.IsMacOS ? this.Context.Options.OutputDir : Path.Combine(this.Context.Options.OutputDir, "release");
var inlines = Path.GetFileName(string.Format("{0}{1}.{2}", Platform.IsWindows ? string.Empty : "lib",
module.InlinesLibraryName, Platform.IsMacOS ? "dylib" : "dll"));
var libFile = Path.Combine(dir, inlines);
Expand Down Expand Up @@ -56,8 +56,8 @@ public override bool VisitLibrary(ASTContext context)
if (parserResult.Kind == ParserResultKind.Success)
{
var nativeLibrary = CppSharp.ClangParser.ConvertLibrary(parserResult.Library);
this.Driver.Symbols.Libraries.Add(nativeLibrary);
this.Driver.Symbols.IndexSymbols();
this.Context.Symbols.Libraries.Add(nativeLibrary);
this.Context.Symbols.IndexSymbols();
parserResult.Library.Dispose();
}
}
Expand All @@ -68,7 +68,7 @@ public override bool VisitLibrary(ASTContext context)
private bool CompileInlines(Module module)
{
var pro = string.Format("{0}.pro", module.InlinesLibraryName);
var path = Path.Combine(this.Driver.Options.OutputDir, pro);
var path = Path.Combine(this.Context.Options.OutputDir, pro);
var proBuilder = new StringBuilder();
var qtModules = string.Join(" ", from header in module.Headers
where !header.EndsWith(".h", StringComparison.Ordinal)
Expand Down Expand Up @@ -104,11 +104,11 @@ private bool CompileInlines(Module module)
Console.WriteLine(error);
return false;
}
var makefile = File.Exists(Path.Combine(Driver.Options.OutputDir, "Makefile.Release")) ? "Makefile.Release" : "Makefile";
var makefile = File.Exists(Path.Combine(this.Context.Options.OutputDir, "Makefile.Release")) ? "Makefile.Release" : "Makefile";
if (Platform.IsMacOS)
{
// HACK: Clang does not support -fkeep-inline-functions so force compilation with (the real) GCC on OS X
var makefilePath = Path.Combine(Driver.Options.OutputDir, makefile);
var makefilePath = Path.Combine(this.Context.Options.OutputDir, makefile);
var script = new StringBuilder(File.ReadAllText(makefilePath));
var xcodePath = XcodeToolchain.GetXcodePath();
script.Replace(Path.Combine(xcodePath, "Contents", "Developer", "usr", "bin", "gcc"), "/usr/local/bin/gcc");
Expand Down
10 changes: 8 additions & 2 deletions QtSharp/GenerateEventEventsPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ namespace QtSharp
{
public class GenerateEventEventsPass : TranslationUnitPass
{
public GenerateEventEventsPass(Generator generator)
{
this.generator = generator;
}

public override bool VisitTranslationUnit(TranslationUnit unit)
{
if (!this.eventAdded)
{
this.Driver.Generator.OnUnitGenerated += this.OnUnitGenerated;
this.generator.OnUnitGenerated += this.OnUnitGenerated;
this.eventAdded = true;
}
return base.VisitTranslationUnit(unit);
Expand Down Expand Up @@ -78,7 +83,7 @@ public override bool VisitMethodDecl(Method method)
baseMethod.IsPure)
{
this.events.Add(method);
this.Driver.Options.ExplicitlyPatchedVirtualFunctions.Add(method.QualifiedOriginalName);
this.Context.Options.ExplicitlyPatchedVirtualFunctions.Add(method.QualifiedOriginalName);
}
}
}
Expand All @@ -87,5 +92,6 @@ public override bool VisitMethodDecl(Method method)

private bool eventAdded;
private readonly HashSet<Method> events = new HashSet<Method>();
private Generator generator;
}
}
12 changes: 9 additions & 3 deletions QtSharp/GenerateSignalEventsPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@ public class GenerateSignalEventsPass : TranslationUnitPass
{
private bool eventAdded;
private readonly HashSet<Event> events = new HashSet<Event>();
private Generator generator;

public GenerateSignalEventsPass(Generator generator)
{
this.generator = generator;
}

public override bool VisitTranslationUnit(TranslationUnit unit)
{
if (!this.eventAdded)
{
this.Driver.Generator.OnUnitGenerated += this.OnUnitGenerated;
this.generator.OnUnitGenerated += this.OnUnitGenerated;
this.eventAdded = true;
}
return base.VisitTranslationUnit(unit);
Expand Down Expand Up @@ -115,7 +121,7 @@ from e in @event.Parameters
var qtMetacall = (
from template in generatorOutput.Templates
from block in template.FindBlocks(CSharpBlockKind.Method)
where block.Declaration != null && block.Declaration.Name == "Qt_metacall" &&
where block.Declaration != null && block.Declaration.Name == "QtMetacall" &&
block.Declaration.Namespace.Name == "QObject"
select block).FirstOrDefault();
if (qtMetacall != null)
Expand Down Expand Up @@ -147,7 +153,7 @@ public override bool VisitClassDecl(Class @class)
var qtMetaCall = @class.FindMethod("qt_metacall");
if (qtMetaCall != null)
{
this.Driver.Options.ExplicitlyPatchedVirtualFunctions.Add(qtMetaCall.QualifiedOriginalName);
this.Context.Options.ExplicitlyPatchedVirtualFunctions.Add(qtMetaCall.QualifiedOriginalName);
}
return true;
}
Expand Down
12 changes: 6 additions & 6 deletions QtSharp/GetCommentsFromQtDocsPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public class GetCommentsFromQtDocsPass : TranslationUnitPass
public GetCommentsFromQtDocsPass(string docsPath, IEnumerable<string> modules)
{
this.documentation = new Documentation(docsPath, modules);
this.Options.VisitFunctionReturnType = false;
this.Options.VisitFunctionParameters = false;
this.Options.VisitEventParameters = false;
this.Options.VisitClassBases = false;
this.Options.VisitTemplateArguments = false;
this.Options.VisitClassFields = false;
this.VisitOptions.VisitFunctionReturnType = false;
this.VisitOptions.VisitFunctionParameters = false;
this.VisitOptions.VisitEventParameters = false;
this.VisitOptions.VisitClassBases = false;
this.VisitOptions.VisitTemplateArguments = false;
this.VisitOptions.VisitClassFields = false;
}

public override bool VisitLibrary(ASTContext context)
Expand Down
4 changes: 2 additions & 2 deletions QtSharp/QFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ public override string CSharpSignature(CSharpTypePrinterContext ctx)
return this.CSharpSignatureType(ctx).ToString();
}

public override void CSharpMarshalToNative(MarshalContext ctx)
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{
if (ctx.Parameter.Type.Desugar().IsAddress())
ctx.Return.Write("new global::System.IntPtr(&{0})", ctx.Parameter.Name);
else
ctx.Return.Write(ctx.Parameter.Name);
}

public override void CSharpMarshalToManaged(MarshalContext ctx)
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{
if (ctx.ReturnType.Type.Desugar().IsAddress())
{
Expand Down
13 changes: 6 additions & 7 deletions QtSharp/QString.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.CSharp;
using CppSharp.Types;

Expand All @@ -13,12 +12,12 @@ public override string CSharpSignature(CSharpTypePrinterContext ctx)
{
if (ctx.CSharpKind == CSharpTypePrinterContextKind.Native)
{
return ctx.Type.IsAddress() ? "QtCore.QString.Internal*" : "QtCore.QString.Internal";
return string.Format("QtCore.QString.{0}{1}", Helpers.InternalStruct, ctx.Type.IsAddress() ? "*" : string.Empty);
}
return "string";
}

public override void CSharpMarshalToNative(MarshalContext ctx)
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{
ctx.SupportBefore.WriteLine("var __stringPtr{0} = ReferenceEquals({1}, null) ? null : (ushort*) Marshal.StringToHGlobalUni({1}).ToPointer();",
ctx.ParameterIndex, ctx.Parameter.Name);
Expand All @@ -37,13 +36,13 @@ public override void CSharpMarshalToNative(MarshalContext ctx)
{
this.Type.TryGetClass(out @class);
}
this.typePrinter = this.typePrinter ?? (this.typePrinter = new CSharpTypePrinter(ctx.Driver));
this.typePrinter = this.typePrinter ?? (this.typePrinter = new CSharpTypePrinter(ctx.Context));
var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(this.typePrinter);
ctx.Return.Write("ReferenceEquals(__qstring{0}, null) ? new {1}.Internal() : *({1}.Internal*) (__qstring{0}.{2})",
ctx.ParameterIndex, qualifiedIdentifier, Helpers.InstanceIdentifier);
ctx.Return.Write("ReferenceEquals(__qstring{0}, null) ? new {1}.{2}() : *({1}.{2}*) (__qstring{0}.{3})",
ctx.ParameterIndex, qualifiedIdentifier, Helpers.InternalStruct, Helpers.InstanceIdentifier);
}

public override void CSharpMarshalToManaged(MarshalContext ctx)
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{
ctx.Return.Write("Marshal.PtrToStringUni(new IntPtr(QtCore.QString.{0}({1}).Utf16))",
Helpers.CreateInstanceIdentifier, ctx.ReturnVarName);
Expand Down
86 changes: 60 additions & 26 deletions QtSharp/QtSharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@ public ICollection<KeyValuePair<string, string>> GetVerifiedWrappedModules()

public void Preprocess(Driver driver, ASTContext lib)
{
foreach (var unit in lib.TranslationUnits.Where(u => u.FilePath != "<invalid>"))
foreach (var unit in lib.TranslationUnits.Where(u => u.IsValid))
{
IgnorePrivateDeclarations(unit);
// HACK: work around https://github.com/mono/CppSharp/issues/677
if (unit.FileName == "locale_classes.tcc")
{
unit.ExplicitlyIgnore();
}
else
{
IgnorePrivateDeclarations(unit);
}
}
lib.SetClassAsValueType("QByteArray");
lib.SetClassAsValueType("QListData");
lib.SetClassAsValueType("QListData::Data");
lib.SetClassAsValueType("QLocale");
lib.SetClassAsValueType("QModelIndex");
lib.SetClassAsValueType("QPoint");
Expand All @@ -51,8 +57,6 @@ public void Preprocess(Driver driver, ASTContext lib)
lib.SetClassAsValueType("QGenericArgument");
lib.SetClassAsValueType("QGenericReturnArgument");
lib.SetClassAsValueType("QVariant");
lib.IgnoreClassMethodWithName("QString", "fromStdWString");
lib.IgnoreClassMethodWithName("QString", "toStdWString");

// QString is type-mapped to string so we only need two methods for the conversion
var qString = lib.FindCompleteClass("QString");
Expand Down Expand Up @@ -133,6 +137,34 @@ where string.IsNullOrEmpty(@enum.Name)
{
enumeration.Name = "TypeEnum";
}

// HACK: work around https://github.com/mono/CppSharp/issues/692
foreach (var name in new[] { "QImage", "QPixmap" })
{
var @class = lib.FindCompleteClass(name);
var ctorWithArray = @class.Constructors.FirstOrDefault(
c => c.Parameters.Count == 1 && c.Parameters[0].Type.Desugar() is ArrayType);
if (ctorWithArray != null)
{
ctorWithArray.ExplicitlyIgnore();
}
}
foreach (var name in new[] { "QGraphicsScene", "QGraphicsView" })
{
var @class = lib.FindCompleteClass(name);
var drawItems = @class.Methods.FirstOrDefault(m => m.OriginalName == "drawItems");
if (drawItems != null)
{
drawItems.ExplicitlyIgnore();
}
}
lib.FindCompleteClass("QAbstractPlanarVideoBuffer").ExplicitlyIgnore();
var qAbstractVideoBuffer = lib.FindCompleteClass("QAbstractVideoBuffer");
var mapPlanes = qAbstractVideoBuffer.Methods.FirstOrDefault(m => m.OriginalName == "mapPlanes");
if (mapPlanes != null)
{
mapPlanes.ExplicitlyIgnore();
}
}

private static void IgnorePrivateDeclarations(DeclarationContext unit)
Expand Down Expand Up @@ -163,15 +195,15 @@ private static void IgnorePrivateDeclaration(Declaration declaration)

public void Postprocess(Driver driver, ASTContext lib)
{
new ClearCommentsPass().VisitLibrary(driver.ASTContext);
new ClearCommentsPass().VisitLibrary(driver.Context.ASTContext);
var modules = this.qtInfo.LibFiles.Select(l => GetModuleNameFromLibFile(l));
var s = System.Diagnostics.Stopwatch.StartNew();
new GetCommentsFromQtDocsPass(this.qtInfo.Docs, modules).VisitLibrary(driver.ASTContext);
new GetCommentsFromQtDocsPass(this.qtInfo.Docs, modules).VisitLibrary(driver.Context.ASTContext);
System.Console.WriteLine("Documentation done in: {0}", s.Elapsed);
new CaseRenamePass(
RenameTargets.Function | RenameTargets.Method | RenameTargets.Property | RenameTargets.Delegate |
RenameTargets.Field | RenameTargets.Variable,
RenameCasePattern.UpperCamelCase).VisitLibrary(driver.ASTContext);
RenameCasePattern.UpperCamelCase).VisitLibrary(driver.Context.ASTContext);

var qChar = lib.FindCompleteClass("QChar");
var op = qChar.FindOperator(CXXOperatorKind.ExplicitConversion)
Expand Down Expand Up @@ -203,18 +235,18 @@ public void Postprocess(Driver driver, ASTContext lib)

public void Setup(Driver driver)
{
driver.ParserOptions.MicrosoftMode = false;
driver.ParserOptions.NoBuiltinIncludes = true;
driver.ParserOptions.TargetTriple = this.qtInfo.Target;
driver.ParserOptions.Abi = CppAbi.Itanium;
driver.ParserOptions.Verbose = true;
driver.ParserOptions.addDefines("__float128=void");
driver.Options.GeneratorKind = GeneratorKind.CSharp;
driver.Options.MicrosoftMode = false;
driver.Options.NoBuiltinIncludes = true;
driver.Options.TargetTriple = this.qtInfo.Target;
driver.Options.Abi = CppAbi.Itanium;
driver.Options.Verbose = true;
driver.Options.GenerateInterfacesForMultipleInheritance = true;
driver.Options.GeneratePropertiesAdvanced = true;
driver.Options.UnityBuild = true;
driver.Options.IgnoreParseWarnings = true;
driver.Options.CheckSymbols = true;
driver.Options.GenerateSingleCSharpFile = true;
driver.Options.GenerateInlines = true;
driver.Options.CompileCode = true;
driver.Options.GenerateDefaultValuesForArguments = true;
Expand Down Expand Up @@ -266,25 +298,27 @@ public void Setup(Driver driver)
module.CodeFiles.Add(Path.Combine(dir, "QObject.cs"));
module.CodeFiles.Add(Path.Combine(dir, "QChar.cs"));
module.CodeFiles.Add(Path.Combine(dir, "QEvent.cs"));
module.CodeFiles.Add(Path.Combine(dir, "_iobuf.cs"));
}

driver.Options.Modules.Add(module);
}

foreach (var systemIncludeDir in this.qtInfo.SystemIncludeDirs)
driver.Options.addSystemIncludeDirs(systemIncludeDir);
driver.ParserOptions.addSystemIncludeDirs(systemIncludeDir);

if (Platform.IsMacOS)
{
foreach (var frameworkDir in this.qtInfo.FrameworkDirs)
driver.Options.addArguments(string.Format("-F{0}", frameworkDir));
driver.Options.addArguments(string.Format("-F{0}", qtInfo.Libs));
driver.ParserOptions.addArguments(string.Format("-F{0}", frameworkDir));
driver.ParserOptions.addArguments(string.Format("-F{0}", qtInfo.Libs));
}

driver.Options.addIncludeDirs(qtInfo.Headers);

driver.Options.addLibraryDirs(Platform.IsWindows ? qtInfo.Bins : qtInfo.Libs);
driver.ParserOptions.addIncludeDirs(qtInfo.Headers);

driver.ParserOptions.addLibraryDirs(Platform.IsWindows ? qtInfo.Bins : qtInfo.Libs);

// Qt defines its own GUID with the same header guard as the system GUID, so ensure the system GUID is read first
driver.Project.AddFile("guiddef.h");
}

public static string GetModuleNameFromLibFile(string libFile)
Expand All @@ -299,10 +333,10 @@ public static string GetModuleNameFromLibFile(string libFile)

public void SetupPasses(Driver driver)
{
driver.TranslationUnitPasses.AddPass(new CompileInlinesPass(this.qtInfo.QMake, this.qtInfo.Make));
driver.TranslationUnitPasses.AddPass(new GenerateSignalEventsPass());
driver.TranslationUnitPasses.AddPass(new GenerateEventEventsPass());
driver.TranslationUnitPasses.AddPass(new RemoveQObjectMembersPass());
driver.Context.TranslationUnitPasses.AddPass(new CompileInlinesPass(this.qtInfo.QMake, this.qtInfo.Make));
driver.Context.TranslationUnitPasses.AddPass(new GenerateSignalEventsPass(driver.Generator));
driver.Context.TranslationUnitPasses.AddPass(new GenerateEventEventsPass(driver.Generator));
driver.Context.TranslationUnitPasses.AddPass(new RemoveQObjectMembersPass());
}

private readonly QtInfo qtInfo;
Expand Down
Loading

0 comments on commit fc165fa

Please sign in to comment.