diff options
Diffstat (limited to 'compiler/symtable.pas')
-rw-r--r-- | compiler/symtable.pas | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/compiler/symtable.pas b/compiler/symtable.pas index 4396969c73..dd91eeb60d 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -230,7 +230,7 @@ interface function generate_objectpascal_helper_key(def:tdef):string; procedure incompatibletypes(def1,def2:tdef); procedure hidesym(sym:TSymEntry); - procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry); + procedure duplicatesym(var hashedid: THashedIDString; dupsym, origsym:TSymEntry; warn: boolean); function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean; function get_jumpbuf_size : longint; @@ -631,7 +631,7 @@ implementation begin hsym:=tsym(FindWithHash(hashedid)); if assigned(hsym) then - DuplicateSym(hashedid,sym,hsym); + DuplicateSym(hashedid,sym,hsym,false); result:=assigned(hsym); end; @@ -1393,9 +1393,9 @@ implementation if tfieldvarsym(sym).fieldoffset=0 then include(tfieldvarsym(sym).varoptions,vo_is_first_field); - { add to this record symtable } + { add to this record symtable, checking for duplicate names } // unionst.SymList.List.List^[i].Data:=nil; - sym.ChangeOwner(self); + insert(sym); varalign:=tfieldvarsym(sym).vardef.alignment; if varalign=0 then varalign:=size_2_align(tfieldvarsym(sym).getsize); @@ -1480,7 +1480,8 @@ implementation function tObjectSymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean; var - hsym : tsym; + hsym: tsym; + warn: boolean; begin result:=false; if not assigned(defowner) then @@ -1511,7 +1512,15 @@ implementation ) ) then begin - DuplicateSym(hashedid,sym,hsym); + { only watn when a parameter/local variable in a method + conflicts with a category method, because this can easily + happen due to all possible categories being imported via + CocoaAll } + warn:= + (is_objccategory(tdef(hsym.owner.defowner)) or + is_classhelper(tdef(hsym.owner.defowner))) and + (sym.typ in [paravarsym,localvarsym,fieldvarsym]); + DuplicateSym(hashedid,sym,hsym,warn); result:=true; end; end @@ -1590,7 +1599,7 @@ implementation (vo_is_result in tabstractvarsym(hsym).varoptions)) then HideSym(hsym) else - DuplicateSym(hashedid,sym,hsym); + DuplicateSym(hashedid,sym,hsym,false); result:=true; exit; end; @@ -1610,7 +1619,7 @@ implementation (vo_is_result in tabstractvarsym(sym).varoptions)) then Hidesym(sym) else - DuplicateSym(hashedid,sym,hsym); + DuplicateSym(hashedid,sym,hsym,false); result:=true; exit; end; @@ -1716,7 +1725,7 @@ implementation tnamespacesym(sym).unitsym:=tsym(hsym); end else - DuplicateSym(hashedid,sym,hsym); + DuplicateSym(hashedid,sym,hsym,false); result:=true; exit; end; @@ -2059,11 +2068,15 @@ implementation end; - procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry); + procedure duplicatesym(var hashedid: THashedIDString; dupsym, origsym: TSymEntry; warn: boolean); var st : TSymtable; + filename : TIDString; begin - Message1(sym_e_duplicate_id,tsym(origsym).realname); + if not warn then + Message1(sym_e_duplicate_id,tsym(origsym).realname) + else + Message1(sym_w_duplicate_id,tsym(origsym).realname); { Write hint where the original symbol was found } st:=finduniTSymtable(origsym.owner); with tsym(origsym).fileinfo do @@ -2073,7 +2086,13 @@ implementation st.iscurrentunit then Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line)) else if assigned(st.name) then - Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line)); + begin + filename:=find_module_from_symtable(st).sourcefiles.get_file_name(fileindex); + if filename<>'' then + Message2(sym_h_duplicate_id_where,'unit '+st.name^+': '+filename,tostr(line)) + else + Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line)) + end; end; { Rename duplicate sym to an unreachable name, but it can be inserted in the symtable without errors } @@ -2223,6 +2242,7 @@ implementation function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean; var symownerdef : tabstractrecorddef; + nonlocalst : tsymtable; begin result:=false; @@ -2231,17 +2251,22 @@ implementation not (symst.symtabletype in [objectsymtable,recordsymtable]) then internalerror(200810285); symownerdef:=tabstractrecorddef(symst.defowner); + { specializations might belong to a localsymtable or parasymtable } + nonlocalst:=symownerdef.owner; + if tstoreddef(symst.defowner).is_specialization then + while nonlocalst.symtabletype in [localsymtable,parasymtable] do + nonlocalst:=nonlocalst.defowner.owner; case symvisibility of vis_private : begin { private symbols are allowed when we are in the same module as they are defined } result:=( - (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and - (symownerdef.owner.iscurrentunit) + (nonlocalst.symtabletype in [globalsymtable,staticsymtable]) and + (nonlocalst.iscurrentunit) ) or ( // the case of specialize inside the generic declaration and nested types - (symownerdef.owner.symtabletype in [objectsymtable,recordsymtable]) and + (nonlocalst.symtabletype in [objectsymtable,recordsymtable]) and ( assigned(current_structdef) and ( @@ -2293,8 +2318,8 @@ implementation in the current module } result:=( ( - (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and - (symownerdef.owner.iscurrentunit) + (nonlocalst.symtabletype in [globalsymtable,staticsymtable]) and + (nonlocalst.iscurrentunit) ) or ( assigned(contextobjdef) and @@ -2303,7 +2328,7 @@ implementation def_is_related(contextobjdef,symownerdef) ) or ( // the case of specialize inside the generic declaration and nested types - (symownerdef.owner.symtabletype in [objectsymtable,recordsymtable]) and + (nonlocalst.symtabletype in [objectsymtable,recordsymtable]) and ( assigned(current_structdef) and ( @@ -2945,7 +2970,9 @@ implementation end; end; { now search in the extended type itself } - if classh.extendeddef.typ in [recorddef,objectdef] then + { Note: the extendeddef might be Nil if we are currently parsing the + extended type itself and the identifier was not found } + if assigned(classh.extendeddef) and (classh.extendeddef.typ in [recorddef,objectdef]) then begin srsymtable:=tabstractrecorddef(classh.extendeddef).symtable; srsym:=tsym(srsymtable.FindWithHash(hashedid)); |