Browse Source

* support Type[index] typecasting

git-svn-id: trunk@711 -
peter 20 years ago
parent
commit
03c02cdb42
2 changed files with 42 additions and 9 deletions
  1. 21 9
      compiler/i386/ra386int.pas
  2. 21 0
      compiler/rautils.pas

+ 21 - 9
compiler/i386/ra386int.pas

@@ -711,7 +711,7 @@ Unit Ra386int;
          begin
            Consume(AS_DOT);
            if actasmtoken=AS_ID then
-            s:=s+'.'+actasmpattern;
+             s:=s+'.'+actasmpattern;
            if not Consume(AS_ID) then
             begin
               RecoverConsume(true);
@@ -1622,14 +1622,26 @@ Unit Ra386int;
                        if SearchType(expr,typesize) then
                         begin
                           oper.hastype:=true;
-                          if (actasmtoken=AS_LPAREN) then
-                            begin
-                              Consume(AS_LPAREN);
-                              BuildOperand(oper);
-                              Consume(AS_RPAREN);
-                              if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
-                                oper.SetSize(typesize,true);
-                            end;
+                          case actasmtoken of
+                            AS_LPAREN :
+                              begin
+                                { Support Type([Reference]) }
+                                Consume(AS_LPAREN);
+                                BuildOperand(oper);
+                                Consume(AS_RPAREN);
+                                if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
+                                  oper.SetSize(typesize,true);
+                              end;
+                            AS_LBRACKET :
+                              begin
+                                { Support Var.Type[Index] }
+                                { Convert @label.Byte[1] to reference }
+                                if oper.opr.typ=OPR_SYMBOL then
+                                  oper.initref;
+                                if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
+                                  oper.SetSize(typesize,true);
+                              end;
+                          end;
                         end
                        else
                         begin

+ 21 - 0
compiler/rautils.pas

@@ -944,6 +944,8 @@ procedure TOperand.InitRef;
 {*********************************************************************}
 var
   l : aint;
+  hsymofs : aint;
+  hsymbol : tasmsymbol;
   reg : tregister;
 Begin
   case opr.typ of
@@ -968,6 +970,15 @@ Begin
         Fillchar(opr.ref,sizeof(treference),0);
         opr.Ref.base:=reg;
       end;
+    OPR_SYMBOL :
+      begin
+        hsymbol:=opr.symbol;
+        hsymofs:=opr.symofs;
+        opr.typ:=OPR_REFERENCE;
+        Fillchar(opr.ref,sizeof(treference),0);
+        opr.ref.symbol:=hsymbol;
+        opr.ref.offset:=hsymofs;
+      end;
     else
       begin
         Message(asmr_e_invalid_operand_type);
@@ -1346,6 +1357,16 @@ Begin
            end;
      end;
    end;
+   { Support Field.Type as typecasting }
+   if (st=nil) and (s<>'') then
+     begin
+       asmsearchsym(s,sym,srsymtable);
+       if assigned(sym) and (sym.typ=typesym) then
+         begin
+           size:=ttypesym(sym).restype.def.size;
+           s:=''
+         end;
+     end;
    GetRecordOffsetSize:=(s='');
 end;