/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="options"> /// </param> /// <param name="finallyOrFaultClause"> /// </param> /// <param name="catch"> /// </param> /// <param name="filter"> /// </param> /// <param name="exceptionAllocationResultNumber"> /// </param> public static void WriteLandingPad( this LlvmWriter llvmWriter, OpCodePart opCode, LandingPadOptions options, CatchOfFinallyClause finallyOrFaultClause, IType[] @catch = null, int[] filter = null, int?exceptionAllocationResultNumber = null) { var writer = llvmWriter.Output; llvmWriter.WriteLandingPadVariables(); var landingPadResult = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Byte.ToPointerType()); writer.WriteLine( "landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)"); if (options.HasFlag(LandingPadOptions.Cleanup)) { writer.Indent++; writer.WriteLine("cleanup"); writer.Indent--; } if (options.HasFlag(LandingPadOptions.EmptyFilter)) { writer.Indent++; writer.WriteLine("filter [0 x i8*] zeroinitializer"); writer.Indent--; } if (@catch != null && @catch.Any()) { foreach (var catchType in @catch) { writer.Indent++; if (catchType != null) { writer.Write("catch i8* bitcast ("); catchType.WriteRttiPointerClassInfoDeclaration(writer); writer.WriteLine("* @\"{0}\" to i8*)", catchType.GetRttiPointerInfoName()); llvmWriter.typeRttiPointerDeclRequired.Add(catchType); llvmWriter.CheckIfExternalDeclarationIsRequired(catchType); } else { writer.Write("catch i8* null"); } writer.Indent--; } } else if (finallyOrFaultClause != null) { // default catch with rethrowing it writer.Indent++; writer.WriteLine("catch i8* null"); writer.Indent--; finallyOrFaultClause.EmptyFinallyRethrowRequired = true; } var getErrorObjectResultNumber = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Byte.ToPointerType()); writer.WriteLine("extractvalue {1} {0}, 0", landingPadResult, "{ i8*, i32 }"); writer.WriteLine("store i8* {0}, i8** %.error_object", getErrorObjectResultNumber); var getErrorTypeIdResultNumber = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Int32); writer.WriteLine("extractvalue {1} {0}, 1", landingPadResult, "{ i8*, i32 }"); writer.Write("store i32 {0}, i32* %.error_typeid", getErrorTypeIdResultNumber); if (exceptionAllocationResultNumber.HasValue) { writer.WriteLine(string.Empty); writer.Write("call void @__cxa_free_exception(i8* {0})", exceptionAllocationResultNumber.Value); } opCode.Result = landingPadResult; }
/// <summary> /// </summary> /// <param name="llvmWriter"> /// </param> /// <param name="opCode"> /// </param> /// <param name="options"> /// </param> /// <param name="finallyOrFaultClause"> /// </param> /// <param name="catch"> /// </param> /// <param name="filter"> /// </param> /// <param name="exceptionAllocationResultNumber"> /// </param> public static void WriteLandingPad( this LlvmWriter llvmWriter, OpCodePart opCode, LandingPadOptions options, CatchOfFinallyClause finallyOrFaultClause, IType[] @catch = null, int[] filter = null, int? exceptionAllocationResultNumber = null) { var writer = llvmWriter.Output; llvmWriter.WriteLandingPadVariables(); var landingPadResult = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Byte.ToPointerType()); writer.WriteLine( "landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)"); if (options.HasFlag(LandingPadOptions.Cleanup)) { writer.Indent++; writer.WriteLine("cleanup"); writer.Indent--; } if (options.HasFlag(LandingPadOptions.EmptyFilter)) { writer.Indent++; writer.WriteLine("filter [0 x i8*] zeroinitializer"); writer.Indent--; } if (@catch != null && @catch.Any()) { foreach (var catchType in @catch) { writer.Indent++; if (catchType != null) { writer.Write("catch i8* bitcast ("); catchType.WriteRttiPointerClassInfoDeclaration(writer); writer.WriteLine("* @\"{0}\" to i8*)", catchType.GetRttiPointerInfoName()); llvmWriter.typeRttiPointerDeclRequired.Add(catchType); llvmWriter.CheckIfExternalDeclarationIsRequired(catchType); } else { writer.Write("catch i8* null"); } writer.Indent--; } } else if (finallyOrFaultClause != null) { // default catch with rethrowing it writer.Indent++; writer.WriteLine("catch i8* null"); writer.Indent--; finallyOrFaultClause.EmptyFinallyRethrowRequired = true; } var getErrorObjectResultNumber = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Byte.ToPointerType()); writer.WriteLine("extractvalue {1} {0}, 0", landingPadResult, "{ i8*, i32 }"); writer.WriteLine("store i8* {0}, i8** %.error_object", getErrorObjectResultNumber); var getErrorTypeIdResultNumber = llvmWriter.WriteSetResultNumber( opCode, llvmWriter.System.System_Int32); writer.WriteLine("extractvalue {1} {0}, 1", landingPadResult, "{ i8*, i32 }"); writer.Write("store i32 {0}, i32* %.error_typeid", getErrorTypeIdResultNumber); if (exceptionAllocationResultNumber.HasValue) { writer.WriteLine(string.Empty); writer.Write("call void @__cxa_free_exception(i8* {0})", exceptionAllocationResultNumber.Value); } opCode.Result = landingPadResult; }