summaryrefslogtreecommitdiff
path: root/compiler/symtable.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/symtable.pas')
-rw-r--r--compiler/symtable.pas65
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));