summaryrefslogtreecommitdiff
path: root/compiler/pgenutil.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/pgenutil.pas')
-rw-r--r--compiler/pgenutil.pas108
1 files changed, 69 insertions, 39 deletions
diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas
index 5b12b97ff7..94cfed0343 100644
--- a/compiler/pgenutil.pas
+++ b/compiler/pgenutil.pas
@@ -182,11 +182,26 @@ uses
odt_interfacecorba,
odt_interfacejava,
odt_dispinterface:
- if not def_is_related(paraobjdef,formalobjdef.childof) then
- begin
- MessagePos2(filepos,type_e_incompatible_types,paraobjdef.typename,formalobjdef.childof.typename);
- result:=false;
- end;
+ begin
+ if (oo_is_forward in paraobjdef.objectoptions) and
+ (paraobjdef.objecttype=formalobjdef.objecttype) and
+ (df_genconstraint in formalobjdef.defoptions) and
+ (
+ (formalobjdef.objecttype=odt_interfacecom) and
+ (formalobjdef.childof=interface_iunknown)
+ )
+ or
+ (
+ (formalobjdef.objecttype=odt_interfacecorba) and
+ (formalobjdef.childof=nil)
+ ) then
+ continue;
+ if not def_is_related(paraobjdef,formalobjdef.childof) then
+ begin
+ MessagePos2(filepos,type_e_incompatible_types,paraobjdef.typename,formalobjdef.childof.typename);
+ result:=false;
+ end;
+ end;
odt_class,
odt_javaclass:
begin
@@ -225,6 +240,14 @@ uses
result:=false;
continue;
end;
+ { for forward declared classes we allow pure TObject/class declarations }
+ if (oo_is_forward in paraobjdef.objectoptions) and
+ (df_genconstraint in formaldef.defoptions) then
+ begin
+ if (formalobjdef.childof=class_tobject) and
+ not formalobjdef.implements_any_interfaces then
+ continue;
+ end;
if assigned(formalobjdef.childof) and
not def_is_related(paradef,formalobjdef.childof) then
begin
@@ -590,6 +613,8 @@ uses
found:=searchsym_in_class(tobjectdef(genericdef.owner.defowner),tobjectdef(genericdef.owner.defowner),ugenname,srsym,st,[])
else
found:=searchsym_in_record(tabstractrecorddef(genericdef.owner.defowner),ugenname,srsym,st);
+ if not found then
+ found:=searchsym(ugenname,srsym,st);
end
else
found:=searchsym(ugenname,srsym,st);
@@ -664,39 +689,6 @@ uses
(current_structdef.objname^=ufinalspecializename) then
tt:=current_structdef;
- { decide in which symtable to put the specialization }
- if parse_generic then
- begin
- if not assigned(current_genericdef) then
- internalerror(2014050901);
- if assigned(current_procinfo) and (df_generic in current_procinfo.procdef.defoptions) then
- { if we are parsing the definition of a method we specialize into
- the local symtable of it }
- specializest:=current_procinfo.procdef.getsymtable(gs_local)
- else
- { we specialize the partial specialization into the symtable of the currently parsed
- generic }
- case current_genericdef.typ of
- procvardef,
- procdef:
- specializest:=current_genericdef.getsymtable(gs_local);
- objectdef,
- recorddef:
- specializest:=current_genericdef.getsymtable(gs_record);
- arraydef:
- specializest:=tarraydef(current_genericdef).symtable;
- else
- internalerror(2014050902);
- end;
- end
- else
- if current_module.is_unit and current_module.in_interface then
- specializest:=current_module.globalsymtable
- else
- specializest:=current_module.localsymtable;
- if not assigned(specializest) then
- internalerror(2014050910);
-
{ Can we reuse an already specialized type? }
{ for this first check whether we are currently specializing a nested
@@ -734,6 +726,39 @@ uses
end;
end;
+ { decide in which symtable to put the specialization }
+ if parse_generic and not assigned(tt) then
+ begin
+ if not assigned(current_genericdef) then
+ internalerror(2014050901);
+ if assigned(current_procinfo) and (df_generic in current_procinfo.procdef.defoptions) then
+ { if we are parsing the definition of a method we specialize into
+ the local symtable of it }
+ specializest:=current_procinfo.procdef.getsymtable(gs_local)
+ else
+ { we specialize the partial specialization into the symtable of the currently parsed
+ generic }
+ case current_genericdef.typ of
+ procvardef,
+ procdef:
+ specializest:=current_genericdef.getsymtable(gs_local);
+ objectdef,
+ recorddef:
+ specializest:=current_genericdef.getsymtable(gs_record);
+ arraydef:
+ specializest:=tarraydef(current_genericdef).symtable;
+ else
+ internalerror(2014050902);
+ end;
+ end
+ else
+ if current_module.is_unit and current_module.in_interface then
+ specializest:=current_module.globalsymtable
+ else
+ specializest:=current_module.localsymtable;
+ if not assigned(specializest) then
+ internalerror(2014050910);
+
{ now check whether there is a specialization somewhere else }
if not assigned(tt) then
begin
@@ -966,6 +991,8 @@ uses
if token=_ID then
begin
generictype:=ctypesym.create(orgpattern,cundefinedtype);
+ { type parameters need to be added as strict private }
+ generictype.visibility:=vis_strictprivate;
include(generictype.symoptions,sp_generic_para);
result.add(orgpattern,generictype);
end;
@@ -1141,6 +1168,8 @@ uses
if assigned(generictype.owner) then
begin
sym:=ctypesym.create(genericlist.nameofindex(i),generictype.typedef);
+ { type parameters need to be added as strict private }
+ sym.visibility:=vis_strictprivate;
st.insert(sym);
include(sym.symoptions,sp_generic_para);
end
@@ -1296,7 +1325,8 @@ uses
if assigned(hmodule.globalsymtable) then
symtablestack.push(hmodule.globalsymtable);
{ push the localsymtable if needed }
- if (hmodule<>current_module) or not current_module.in_interface then
+ if ((hmodule<>current_module) or not current_module.in_interface)
+ and assigned(hmodule.localsymtable) then
symtablestack.push(hmodule.localsymtable);
end;