diff --git a/compiler/llvm/aasmllvm.pas b/compiler/llvm/aasmllvm.pas index 3d07aea8ad..52dc061d4b 100644 --- a/compiler/llvm/aasmllvm.pas +++ b/compiler/llvm/aasmllvm.pas @@ -110,6 +110,7 @@ interface constructor blockaddress(fun, lab: tasmsymbol); constructor landingpad(dst:tregister;def:tdef;firstclause:taillvm); constructor exceptclause(op:tllvmop;def:tdef;kind:TAsmSymbol;nextclause:taillvm); + constructor cleanupclause; { e.g. dst = call retsize name (paras) } constructor call_size_name_paras(callpd: tdef; dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist); @@ -486,7 +487,10 @@ uses begin if llvmopcode<>la_landingpad then internalerror(2018052001); - clause:=taillvm.exceptclause(op,voidpointertype,nil,nil); + if op<>la_cleanup then + clause:=taillvm.exceptclause(op,voidpointertype,nil,nil) + else + clause:=taillvm.cleanupclause; lastclause:=self; while assigned(lastclause.oper[2]^.ai) do lastclause:=taillvm(lastclause.oper[2]^.ai); @@ -1090,6 +1094,13 @@ uses end; + constructor taillvm.cleanupclause; + begin + create_llvm(la_cleanup); + ops:=0; + end; + + constructor taillvm.call_size_name_paras(callpd: tdef; dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist); begin create_llvm(la_call); diff --git a/compiler/llvm/agllvm.pas b/compiler/llvm/agllvm.pas index 149a389ac3..a3cea5449f 100644 --- a/compiler/llvm/agllvm.pas +++ b/compiler/llvm/agllvm.pas @@ -577,7 +577,8 @@ implementation la_cmpxchg, la_atomicrmw, la_catch, - la_filter: + la_filter, + la_cleanup: begin { instructions that never have a result } end; @@ -694,7 +695,7 @@ implementation owner.writer.AsmWrite(getopstr(taillvm(hp).oper[i]^,op in [la_load,la_store])); if (taillvm(hp).oper[i]^.typ in [top_def,top_cond,top_fpcond]) or - (op in [la_call,la_invoke,la_landingpad,la_catch,la_filter]) then + (op in [la_call,la_invoke,la_landingpad,la_catch,la_filter,la_cleanup]) then sep :=' ' else sep:=', '; diff --git a/compiler/llvm/itllvm.pas b/compiler/llvm/itllvm.pas index 466f3b8c67..fb7709c167 100644 --- a/compiler/llvm/itllvm.pas +++ b/compiler/llvm/itllvm.pas @@ -62,6 +62,7 @@ interface 'type', { type definition } 'catch', { catch exception } 'filter', { exception filter } + 'cleanup', { exception cleanup/finally } 'invalid1', { la_x_to_inttoptr } 'invalid2', { la_ptrtoint_to_x } 'asm' { la_asmblock } diff --git a/compiler/llvm/llvmbase.pas b/compiler/llvm/llvmbase.pas index bd31677062..1fe226086d 100644 --- a/compiler/llvm/llvmbase.pas +++ b/compiler/llvm/llvmbase.pas @@ -70,6 +70,7 @@ interface la_type, { type definition } la_catch, { catch clause of a landingpad } la_filter, { filter clause of a landingpad } + la_cleanup, { cleanup clause of a landingpad (finally) } la_x_to_inttoptr, { have to convert something first to int before it can be converted to a pointer } la_ptrtoint_to_x, { have to convert a pointer first to int before it can be converted to something else } la_asmblock