|
@@ -745,11 +745,13 @@ type
|
|
|
FAssertMsgConstructor: TPasConstructor;
|
|
|
FRangeErrorClass: TPasClassType;
|
|
|
FRangeErrorConstructor: TPasConstructor;
|
|
|
+ FSystemTVarRec: TPasRecordType;
|
|
|
procedure SetAssertClass(const AValue: TPasClassType);
|
|
|
procedure SetAssertDefConstructor(const AValue: TPasConstructor);
|
|
|
procedure SetAssertMsgConstructor(const AValue: TPasConstructor);
|
|
|
procedure SetRangeErrorClass(const AValue: TPasClassType);
|
|
|
procedure SetRangeErrorConstructor(const AValue: TPasConstructor);
|
|
|
+ procedure SetSystemTVarRec(const AValue: TPasRecordType);
|
|
|
public
|
|
|
FirstName: string; // the 'unit1' in 'unit1', or 'ns' in 'ns.unit1'
|
|
|
PendingResolvers: TFPList; // list of TPasResolver waiting for the unit interface
|
|
@@ -765,6 +767,7 @@ type
|
|
|
property AssertMsgConstructor: TPasConstructor read FAssertMsgConstructor write SetAssertMsgConstructor;
|
|
|
property RangeErrorClass: TPasClassType read FRangeErrorClass write SetRangeErrorClass;
|
|
|
property RangeErrorConstructor: TPasConstructor read FRangeErrorConstructor write SetRangeErrorConstructor;
|
|
|
+ property SystemTVarRec: TPasRecordType read FSystemTVarRec write SetSystemTVarRec;
|
|
|
end;
|
|
|
TPasModuleScopeClass = class of TPasModuleScope;
|
|
|
|
|
@@ -1228,7 +1231,7 @@ type
|
|
|
ExprEl: TPasExpr;
|
|
|
Flags: TPasResolverResultFlags;
|
|
|
end;
|
|
|
- PPasResolvedElement = ^TPasResolverResult;
|
|
|
+ PPasResolverResult = ^TPasResolverResult;
|
|
|
|
|
|
type
|
|
|
TPasResolverComputeFlag = (
|
|
@@ -1528,10 +1531,11 @@ type
|
|
|
procedure FinishArgument(El: TPasArgument); virtual;
|
|
|
procedure FinishAncestors(aClass: TPasClassType); virtual;
|
|
|
procedure FinishMethodResolution(El: TPasMethodResolution); virtual;
|
|
|
+ procedure FinishProcParamAccess(ProcType: TPasProcedureType; Params: TParamsExpr); virtual;
|
|
|
procedure FinishPropertyParamAccess(Params: TParamsExpr;
|
|
|
- Prop: TPasProperty);
|
|
|
- procedure FinishCallArgAccess(Expr: TPasExpr; Access: TResolvedRefAccess);
|
|
|
- procedure FinishInitialFinalization(El: TPasImplBlock);
|
|
|
+ Prop: TPasProperty); virtual;
|
|
|
+ procedure FinishCallArgAccess(Expr: TPasExpr; Access: TResolvedRefAccess); virtual;
|
|
|
+ procedure FinishInitialFinalization(El: TPasImplBlock); virtual;
|
|
|
procedure EmitTypeHints(PosEl: TPasElement; aType: TPasType); virtual;
|
|
|
function EmitElementHints(PosEl, El: TPasElement): boolean; virtual;
|
|
|
procedure StoreScannerFlagsInProc(ProcScope: TPasProcedureScope);
|
|
@@ -1604,6 +1608,8 @@ type
|
|
|
ErrorEl: TPasElement): boolean; virtual;
|
|
|
procedure FindAssertExceptionConstructors(ErrorEl: TPasElement); virtual;
|
|
|
procedure FindRangeErrorConstructors(ErrorEl: TPasElement); virtual;
|
|
|
+ function FindTVarRec(ErrorEl: TPasElement): TPasRecordType; virtual;
|
|
|
+ function GetTVarRec(El: TPasArrayType): TPasRecordType; virtual;
|
|
|
protected
|
|
|
fExprEvaluator: TResExprEvaluator;
|
|
|
procedure OnExprEvalLog(Sender: TResExprEvaluator; const id: TMaxPrecInt;
|
|
@@ -1999,6 +2005,8 @@ type
|
|
|
function IsDynArray(TypeEl: TPasType; OptionalOpenArray: boolean = true): boolean;
|
|
|
function IsOpenArray(TypeEl: TPasType): boolean;
|
|
|
function IsDynOrOpenArray(TypeEl: TPasType): boolean;
|
|
|
+ function IsArrayOfConst(TypeEl: TPasType): boolean;
|
|
|
+ function GetArrayElType(ArrType: TPasArrayType): TPasType;
|
|
|
function IsVarInit(Expr: TPasExpr): boolean;
|
|
|
function IsEmptyArrayExpr(const ResolvedEl: TPasResolverResult): boolean;
|
|
|
function IsClassMethod(El: TPasElement): boolean;
|
|
@@ -3713,6 +3721,16 @@ begin
|
|
|
FRangeErrorConstructor.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetRangeErrorConstructor'){$ENDIF};
|
|
|
end;
|
|
|
|
|
|
+procedure TPasModuleScope.SetSystemTVarRec(const AValue: TPasRecordType);
|
|
|
+begin
|
|
|
+ if FSystemTVarRec=AValue then Exit;
|
|
|
+ if FSystemTVarRec<>nil then
|
|
|
+ FSystemTVarRec.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetSystemTVarRec'){$ENDIF};
|
|
|
+ FSystemTVarRec:=AValue;
|
|
|
+ if FSystemTVarRec<>nil then
|
|
|
+ FSystemTVarRec.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetSystemTVarRec'){$ENDIF};
|
|
|
+end;
|
|
|
+
|
|
|
constructor TPasModuleScope.Create;
|
|
|
begin
|
|
|
inherited Create;
|
|
@@ -3726,6 +3744,7 @@ begin
|
|
|
AssertMsgConstructor:=nil;
|
|
|
RangeErrorClass:=nil;
|
|
|
RangeErrorConstructor:=nil;
|
|
|
+ SystemTVarRec:=nil;
|
|
|
FreeAndNil(PendingResolvers);
|
|
|
inherited Destroy;
|
|
|
end;
|
|
@@ -5406,6 +5425,8 @@ begin
|
|
|
RaiseMsg(20170415165455,nCannotNestAnonymousX,sCannotNestAnonymousX,[GetElementTypeName(El)],El);
|
|
|
if not (Parent.Parent is TPasDeclarations) then
|
|
|
RaiseMsg(20170416094735,nCannotNestAnonymousX,sCannotNestAnonymousX,[GetElementTypeName(El)],El);
|
|
|
+ if El.Parent<>Parent then
|
|
|
+ RaiseNotYetImplemented(20190215085011,Parent);
|
|
|
// give anonymous sub type a name
|
|
|
El.Name:=Parent.Name+AnonymousElTypePostfix;
|
|
|
{$IFDEF VerbosePasResolver}
|
|
@@ -5729,9 +5750,17 @@ begin
|
|
|
RaiseXExpectedButYFound(20170216151609,'range',GetElementTypeName(RangeResolved.IdentEl),Expr);
|
|
|
end;
|
|
|
if El.ElType=nil then
|
|
|
- RaiseNotYetImplemented(20171005235610,El,'array of const');
|
|
|
- CheckUseAsType(El.ElType,20190123095401,El);
|
|
|
- FinishSubElementType(El,El.ElType);
|
|
|
+ begin
|
|
|
+ // array of const
|
|
|
+ if length(El.Ranges)>0 then
|
|
|
+ RaiseNotYetImplemented(20190215102529,El);
|
|
|
+ FindTVarRec(El);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ CheckUseAsType(El.ElType,20190123095401,El);
|
|
|
+ FinishSubElementType(El,El.ElType);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
procedure TPasResolver.FinishResourcestring(El: TPasResString);
|
|
@@ -7452,6 +7481,27 @@ begin
|
|
|
// El.ImplementationProc is resolved in FinishClassType
|
|
|
end;
|
|
|
|
|
|
+procedure TPasResolver.FinishProcParamAccess(ProcType: TPasProcedureType;
|
|
|
+ Params: TParamsExpr);
|
|
|
+var
|
|
|
+ ParamAccess: TResolvedRefAccess;
|
|
|
+ i: Integer;
|
|
|
+ ArrParams: TPasExprArray;
|
|
|
+begin
|
|
|
+ ArrParams:=Params.Params;
|
|
|
+ for i:=0 to length(ArrParams)-1 do
|
|
|
+ begin
|
|
|
+ ParamAccess:=rraRead;
|
|
|
+ if i<ProcType.Args.Count then
|
|
|
+ case TPasArgument(ProcType.Args[i]).Access of
|
|
|
+ argVar: ParamAccess:=rraVarParam;
|
|
|
+ argOut: ParamAccess:=rraOutParam;
|
|
|
+ end;
|
|
|
+ AccessExpr(ArrParams[i],ParamAccess);
|
|
|
+ end;
|
|
|
+ CheckCallProcCompatibility(ProcType,Params,false,true);
|
|
|
+end;
|
|
|
+
|
|
|
procedure TPasResolver.FinishPropertyParamAccess(Params: TParamsExpr;
|
|
|
Prop: TPasProperty);
|
|
|
var
|
|
@@ -8064,7 +8114,7 @@ var
|
|
|
InRange, VarRange: TResEvalValue;
|
|
|
InRangeInt, VarRangeInt: TResEvalRangeInt;
|
|
|
bt: TResolverBaseType;
|
|
|
- TypeEl: TPasType;
|
|
|
+ TypeEl, ElType: TPasType;
|
|
|
C: TClass;
|
|
|
begin
|
|
|
CreateScope(Loop,TPasForLoopScope);
|
|
@@ -8150,7 +8200,8 @@ begin
|
|
|
C:=TypeEl.ClassType;
|
|
|
if C=TPasArrayType then
|
|
|
begin
|
|
|
- ComputeElement(TPasArrayType(TypeEl).ElType,StartResolved,[rcType]);
|
|
|
+ ElType:=GetArrayElType(TPasArrayType(TypeEl));
|
|
|
+ ComputeElement(ElType,StartResolved,[rcType]);
|
|
|
StartResolved.Flags:=OrigStartResolved.Flags*[rrfReadable,rrfWritable];
|
|
|
if CheckAssignResCompatibility(VarResolved,StartResolved,Loop.StartExpr,true)=cIncompatible then
|
|
|
RaiseIncompatibleTypeRes(20171112210138,nIncompatibleTypesGotExpected,
|
|
@@ -9080,8 +9131,8 @@ begin
|
|
|
ComputeElement(SubParams,ResolvedEl,[rcNoImplicitProc,rcSetReferenceFlags]);
|
|
|
if IsProcedureType(ResolvedEl,true) then
|
|
|
begin
|
|
|
- CheckCallProcCompatibility(TPasProcedureType(ResolvedEl.LoTypeEl),Params,true);
|
|
|
CreateReference(TPasProcedureType(ResolvedEl.LoTypeEl),Value,Access);
|
|
|
+ FinishProcParamAccess(TPasProcedureType(ResolvedEl.LoTypeEl),Params);
|
|
|
exit;
|
|
|
end
|
|
|
end;
|
|
@@ -9095,31 +9146,6 @@ end;
|
|
|
procedure TPasResolver.ResolveFuncParamsExprName(NameExpr: TPasExpr;
|
|
|
Params: TParamsExpr; Access: TResolvedRefAccess);
|
|
|
|
|
|
- procedure FinishProcParams(ProcType: TPasProcedureType);
|
|
|
- var
|
|
|
- ParamAccess: TResolvedRefAccess;
|
|
|
- i: Integer;
|
|
|
- begin
|
|
|
- if not (Access in [rraRead,rraParamToUnknownProc]) then
|
|
|
- begin
|
|
|
- {$IFDEF VerbosePasResolver}
|
|
|
- writeln('TPasResolver.ResolveFuncParamsExpr.FinishProcParams Params=',GetObjName(Params),' NameEl=',GetObjName(NameExpr),' Access=',Access);
|
|
|
- {$ENDIF}
|
|
|
- RaiseMsg(20170306104440,nVariableIdentifierExpected,sVariableIdentifierExpected,[],Params);
|
|
|
- end;
|
|
|
- for i:=0 to length(Params.Params)-1 do
|
|
|
- begin
|
|
|
- ParamAccess:=rraRead;
|
|
|
- if i<ProcType.Args.Count then
|
|
|
- case TPasArgument(ProcType.Args[i]).Access of
|
|
|
- argVar: ParamAccess:=rraVarParam;
|
|
|
- argOut: ParamAccess:=rraOutParam;
|
|
|
- end;
|
|
|
- AccessExpr(Params.Params[i],ParamAccess);
|
|
|
- end;
|
|
|
- CheckCallProcCompatibility(ProcType,Params,false,true);
|
|
|
- end;
|
|
|
-
|
|
|
procedure FinishUntypedParams(ParamAccess: TResolvedRefAccess);
|
|
|
var
|
|
|
i: Integer;
|
|
@@ -9243,8 +9269,17 @@ begin
|
|
|
|
|
|
// set param expression Access flags
|
|
|
if FoundEl is TPasProcedure then
|
|
|
+ begin
|
|
|
// now it is known which overloaded proc to call
|
|
|
- FinishProcParams(TPasProcedure(FoundEl).ProcType)
|
|
|
+ if not (Access in [rraRead,rraParamToUnknownProc]) then
|
|
|
+ begin
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
+ writeln('TPasResolver.ResolveFuncParamsExprName Params=',GetObjName(Params),' NameExpr=',GetObjName(NameExpr),' Access=',Access);
|
|
|
+ {$ENDIF}
|
|
|
+ RaiseMsg(20170306104440,nVariableIdentifierExpected,sVariableIdentifierExpected,[],Params);
|
|
|
+ end;
|
|
|
+ FinishProcParamAccess(TPasProcedure(FoundEl).ProcType,Params);
|
|
|
+ end
|
|
|
else if FoundEl is TPasType then
|
|
|
begin
|
|
|
TypeEl:=ResolveAliasType(TPasType(FoundEl));
|
|
@@ -9307,7 +9342,14 @@ begin
|
|
|
TypeEl:=ResolvedEl.LoTypeEl;
|
|
|
if TypeEl is TPasProcedureType then
|
|
|
begin
|
|
|
- FinishProcParams(TPasProcedureType(TypeEl));
|
|
|
+ if not (Access in [rraRead,rraParamToUnknownProc]) then
|
|
|
+ begin
|
|
|
+ {$IFDEF VerbosePasResolver}
|
|
|
+ writeln('TPasResolver.ResolveFuncParamsExprName Params=',GetObjName(Params),' NameExpr=',GetObjName(NameExpr),' Access=',Access);
|
|
|
+ {$ENDIF}
|
|
|
+ RaiseMsg(20190215195439,nVariableIdentifierExpected,sVariableIdentifierExpected,[],Params);
|
|
|
+ end;
|
|
|
+ FinishProcParamAccess(TPasProcedureType(TypeEl),Params);
|
|
|
exit;
|
|
|
end;
|
|
|
{$IFDEF VerbosePasResolver}
|
|
@@ -9912,6 +9954,8 @@ procedure TPasResolver.MarkArrayExprRecursive(Expr: TPasExpr;
|
|
|
inc(RgIndex);
|
|
|
if RgIndex>length(ArrayType.Ranges) then
|
|
|
begin
|
|
|
+ if ArrayType.ElType=nil then
|
|
|
+ exit; // elements are not arrays
|
|
|
ComputeElement(ArrayType.ElType,ResolvedElType,[rcType]);
|
|
|
if (ResolvedElType.BaseType=btContext)
|
|
|
and (ResolvedElType.LoTypeEl is TPasArrayType) then
|
|
@@ -11337,7 +11381,7 @@ procedure TPasResolver.ComputeArrayParams(Params: TParamsExpr; out
|
|
|
end;
|
|
|
|
|
|
var
|
|
|
- TypeEl: TPasType;
|
|
|
+ TypeEl, ElType: TPasType;
|
|
|
ArrayEl: TPasArrayType;
|
|
|
ArgNo: Integer;
|
|
|
OrigResolved: TPasResolverResult;
|
|
@@ -11426,7 +11470,8 @@ begin
|
|
|
ArrayEl:=NoNil(ResolveAliasType(ArrayEl.ElType)) as TPasArrayType;
|
|
|
until false;
|
|
|
OrigResolved:=ResolvedEl;
|
|
|
- ComputeElement(ArrayEl.ElType,ResolvedEl,Flags,StartEl);
|
|
|
+ ElType:=GetArrayElType(ArrayEl);
|
|
|
+ ComputeElement(ElType,ResolvedEl,Flags,StartEl);
|
|
|
// identifier and value is the array itself
|
|
|
ResolvedEl.IdentEl:=OrigResolved.IdentEl;
|
|
|
ResolvedEl.ExprEl:=OrigResolved.ExprEl;
|
|
@@ -12710,6 +12755,51 @@ begin
|
|
|
ModScope.RangeErrorConstructor:=aConstructor;
|
|
|
end;
|
|
|
|
|
|
+function TPasResolver.FindTVarRec(ErrorEl: TPasElement): TPasRecordType;
|
|
|
+var
|
|
|
+ aMod, UtilsMod: TPasModule;
|
|
|
+ SectionScope: TPasSectionScope;
|
|
|
+ Identifier: TPasIdentifier;
|
|
|
+ El: TPasElement;
|
|
|
+ ModScope: TPasModuleScope;
|
|
|
+begin
|
|
|
+ aMod:=RootElement;
|
|
|
+ ModScope:=aMod.CustomData as TPasModuleScope;
|
|
|
+ Result:=ModScope.SystemTVarRec;
|
|
|
+ if Result<>nil then exit;
|
|
|
+
|
|
|
+ // find unit in uses clauses
|
|
|
+ UtilsMod:=FindUsedUnit('system',aMod);
|
|
|
+ if UtilsMod=nil then
|
|
|
+ RaiseIdentifierNotFound(20190215101210,'System.TVarRec',ErrorEl);
|
|
|
+
|
|
|
+ // find class in interface
|
|
|
+ if UtilsMod.InterfaceSection=nil then
|
|
|
+ RaiseIdentifierNotFound(20190215101231,'System.TVarRec',ErrorEl);
|
|
|
+
|
|
|
+ SectionScope:=NoNil(UtilsMod.InterfaceSection.CustomData) as TPasSectionScope;
|
|
|
+ Identifier:=SectionScope.FindLocalIdentifier('TVarRec');
|
|
|
+ if Identifier=nil then
|
|
|
+ RaiseIdentifierNotFound(20190215101253,'System.TVarRec',ErrorEl);
|
|
|
+ El:=Identifier.Element;
|
|
|
+ if not (El is TPasRecordType) then
|
|
|
+ RaiseXExpectedButYFound(20190215101310,'record TVarRec',GetElementTypeName(El),ErrorEl);
|
|
|
+ Result:=TPasRecordType(El);
|
|
|
+ ModScope.SystemTVarRec:=Result;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPasResolver.GetTVarRec(El: TPasArrayType): TPasRecordType;
|
|
|
+var
|
|
|
+ aModule: TPasModule;
|
|
|
+ ModScope: TPasModuleScope;
|
|
|
+begin
|
|
|
+ aModule:=El.GetModule;
|
|
|
+ ModScope:=aModule.CustomData as TPasModuleScope;
|
|
|
+ Result:=ModScope.SystemTVarRec;
|
|
|
+ if Result=nil then
|
|
|
+ RaiseNotYetImplemented(20190215111924,El,'missing System.TVarRec');
|
|
|
+end;
|
|
|
+
|
|
|
procedure TPasResolver.OnExprEvalLog(Sender: TResExprEvaluator;
|
|
|
const id: TMaxPrecInt; MsgType: TMessageType; MsgNumber: integer;
|
|
|
const Fmt: String; Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif};
|
|
@@ -14580,6 +14670,8 @@ var
|
|
|
Param: TPasExpr;
|
|
|
ParamResolved, ElTypeResolved, FirstElTypeResolved: TPasResolverResult;
|
|
|
i: Integer;
|
|
|
+ ArrType: TPasArrayType;
|
|
|
+ ElType: TPasType;
|
|
|
begin
|
|
|
Result:=cIncompatible;
|
|
|
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
|
@@ -14598,7 +14690,11 @@ begin
|
|
|
if ParamResolved.BaseType=btContext then
|
|
|
begin
|
|
|
if IsDynArray(ParamResolved.LoTypeEl) then
|
|
|
- ComputeElement(TPasArrayType(ParamResolved.LoTypeEl).ElType,ElTypeResolved,[rcType]);
|
|
|
+ begin
|
|
|
+ ArrType:=TPasArrayType(ParamResolved.LoTypeEl);
|
|
|
+ ElType:=GetArrayElType(ArrType);
|
|
|
+ ComputeElement(ElType,ElTypeResolved,[rcType]);
|
|
|
+ end;
|
|
|
end
|
|
|
else if ParamResolved.BaseType in [btArrayLit,btArrayOrSet] then
|
|
|
SetResolverValueExpr(ElTypeResolved,ParamResolved.SubType,
|
|
@@ -14793,6 +14889,8 @@ var
|
|
|
Params: TParamsExpr;
|
|
|
Param, ItemParam: TPasExpr;
|
|
|
ItemResolved, ParamResolved, ElTypeResolved: TPasResolverResult;
|
|
|
+ ArrType: TPasArrayType;
|
|
|
+ ElType: TPasType;
|
|
|
begin
|
|
|
Result:=cIncompatible;
|
|
|
if not CheckBuiltInMinParamCount(Proc,Expr,3,RaiseOnError) then
|
|
@@ -14817,7 +14915,9 @@ begin
|
|
|
if (ParamResolved.BaseType<>btContext)
|
|
|
or not IsDynArray(ParamResolved.LoTypeEl) then
|
|
|
exit(CheckRaiseTypeArgNo(20170329172024,2,Param,ParamResolved,'dynamic array',RaiseOnError));
|
|
|
- ComputeElement(TPasArrayType(ParamResolved.LoTypeEl).ElType,ElTypeResolved,[rcType]);
|
|
|
+ ArrType:=TPasArrayType(ParamResolved.LoTypeEl);
|
|
|
+ ElType:=GetArrayElType(ArrType);
|
|
|
+ ComputeElement(ElType,ElTypeResolved,[rcType]);
|
|
|
if CheckAssignResCompatibility(ElTypeResolved,ItemResolved,ItemParam,RaiseOnError)=cIncompatible then
|
|
|
exit(cIncompatible);
|
|
|
|
|
@@ -14837,6 +14937,7 @@ var
|
|
|
P: TPasExprArray;
|
|
|
Param0, Param1: TPasExpr;
|
|
|
ArrayResolved, ElTypeResolved: TPasResolverResult;
|
|
|
+ ElType: TPasType;
|
|
|
begin
|
|
|
if Proc=nil then ;
|
|
|
P:=Params.Params;
|
|
@@ -14853,7 +14954,8 @@ begin
|
|
|
if (ArrayResolved.BaseType<>btContext)
|
|
|
or not IsDynArray(ArrayResolved.LoTypeEl) then
|
|
|
RaiseNotYetImplemented(20180622144039,Param1);
|
|
|
- ComputeElement(TPasArrayType(ArrayResolved.LoTypeEl).ElType,ElTypeResolved,[rcType]);
|
|
|
+ ElType:=GetArrayElType(TPasArrayType(ArrayResolved.LoTypeEl));
|
|
|
+ ComputeElement(ElType,ElTypeResolved,[rcType]);
|
|
|
if (ElTypeResolved.BaseType=btContext)
|
|
|
and (ElTypeResolved.LoTypeEl.ClassType=TPasArrayType) then
|
|
|
MarkArrayExprRecursive(Param0,TPasArrayType(ElTypeResolved.LoTypeEl));
|
|
@@ -18082,7 +18184,7 @@ begin
|
|
|
exit(false);
|
|
|
if length(Arr1.Ranges)>0 then
|
|
|
RaiseNotYetImplemented(20170328093733,Arr1.Ranges[0],'anonymous static array');
|
|
|
- Result:=CheckElTypeCompatibility(Arr1.ElType,Arr2.ElType,ResolveAlias);
|
|
|
+ Result:=CheckElTypeCompatibility(GetArrayElType(Arr1),GetArrayElType(Arr2),ResolveAlias);
|
|
|
exit;
|
|
|
end;
|
|
|
|
|
@@ -19574,9 +19676,14 @@ begin
|
|
|
ArrayEl:=TPasArrayType(T.LoTypeEl);
|
|
|
if length(ArrayEl.Ranges)=0 then
|
|
|
begin
|
|
|
- Result:='array of '+ArrayEl.ElType.Name;
|
|
|
- if IsOpenArray(ArrayEl) then
|
|
|
- Result:='open '+Result;
|
|
|
+ if ArrayEl.ElType=nil then
|
|
|
+ Result:='array of const'
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ Result:='array of '+ArrayEl.ElType.Name;
|
|
|
+ if IsOpenArray(ArrayEl) then
|
|
|
+ Result:='open '+Result;
|
|
|
+ end;
|
|
|
end
|
|
|
else
|
|
|
Result:='static array[] of '+ArrayEl.ElType.Name;
|
|
@@ -19610,6 +19717,8 @@ function TPasResolver.GetTypeDescription(aType: TPasType; AddPath: boolean): str
|
|
|
begin
|
|
|
if length(TPasArrayType(aType).Ranges)>0 then
|
|
|
Result:='static array'
|
|
|
+ else if TPasArrayType(aType).ElType=nil then
|
|
|
+ Result:='array of const'
|
|
|
else if IsOpenArray(aType) then
|
|
|
Result:='open array'
|
|
|
else
|
|
@@ -19900,12 +20009,13 @@ var
|
|
|
SrcResolved, DstResolved: TPasResolverResult;
|
|
|
LArray, RArray: TPasArrayType;
|
|
|
GotDesc, ExpDesc: String;
|
|
|
+ CurTVarRec: TPasRecordType;
|
|
|
|
|
|
- function RaiseIncompatType: integer;
|
|
|
+ function RaiseIncompatType(Id: TMaxPrecInt): integer;
|
|
|
begin
|
|
|
Result:=cIncompatible;
|
|
|
if not RaiseOnIncompatible then exit;
|
|
|
- RaiseIncompatibleTypeRes(20170216152505,nIncompatibleTypesGotExpected,
|
|
|
+ RaiseIncompatibleTypeRes(Id,nIncompatibleTypesGotExpected,
|
|
|
[],RHS,LHS,ErrorEl);
|
|
|
end;
|
|
|
|
|
@@ -19932,7 +20042,7 @@ begin
|
|
|
begin
|
|
|
Result:=cIncompatible;
|
|
|
if not (rrfReadable in RHS.Flags) then
|
|
|
- exit(RaiseIncompatType);
|
|
|
+ exit(RaiseIncompatType(20190215112914));
|
|
|
if TPasClassType(LTypeEl).ObjKind=TPasClassType(RTypeEl).ObjKind then
|
|
|
Result:=CheckSrcIsADstType(RHS,LHS)
|
|
|
else if TPasClassType(LTypeEl).ObjKind=okInterface then
|
|
@@ -19950,7 +20060,7 @@ begin
|
|
|
[],RTypeEl,LTypeEl,ErrorEl);
|
|
|
end
|
|
|
else
|
|
|
- exit(RaiseIncompatType);
|
|
|
+ exit(RaiseIncompatType(20190215112919));
|
|
|
end
|
|
|
else if LTypeEl.ClassType=TPasClassOfType then
|
|
|
begin
|
|
@@ -20020,15 +20130,7 @@ begin
|
|
|
begin
|
|
|
// DynOrOpenArr:=array
|
|
|
RArray:=TPasArrayType(RTypeEl);
|
|
|
- if length(RArray.Ranges)>1 then
|
|
|
- begin
|
|
|
- // DynOrOpenArr:=MultiDimStaticArr -> no
|
|
|
- if RaiseOnIncompatible then
|
|
|
- RaiseIncompatibleTypeDesc(20180620115235,nIncompatibleTypesGotExpected,
|
|
|
- [],'multi dimensional static array','dynamic array',ErrorEl);
|
|
|
- exit(cIncompatible);
|
|
|
- end
|
|
|
- else if length(RArray.Ranges)>0 then
|
|
|
+ if length(RArray.Ranges)=1 then
|
|
|
begin
|
|
|
// DynOrOpenArr:=SingleDimStaticArr
|
|
|
if (msDelphi in CurrentParser.CurrentModeswitches)
|
|
@@ -20042,6 +20144,14 @@ begin
|
|
|
exit(cIncompatible);
|
|
|
end;
|
|
|
end
|
|
|
+ else if length(RArray.Ranges)>1 then
|
|
|
+ begin
|
|
|
+ // DynOrOpenArr:=MultiDimStaticArr -> no
|
|
|
+ if RaiseOnIncompatible then
|
|
|
+ RaiseIncompatibleTypeDesc(20180620115235,nIncompatibleTypesGotExpected,
|
|
|
+ [],'multi dimensional static array','dynamic array',ErrorEl);
|
|
|
+ exit(cIncompatible);
|
|
|
+ end
|
|
|
else if not (proOpenAsDynArrays in Options) then
|
|
|
begin
|
|
|
if IsOpenArray(LArray) then
|
|
@@ -20061,16 +20171,33 @@ begin
|
|
|
and (LArray<>RArray) then
|
|
|
begin
|
|
|
// Delphi does not allow assigning arrays with same element types
|
|
|
- if RaiseOnIncompatible then
|
|
|
- RaiseIncompatibleTypeRes(20180620115515,nIncompatibleTypesGotExpected,
|
|
|
- [],RHS,LHS,ErrorEl);
|
|
|
- exit(cIncompatible);
|
|
|
+ exit(RaiseIncompatType(20190215112626));
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
// check element type
|
|
|
- if CheckElTypeCompatibility(LArray.ElType,RArray.ElType,prraAlias) then
|
|
|
+ if LArray.ElType=nil then
|
|
|
+ begin
|
|
|
+ // ArrayOfConst:=SingleDimArr
|
|
|
+ if RArray.ElType=nil then
|
|
|
+ // ArrayOfConst:=ArrayOfConst
|
|
|
+ Result:=cExact
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ CurTVarRec:=GetTVarRec(LArray);
|
|
|
+ if ResolveAliasType(RArray.ElType)=CurTVarRec then
|
|
|
+ // ArrayOfConst:=ArrayOfTVarRec
|
|
|
+ Result:=cExact
|
|
|
+ else
|
|
|
+ // ArrayOfConst:=SingleDimArr
|
|
|
+ exit(RaiseIncompatType(20190215112715));
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else if RArray.ElType=nil then
|
|
|
+ // ArrayOfNonConst:=ArrayOfConst
|
|
|
+ exit(RaiseIncompatType(20190215112907))
|
|
|
+ else if CheckElTypeCompatibility(LArray.ElType,RArray.ElType,prraAlias) then
|
|
|
Result:=cExact
|
|
|
else if RaiseOnIncompatible then
|
|
|
begin
|
|
@@ -20118,7 +20245,7 @@ begin
|
|
|
exit(cIncompatible);
|
|
|
end
|
|
|
else
|
|
|
- exit(RaiseIncompatType);
|
|
|
+ exit(RaiseIncompatType(20190215112924));
|
|
|
end
|
|
|
else if LTypeEl.ClassType=TPasPointerType then
|
|
|
begin
|
|
@@ -20128,7 +20255,7 @@ begin
|
|
|
Result:=CheckAssignCompatibilityPointerType(TPasPointerType(LTypeEl).DestType,
|
|
|
TPasPointerType(RTypeEl).DestType,ErrorEl,false);
|
|
|
if Result=cIncompatible then
|
|
|
- exit(RaiseIncompatType);
|
|
|
+ exit(RaiseIncompatType(20190215112927));
|
|
|
end;
|
|
|
end
|
|
|
else
|
|
@@ -20139,9 +20266,9 @@ begin
|
|
|
{$ENDIF}
|
|
|
|
|
|
if Result=-1 then
|
|
|
- exit(RaiseIncompatType);
|
|
|
+ exit(RaiseIncompatType(20190215112931));
|
|
|
if not (rrfReadable in RHS.Flags) then
|
|
|
- exit(RaiseIncompatType);
|
|
|
+ exit(RaiseIncompatType(20190215112934));
|
|
|
end;
|
|
|
|
|
|
function TPasResolver.CheckAssignCompatibilityArrayType(const LHS,
|
|
@@ -20356,9 +20483,9 @@ function TPasResolver.CheckAssignCompatibilityArrayType(const LHS,
|
|
|
exit;
|
|
|
end;
|
|
|
// dynarr:=dynarr -> check element type
|
|
|
- ComputeElement(ArrType.ElType,ElTypeResolved,[rcType]);
|
|
|
+ ComputeElement(GetArrayElType(ArrType),ElTypeResolved,[rcType]);
|
|
|
Include(ElTypeResolved.Flags,rrfWritable);
|
|
|
- ComputeElement(RArrayType.ElType,ValueResolved,[rcType]);
|
|
|
+ ComputeElement(GetArrayElType(RArrayType),ValueResolved,[rcType]);
|
|
|
Include(ValueResolved.Flags,rrfReadable);
|
|
|
Result:=CheckAssignResCompatibility(ElTypeResolved,ValueResolved,ErrorEl,RaiseOnIncompatible);
|
|
|
exit;
|
|
@@ -20540,6 +20667,12 @@ begin
|
|
|
if (LHS.BaseType<>btContext) or (not (LHS.LoTypeEl is TPasArrayType)) then
|
|
|
RaiseInternalError(20170222230012);
|
|
|
LArrType:=TPasArrayType(LHS.LoTypeEl);
|
|
|
+ if (LArrType.ElType=nil) and (rrfReadable in RHS.Flags)
|
|
|
+ and (RHS.BaseType in [btArrayLit,btArrayOrSet]) then
|
|
|
+ begin
|
|
|
+ // ArrayOfConst:=[]
|
|
|
+ exit(cExact);
|
|
|
+ end;
|
|
|
|
|
|
CheckRange(LArrType,0,RHS,ErrorEl);
|
|
|
|
|
@@ -21101,7 +21234,7 @@ function TPasResolver.CheckTypeCastArray(FromType, ToType: TPasArrayType;
|
|
|
ElTypeResolved.BaseType:=btNone;
|
|
|
exit(true);
|
|
|
end;
|
|
|
- ComputeElement(ArrType.ElType,ElTypeResolved,[rcType]);
|
|
|
+ ComputeElement(GetArrayElType(ArrType),ElTypeResolved,[rcType]);
|
|
|
if (ElTypeResolved.BaseType<>btContext)
|
|
|
or (ElTypeResolved.LoTypeEl.ClassType<>TPasArrayType) then
|
|
|
exit(false);
|
|
@@ -22082,6 +22215,8 @@ begin
|
|
|
exit(false);
|
|
|
if length(TPasArrayType(TypeEl).Ranges)<>0 then
|
|
|
exit(false);
|
|
|
+ if TPasArrayType(TypeEl).ElType=nil then
|
|
|
+ exit(true);// array of const is a dynamic array of TVarRec
|
|
|
if OptionalOpenArray and (proOpenAsDynArrays in Options) then
|
|
|
Result:=true
|
|
|
else
|
|
@@ -22094,7 +22229,8 @@ begin
|
|
|
and (TypeEl.ClassType=TPasArrayType)
|
|
|
and (length(TPasArrayType(TypeEl).Ranges)=0)
|
|
|
and (TypeEl.Parent<>nil)
|
|
|
- and (TypeEl.Parent.ClassType=TPasArgument);
|
|
|
+ and (TypeEl.Parent.ClassType=TPasArgument)
|
|
|
+ and (TPasArrayType(TypeEl).ElType<>nil);
|
|
|
end;
|
|
|
|
|
|
function TPasResolver.IsDynOrOpenArray(TypeEl: TPasType): boolean;
|
|
@@ -22104,6 +22240,19 @@ begin
|
|
|
and (length(TPasArrayType(TypeEl).Ranges)=0);
|
|
|
end;
|
|
|
|
|
|
+function TPasResolver.IsArrayOfConst(TypeEl: TPasType): boolean;
|
|
|
+begin
|
|
|
+ Result:=(TypeEl<>nil) and (TypeEl.ClassType=TPasArrayType)
|
|
|
+ and (TPasArrayType(TypeEl).ElType=nil);
|
|
|
+end;
|
|
|
+
|
|
|
+function TPasResolver.GetArrayElType(ArrType: TPasArrayType): TPasType;
|
|
|
+begin
|
|
|
+ Result:=ArrType.ElType;
|
|
|
+ if Result=nil then
|
|
|
+ Result:=GetTVarRec(ArrType);
|
|
|
+end;
|
|
|
+
|
|
|
function TPasResolver.IsVarInit(Expr: TPasExpr): boolean;
|
|
|
var
|
|
|
C: TClass;
|