mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-27 04:03:43 +02:00

symconst.pas: + extend "tdefoptions" by a "df_genconstraint" which will be used to mark dummy defs that should mainly satisfy the compiler's type checking without to much changes symsym.pas: + add a class "tgenericconstraintdata" which will hold information about the constraints associated with a specific generic type parameter (designed for future extensions) + extend "ttypesym" by a reference to a "tgenericconstraintdata" which is written to the ppu only if needed symtype.pas: + add a pointer to "tderef" as this is needed for the ppu reading/writing code for the "tgenericconstraintdata" pdecl.pas, types_dec: + call "parse_generic_parameters" so that constraints are allowed pgenutil.pas: + extend "generate_specialization" by a "parsedpos" to give in the file position of the first parsed parameter (needed for correct error locations when checking the constraints) + add an overloaded call of "generate_specialization" to differentiate between the use cases "first parameter parsed by generate_specialization" and "first parameter parsed by other code"; this also allows to write the "fillchar" for the "parampos" parameter only once ( => otherwise a warning is triggered => error in compilation) + extend the "parse_generic_specialization_types" by a "poslist" parameter which will contain the positions of all parsed type parameters (can only be used in the case that all parameters are parsed) * move the original code of "parse_generic_specialization_types" to a new procedure "parse_generic_specialization_types_internal" which take an additional "parsedpos" parameter which will be added to the "poslist" before all others; "parse_generic_specialization_types" calls this new procedure with a dummy argument (which won't be used) + extend "parse_generic_parameters" by the parsing of generic constraints which constructs correct defs for the parameters and fills in the new "tgenericconstraintdata" object for each parameter (note: the "constructor" constraint is only parsed for Delphi compatibility and basically means the same as a "class" constraint... (it's a relict of Delphi.NET)) * adjust "insert_generic_parameter_types" as specializations and generics can no longer be differed by whether the type parameters are of type "undefineddef" pdecsub.pas, parse_proc_head, consume_generic_interface: * adjust call to "generate_specialization" + add a new function "check_generic_constraints" which is used from within "generate_specialization" to ensure that the given specialization parameters are compatible with the constraints of the generic parameters ptype.pas: * single_type: adjust call to "generate_specialization" * read_named_type, expr_type: adjust call to "generate_specialization" + write_persistent_type_info: don't write typeinfo for constraints pexpr.pas, sub_expr: * adjust call to "generate_specialization" * adjusted ppudump, because of added "tdefoptions.df_genconstraint" value + added tests for generic constraints * modified test for class helper inside a generic which extends a class type parameter + added test for record helper inside a generic which extends a record type parameter git-svn-id: trunk@23158 -
187 lines
2.8 KiB
ObjectPascal
187 lines
2.8 KiB
ObjectPascal
unit ugenconstraints;
|
|
|
|
{$ifdef fpc}
|
|
{$mode delphi}
|
|
{$else}
|
|
// Delphi only knows "MSWINDOWS"
|
|
{$define windows}
|
|
{$endif}
|
|
|
|
interface
|
|
|
|
type
|
|
TTestClass = class
|
|
|
|
end;
|
|
|
|
TTestClass2 = class(TTestClass)
|
|
|
|
end;
|
|
|
|
TTestRec = record
|
|
|
|
end;
|
|
|
|
ITest1 = interface
|
|
|
|
end;
|
|
|
|
ITest2 = interface(ITest1)
|
|
|
|
end;
|
|
|
|
TTestClass3 = class(TInterfacedObject, ITest1)
|
|
|
|
end;
|
|
|
|
TTestClass4 = class(TInterfacedObject, ITest1, ITest2)
|
|
|
|
end;
|
|
|
|
TTestClass5 = class(TInterfacedObject, ITest2)
|
|
|
|
end;
|
|
|
|
TTestClass6 = class(TTestClass3, ITest2)
|
|
|
|
end;
|
|
|
|
TTestClass7 = class(TTestClass, ITest1)
|
|
function QueryInterface({$IFDEF FPC}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
end;
|
|
|
|
TTestClass8 = class(TTestClass7, ITest2)
|
|
|
|
end;
|
|
|
|
TTestClass9 = class(TTestClass, ITest2)
|
|
function QueryInterface({$IFDEF FPC}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
|
|
end;
|
|
|
|
TTestObject1 = object
|
|
|
|
end;
|
|
|
|
type
|
|
TTest1<T: class> = class
|
|
|
|
end;
|
|
|
|
TTest2<T: record> = class
|
|
|
|
end;
|
|
|
|
TTest3<T: TTestClass> = class
|
|
|
|
end;
|
|
|
|
TTest4<T: class, constructor> = class
|
|
|
|
end;
|
|
|
|
TTest5<T: IInterface> = class
|
|
|
|
end;
|
|
|
|
TTest6<T: ITest1> = class
|
|
|
|
end;
|
|
|
|
TTest7<T: ITest1, ITest2> = class
|
|
|
|
end;
|
|
|
|
TTest8<T: class, ITest1> = class
|
|
|
|
end;
|
|
|
|
TTest9<T: ITest1, class> = class
|
|
|
|
end;
|
|
|
|
TTest10<T: class, constructor, ITest1> = class
|
|
|
|
end;
|
|
|
|
TTest11<T: constructor, ITest1, class> = class
|
|
|
|
end;
|
|
|
|
TTest12<T: TTestClass, ITest1> = class
|
|
|
|
end;
|
|
|
|
TTest13<T: TTestClass, constructor> = class
|
|
|
|
end;
|
|
|
|
TTest14<T: TTestClass, ITest1, constructor> = class
|
|
|
|
end;
|
|
|
|
TTest15<T: ITest1, constructor, ITest2, TTestClass> = class
|
|
|
|
end;
|
|
|
|
TTest16<T: ITest1, constructor> = class
|
|
|
|
end;
|
|
|
|
TTest17<T1, T2: ITest1> = class
|
|
|
|
end;
|
|
|
|
TTest18<T1: ITest1; T2: ITest2> = class
|
|
|
|
end;
|
|
|
|
TTest19<T1: record; T2: class> = class
|
|
|
|
end;
|
|
|
|
TTest20<T1: TTestClass; T2: constructor> = class
|
|
|
|
end;
|
|
|
|
TTest21<T: constructor> = class
|
|
|
|
end;
|
|
|
|
implementation
|
|
|
|
function TTestClass7.QueryInterface({$IFDEF FPC}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;
|
|
begin
|
|
|
|
end;
|
|
|
|
function TTestClass7._AddRef : longint;
|
|
begin
|
|
|
|
end;
|
|
|
|
function TTestClass7._Release : longint;
|
|
begin
|
|
|
|
end;
|
|
|
|
function TTestClass9.QueryInterface({$IFDEF FPC}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;
|
|
begin
|
|
|
|
end;
|
|
|
|
function TTestClass9._AddRef : longint;
|
|
begin
|
|
|
|
end;
|
|
|
|
function TTestClass9._Release : longint;
|
|
begin
|
|
|
|
end;
|
|
|
|
end.
|