Skip to content

Commit 0100990

Browse files
Build Agenttritao
authored andcommitted
Add blocks for ctor, dtor, and finalizer bodies. Add constructor that takes a bool from the caller to indicate if the callee should own the pointer passed to it or not
1 parent 648b1fd commit 0100990

File tree

4 files changed

+47
-15
lines changed

4 files changed

+47
-15
lines changed

src/Generator/Generators/CLI/CLIHeaders.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ public void GenerateClassConstructors(Class @class, string nativeType)
376376

377377
// Output a default constructor that takes the native pointer.
378378
WriteLine("{0}({1} native);", @class.Name, nativeType);
379+
WriteLine("{0}({1} native, bool ownNativeInstance);", @class.Name, nativeType);
379380
WriteLine("static {0}^ {1}(::System::IntPtr native);",
380381
@class.Name, Helpers.CreateInstanceIdentifier);
381382

src/Generator/Generators/CLI/CLIMarshal.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,19 @@ public override bool VisitClassDecl(Class @class)
275275
instance += Context.ReturnVarName;
276276
var needsCopy = Context.MarshalKind != MarshalKind.NativeField;
277277

278+
bool ownNativeInstance = false;
279+
278280
if (@class.IsRefType && needsCopy)
279281
{
280282
var name = Generator.GeneratedIdentifier(Context.ReturnVarName);
281283
Context.Before.WriteLine("auto {0} = new ::{1}({2});", name,
282284
@class.QualifiedOriginalName, Context.ReturnVarName);
283285
instance = name;
286+
287+
ownNativeInstance = true;
284288
}
285289

286-
WriteClassInstance(@class, instance);
290+
WriteClassInstance(@class, instance, ownNativeInstance);
287291
return true;
288292
}
289293

@@ -295,15 +299,15 @@ public string QualifiedIdentifier(Declaration decl)
295299
return decl.QualifiedName;
296300
}
297301

298-
public void WriteClassInstance(Class @class, string instance)
302+
public void WriteClassInstance(Class @class, string instance, bool ownNativeInstance = false)
299303
{
300304
if (@class.IsRefType)
301305
Context.Return.Write("({0} == nullptr) ? nullptr : gcnew ",
302306
instance);
303307

304308
Context.Return.Write("{0}(", QualifiedIdentifier(@class));
305309
Context.Return.Write("(::{0}*)", @class.QualifiedOriginalName);
306-
Context.Return.Write("{0})", instance);
310+
Context.Return.Write("{0}{1})", instance, ownNativeInstance ? ", true" : "");
307311
}
308312

309313
public override bool VisitFieldDecl(Field field)

src/Generator/Generators/CLI/CLISources.cs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ private void GenerateClassDestructor(Class @class)
250250
WriteLine("{0}::~{1}()", QualifiedIdentifier(@class), @class.Name);
251251
WriteOpenBraceAndIndent();
252252

253+
PushBlock(BlockKind.DestructorBody, @class);
254+
253255
if (CLIGenerator.ShouldGenerateClassNativeField(@class))
254256
{
255257
WriteLine("delete NativePtr;");
@@ -264,6 +266,8 @@ private void GenerateClassDestructor(Class @class)
264266
UnindentAndWriteCloseBrace();
265267
}
266268

269+
PopBlock();
270+
267271
UnindentAndWriteCloseBrace();
268272

269273
PopBlock(NewLineKind.BeforeNextBlock);
@@ -276,9 +280,13 @@ private void GenerateClassFinalizer(Class @class)
276280
WriteLine("{0}::!{1}()", QualifiedIdentifier(@class), @class.Name);
277281
WriteOpenBraceAndIndent();
278282

283+
PushBlock(BlockKind.FinalizerBody, @class);
284+
279285
if (CLIGenerator.ShouldGenerateClassNativeField(@class))
280286
WriteLine("delete NativePtr;");
281287

288+
PopBlock();
289+
282290
UnindentAndWriteCloseBrace();
283291

284292
PopBlock(NewLineKind.BeforeNextBlock);
@@ -618,28 +626,30 @@ private void GenerateVariable(Variable variable, Class @class)
618626
GeneratePropertySetter(variable, @class, variable.Name, variable.Type);
619627
}
620628

