소스 검색

* Attributes must be assigned only to elements before the first colon

Michaël Van Canneyt 1 년 전
부모
커밋
2c9870f85a
3개의 변경된 파일44개의 추가작업 그리고 10개의 파일을 삭제
  1. 16 3
      compiler/pdecobj.pas
  2. 8 3
      compiler/pdecvar.pas
  3. 20 4
      compiler/ptype.pas

+ 16 - 3
compiler/pdecobj.pas

@@ -1084,7 +1084,7 @@ implementation
         vdoptions: tvar_dec_options;
         fieldlist: tfpobjectlist;
         rtti_attrs_def: trtti_attribute_list;
-        fldCount : Integer;
+        attr_element_count,fldCount : Integer;
 
       procedure parse_const;
         begin
@@ -1367,15 +1367,28 @@ implementation
                                   include(vdoptions,vd_threadvar);
                                 // Record count
                                 fldCount:=FieldList.Count;
-                                read_record_fields(vdoptions,fieldlist,nil,hadgeneric);
+                                read_record_fields(vdoptions,fieldlist,nil,hadgeneric,attr_element_count);
+                                {
+                                  attr_element_count returns the number of fields to which the attribute must be applied.
+                                  For
+                                  [someattr]
+                                  a : integer;
+                                  b : integer;
+                                  attr_element_count returns 1. For
+                                  [someattr]
+                                  a, b : integer;
+                                  it returns 2.
+                                  Basically the number of variables before the first colon.
+                                }
                                 if assigned(rtti_attrs_def) then
                                   begin
                                   { read_record_fields can read a list of fields with the same type.
                                     for the first fields, we simply copy. for the last one we bind.}
-                                  While (fldCount+1<FieldList.Count) do
+                                  While (attr_element_count>1) do
                                     begin
                                     trtti_attribute_list.copyandbind(rtti_attrs_def,tfieldvarsym(fieldlist[FldCount]).rtti_attribute_list);
                                     inc(fldcount);
+                                    dec(attr_element_count);
                                     end;
                                   if fldCount<FieldList.Count then
                                     trtti_attribute_list.bind(rtti_attrs_def,tfieldvarsym(fieldlist[FldCount]).rtti_attribute_list)

+ 8 - 3
compiler/pdecvar.pas

@@ -38,7 +38,7 @@ interface
 
     procedure read_var_decls(options:Tvar_dec_options;out had_generic:boolean);
 
-    procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc: ppvariantrecdesc;out had_generic:boolean);
+    procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc: ppvariantrecdesc;out had_generic:boolean; out attr_element_count : integer);
 
     procedure read_public_and_external(vs: tabstractvarsym);
 
@@ -1679,7 +1679,7 @@ implementation
       end;
 
 
-    procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc : ppvariantrecdesc;out had_generic:boolean);
+    procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc : ppvariantrecdesc;out had_generic:boolean; out attr_element_count : integer);
       var
          sc : TFPObjectList;
          i  : longint;
@@ -1707,6 +1707,7 @@ implementation
          hadgendummy,
          semicoloneaten,
          removeclassoption: boolean;
+         dummyattrelementcount : integer;
 {$if defined(powerpc) or defined(powerpc64)}
          tempdef: tdef;
          is_first_type: boolean;
@@ -1727,6 +1728,7 @@ implementation
          sc:=TFPObjectList.create(false);
          removeclassoption:=false;
          had_generic:=false;
+         attr_element_count:=0;
          while (token=_ID) and
             not(((vd_object in options) or
                  ((vd_record in options) and (m_advanced_records in current_settings.modeswitches))) and
@@ -1775,6 +1777,9 @@ implementation
              if had_generic and (sc.count=0) then
                break;
              consume(_COLON);
+             if attr_element_count=0 then
+               attr_element_count:=sc.Count;
+
              typepos:=current_filepos;
 
              read_anon_type(hdef,false);
@@ -2056,7 +2061,7 @@ implementation
                 consume(_LKLAMMER);
                 inc(variantrecordlevel);
                 if token<>_RKLAMMER then
-                  read_record_fields([vd_record],nil,@variantdesc^^.branches[high(variantdesc^^.branches)].nestedvariant,hadgendummy);
+                  read_record_fields([vd_record],nil,@variantdesc^^.branches[high(variantdesc^^.branches)].nestedvariant,hadgendummy,dummyattrelementcount);
                 dec(variantrecordlevel);
                 consume(_RKLAMMER);
 

+ 20 - 4
compiler/ptype.pas

@@ -698,6 +698,7 @@ implementation
         vdoptions: tvar_dec_options;
         rtti_attrs_def: trtti_attribute_list;
         fldCount : Integer;
+        attr_element_count : Integer;
 
       procedure check_unbound_attributes;
         begin
@@ -894,15 +895,29 @@ implementation
                                 if threadvarfields then
                                   include(vdoptions,vd_threadvar);
                                 fldCount:=current_structdef.symtable.SymList.Count;
-                                read_record_fields(vdoptions,nil,nil,hadgeneric);
+                                read_record_fields(vdoptions,nil,nil,hadgeneric,attr_element_count);
+                                {
+                                  attr_element_count returns the number of fields to which the attribute must be applied.
+                                  For
+                                  [someattr]
+                                  a : integer;
+                                  b : integer;
+                                  attr_element_count returns 1. For
+                                  [someattr]
+                                  a, b : integer;
+                                  it returns 2.
+                                  Basically the number of variables before the first colon.
+                                }
                                 if assigned(rtti_attrs_def) then
                                   begin
-                                  While (fldCount+1<current_structdef.symtable.SymList.Count) do
+                                  While (attr_element_count>1) do
                                     begin
                                     trtti_attribute_list.copyandbind(rtti_attrs_def,(current_structdef.symtable.SymList[fldCount] as tfieldvarsym).rtti_attribute_list);
                                     inc(fldcount);
+                                    dec(attr_element_count);
                                     end;
-                                  trtti_attribute_list.bind(rtti_attrs_def,(current_structdef.symtable.SymList[fldCount] as tfieldvarsym).rtti_attribute_list);
+                                  if fldCount<current_structdef.symtable.SymList.Count then
+                                    trtti_attribute_list.bind(rtti_attrs_def,(current_structdef.symtable.SymList[fldCount] as tfieldvarsym).rtti_attribute_list);
                                   end;
                               end;
                           end
@@ -1036,6 +1051,7 @@ implementation
          recst: trecordsymtable;
          hadgendummy : boolean;
          alignment: Integer;
+         dummyattrelcount : Integer;
       begin
          old_current_structdef:=current_structdef;
          old_current_genericdef:=current_genericdef;
@@ -1100,7 +1116,7 @@ implementation
            end
          else
            begin
-             read_record_fields([vd_record],nil,nil,hadgendummy);
+             read_record_fields([vd_record],nil,nil,hadgendummy,dummyattrelcount);
 {$ifdef jvm}
              { we need a constructor to create temps, a deep copy helper, ... }
              add_java_default_record_methods_intf(trecorddef(current_structdef));