diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index 0b52e3ac36..0e0bf32022 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -46,6 +46,8 @@ interface { subroutine handling } procedure test_protected_sym(sym : psym); procedure test_protected(p : ptree); + function valid_for_formal_var(p : ptree) : boolean; + function valid_for_formal_const(p : ptree) : boolean; function is_procsym_load(p:Ptree):boolean; function is_procsym_call(p:Ptree):boolean; function is_assignment_overloaded(from_def,to_def : pdef) : boolean; @@ -607,7 +609,38 @@ implementation end; end; - + function valid_for_formal_var(p : ptree) : boolean; + var + v : boolean; + begin + case p^.treetype of + loadn : v:=(p^.symtableentry^.typ in [typedconstsym,varsym]); + typeconvn : v:=valid_for_formal_var(p^.left); + typen : v:=false; + derefn,subscriptn,vecn, + funcretn,selfn : v:=true; + { procvars are callnodes first } + calln : v:=assigned(p^.right) and not assigned(p^.left); + { should this depend on mode ? } + addrn : v:=true; + { no other node accepted (PM) } + else v:=false; + end; + valid_for_formal_var:=v; + end; + + function valid_for_formal_const(p : ptree) : boolean; + var + v : boolean; + begin + { p must have been firstpass'd before } + { accept about anything but not a statement ! } + v:=true; + if not assigned(p^.resulttype) or (p^.resulttype=voiddef) then + v:=false; + valid_for_formal_const:=v; + end; + function is_procsym_load(p:Ptree):boolean; begin is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or @@ -650,7 +683,10 @@ implementation end. { $Log$ - Revision 1.20 1999-04-15 08:56:27 peter + Revision 1.21 1999-04-21 16:31:40 pierre + ra386att.pas + + Revision 1.20 1999/04/15 08:56:27 peter * fixed bool-bool conversion Revision 1.19 1999/03/24 23:17:02 peter diff --git a/compiler/ra386att.pas b/compiler/ra386att.pas index dc83ce646f..dac3d4f39c 100644 --- a/compiler/ra386att.pas +++ b/compiler/ra386att.pas @@ -2960,6 +2960,21 @@ end; Until actasmtoken=AS_SEPARATOR; end; +Procedure Check_arg(const op : toperand); + var + sym : pvarsym; +begin + if (op.ref.base=procinfo.framepointer) and + (op.ref.offset>=procinfo.call_offset) and + assigned(aktprocsym^.definition^.parast) then + begin + sym:=aktprocsym^.definition^.parast^.find_at_offset(op.ref.offset); + if assigned(sym) then + Message2(assem_d_arg_offset,tostr(op.ref.offset)+'('+att_reg2str[procinfo.framepointer]+')',sym^.name) + else + Message1(assem_d_arg_unfound_offset,tostr(op.ref.offset)+'('+att_reg2str[procinfo.framepointer]+')'); + end; +end; Procedure BuildReference(var Instr: TInstruction); @@ -3034,6 +3049,7 @@ Begin if actasmtoken=AS_RPAREN then Begin Consume_RParen; + Check_arg(instr.operands[operandnum]); exit; end; { (reg,reg .. } @@ -3150,6 +3166,7 @@ var tempstr: string; expr: string; lab: Pasmlabel; + is_var : boolean; hl: plabel; tsize,l, toffset : longint; @@ -3190,7 +3207,20 @@ Begin Begin Consume(AS_STAR); InitAsmRef(instr); - if not CreateVarInstr(instr,actasmpattern,operandnum) then + { allow call *%edi or jmp *%eax } + { which is the correct ATT syntax !!! (PM) } + if actasmtoken=AS_REGISTER then + begin + if (instr.getinstruction=A_CALL) or (instr.getinstruction=A_JMP) and (operandnum=1) then + begin + instr.operands[operandnum].operandtype:=OPR_REGISTER; + instr.operands[operandnum].reg:=FindRegister(actasmpattern); + consume(AS_REGISTER); + end + else + Message(assem_e_invalid_opcode_and_operand); + end + else if not CreateVarInstr(instr,actasmpattern,operandnum) then Message(assem_e_syn_opcode_operand); end; @@ -3252,7 +3282,10 @@ Begin Begin { context for scanner } initAsmRef(instr); - if not CreateVarInstr(instr,actasmpattern,operandnum) then + is_var:=false; + if CreateVarInstr(instr,actasmpattern,operandnum) then + is_var:=true + else Begin { look for special symbols ... } if actasmpattern = '__RESULT' then @@ -3323,6 +3356,16 @@ Begin end; if actasmtoken=AS_LPAREN then BuildReference(instr); + { allow leal l+2,%eax } + + if is_var and (actasmtoken in [AS_PLUS,AS_MINUS]) and + (instr.operands[operandnum].ref.base=R_NO) and + (instr.operands[operandnum].ref.index=R_NO) then + Begin + Instr.Operands[OperandNum].Ref.Offset := + Instr.Operands[OperandNum].Ref.Offset + +BuildConstExpression(false,false); + End; end; end; { end if } end; { end if } @@ -3924,7 +3967,10 @@ end. { $Log$ - Revision 1.36 1999-04-18 00:32:22 pierre + Revision 1.37 1999-04-21 16:31:41 pierre + ra386att.pas + + Revision 1.36 1999/04/18 00:32:22 pierre * fix for bug0124 and better error position info Revision 1.35 1999/04/17 22:16:55 pierre diff --git a/compiler/tccal.pas b/compiler/tccal.pas index 3fbf47a2bb..b6fba1cb7f 100644 --- a/compiler/tccal.pas +++ b/compiler/tccal.pas @@ -277,6 +277,16 @@ implementation { into a register } { is this usefull here ? } { this was missing in formal parameter list } + if (defcoll^.data=cformaldef) then + begin + if defcoll^.paratyp=vs_var then + if not valid_for_formal_var(p^.left) then + CGMessage(parser_e_illegal_parameter_list); + if defcoll^.paratyp=vs_const then + if not valid_for_formal_const(p^.left) then + CGMessage(parser_e_illegal_parameter_list); + end; + if defcoll^.paratyp=vs_var then begin set_unique(p^.left); @@ -1139,7 +1149,10 @@ implementation end. { $Log$ - Revision 1.33 1999-04-21 09:44:00 peter + Revision 1.34 1999-04-21 16:31:46 pierre + ra386att.pas + + Revision 1.33 1999/04/21 09:44:00 peter * storenumber works * fixed some typos in double_checksum + incompatible types type1 and type2 message (with storenumber) diff --git a/compiler/tcld.pas b/compiler/tcld.pas index 221c4fe34f..1f2e175e61 100644 --- a/compiler/tcld.pas +++ b/compiler/tcld.pas @@ -85,11 +85,12 @@ implementation clear_reference(p^.location.reference); if p^.symtableentry^.typ=funcretsym then begin + p1:=genzeronode(funcretn); + p1^.funcretprocinfo:=pprocinfo(pfuncretsym(p^.symtableentry)^.funcretprocinfo); + p1^.retdef:=pfuncretsym(p^.symtableentry)^.funcretdef; + firstpass(p1); putnode(p); - p:=genzeronode(funcretn); - p^.funcretprocinfo:=pprocinfo(pfuncretsym(p^.symtableentry)^.funcretprocinfo); - p^.retdef:=pfuncretsym(p^.symtableentry)^.funcretdef; - firstpass(p); + p:=p1; exit; end; if p^.symtableentry^.typ=absolutesym then @@ -474,7 +475,10 @@ implementation end. { $Log$ - Revision 1.21 1999-04-01 21:59:57 peter + Revision 1.22 1999-04-21 16:31:47 pierre + ra386att.pas + + Revision 1.21 1999/04/01 21:59:57 peter * type error for array constructor with array,record as argument Revision 1.20 1999/03/24 23:17:39 peter diff --git a/compiler/tgeni386.pas b/compiler/tgeni386.pas index 173282096b..b347f5f459 100644 --- a/compiler/tgeni386.pas +++ b/compiler/tgeni386.pas @@ -185,7 +185,7 @@ implementation begin if r in [R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI] then ungetregister32(r) - else if r in [R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI] then + else if r in [R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI] then ungetregister32(reg16toreg32(r)) else if r in [R_AL,R_BL,R_CL,R_DL] then ungetregister32(reg8toreg32(r)) @@ -373,7 +373,10 @@ begin end. { $Log$ - Revision 1.21 1999-04-16 11:49:47 peter + Revision 1.22 1999-04-21 16:31:48 pierre + ra386att.pas + + Revision 1.21 1999/04/16 11:49:47 peter + tempalloc + -at to show temp alloc info in .s file diff --git a/compiler/tree.pas b/compiler/tree.pas index 1bf4e08594..5a30dbbc5a 100644 --- a/compiler/tree.pas +++ b/compiler/tree.pas @@ -209,6 +209,9 @@ unit tree; {$ifdef extdebug} firstpasscount : longint; {$endif extdebug} +{$ifdef TEMPS_NOT_PUSH} + temp_offset : longint; +{$endif TEMPS_NOT_PUSH} case treetype : ttreetyp of addn : (use_strconcat : boolean;string_typ : tstringtype); callparan : (is_colon_para : boolean;exact_match_found, @@ -1714,7 +1717,10 @@ unit tree; end. { $Log$ - Revision 1.72 1999-04-15 09:01:35 peter + Revision 1.73 1999-04-21 16:31:49 pierre + ra386att.pas + + Revision 1.72 1999/04/15 09:01:35 peter * fixed set loading * object inheritance support for browser