621-
private void GenerateClassConstructor(Class @class)
629+
private void GenerateClassConstructor(Class @class, bool withOwnNativeInstanceParam = false)
622630
{
623631
string qualifiedIdentifier = QualifiedIdentifier(@class);
624632

625633
Write("{0}::{1}(", qualifiedIdentifier, @class.Name);
626634

627635
var nativeType = string.Format("::{0}*", @class.QualifiedOriginalName);
628-
WriteLine("{0} native)", nativeType);
636+
WriteLine(!withOwnNativeInstanceParam ? "{0} native)" : "{0} native, const bool ownNativeInstance)", nativeType);
629637

630-
var hasBase = GenerateClassConstructorBase(@class);
638+
var hasBase = GenerateClassConstructorBase(@class, null, withOwnNativeInstanceParam);
631639

632640
if (CLIGenerator.ShouldGenerateClassNativeField(@class))
633641
{
634642
Indent();
635643
Write(hasBase ? "," : ":");
636644
Unindent();
637645

638-
WriteLine(" {0}(false)", Helpers.OwnsNativeInstanceIdentifier);
646+
WriteLine(!withOwnNativeInstanceParam ? " {0}(false)" : " {0}(ownNativeInstance)", Helpers.OwnsNativeInstanceIdentifier);
639647
}
640648

641649
WriteOpenBraceAndIndent();
642650

651+
PushBlock(BlockKind.ConstructorBody, @class);
652+
643653
const string nativePtr = "native";
644654

645655
if (@class.IsRefType)
@@ -654,16 +664,24 @@ private void GenerateClassConstructor(Class @class)
654664
GenerateStructMarshaling(@class, nativePtr + "->");
655665
}
656666

667+
PopBlock();
668+
657669
UnindentAndWriteCloseBrace();
658-
NewLine();
659-
WriteLine("{0}^ {0}::{1}(::System::IntPtr native)", qualifiedIdentifier, Helpers.CreateInstanceIdentifier);
660670

661-
WriteOpenBraceAndIndent();
671+
if (!withOwnNativeInstanceParam)
672+
{
673+
NewLine();
674+
WriteLine("{0}^ {0}::{1}(::System::IntPtr native)", qualifiedIdentifier, Helpers.CreateInstanceIdentifier);
662675

663-
WriteLine("return gcnew ::{0}(({1}) native.ToPointer());", qualifiedIdentifier, nativeType);
676+
WriteOpenBraceAndIndent();
664677

665-
UnindentAndWriteCloseBrace();
666-
NewLine();
678+
WriteLine("return gcnew ::{0}(({1}) native.ToPointer());", qualifiedIdentifier, nativeType);
679+
680+
UnindentAndWriteCloseBrace();
681+
NewLine();
682+
683+
GenerateClassConstructor(@class, true);
684+
}
667685
}
668686

669687
private void GenerateStructMarshaling(Class @class, string nativeVar)
@@ -701,7 +719,7 @@ private void GenerateStructMarshaling(Class @class, string nativeVar)
701719
}
702720
}
703721

704-
private bool GenerateClassConstructorBase(Class @class, Method method = null)
722+
private bool GenerateClassConstructorBase(Class @class, Method method = null, bool withOwnNativeInstanceParam = false)
705723
{
706724
var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsGenerated;
707725
if (!hasBase)
@@ -720,7 +738,7 @@ private bool GenerateClassConstructorBase(Class @class, Method method = null)
720738
var nativeTypeName = baseClass.Visit(cppTypePrinter);
721739
Write("({0}*)", nativeTypeName);
722740

723-
WriteLine("{0})", method != null ? "nullptr" : "native");
741+
WriteLine("{0}{1})", method != null ? "nullptr" : "native", !withOwnNativeInstanceParam ? "" : ", ownNativeInstance");
724742

725743
Unindent();
726744
}
@@ -754,7 +772,11 @@ public void GenerateMethod(Method method, Class @class)
754772
PushBlock(BlockKind.MethodBody, method);
755773

756774
if (method.IsConstructor && @class.IsRefType)
775+
{
776+
PushBlock(BlockKind.ConstructorBody, @class);
777+
757778
WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier);
779+
}
758780

759781
if (method.IsProxy)
760782
goto SkipImpl;
@@ -770,6 +792,8 @@ public void GenerateMethod(Method method, Class @class)
770792
GenerateFunctionParams(@params);
771793
WriteLine(");");
772794
}
795+
796+
PopBlock();
773797
}
774798
else
775799
{

src/Generator/Utils/BlockGenerator.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public enum BlockKind
5050
Destructor,
5151
AccessSpecifier,
5252
Fields,
53+
ConstructorBody,
54+
DestructorBody,
55+
FinalizerBody
5356
}
5457

5558
[DebuggerDisplay("{Kind} | {Object}")]

0 commit comments

Comments
 (0)