mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 06:32:03 +02:00
fcl-passrc: fixed parsing generic array type
git-svn-id: trunk@42472 -
This commit is contained in:
parent
e97a2cb03e
commit
f35e711024
@ -606,6 +606,10 @@ type
|
|||||||
{ TPasArrayType }
|
{ TPasArrayType }
|
||||||
|
|
||||||
TPasArrayType = class(TPasType)
|
TPasArrayType = class(TPasType)
|
||||||
|
private
|
||||||
|
procedure ClearChildReferences(El: TPasElement; arg: pointer);
|
||||||
|
protected
|
||||||
|
procedure SetParent(const AValue: TPasElement); override;
|
||||||
public
|
public
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function ElementTypeName: string; override;
|
function ElementTypeName: string; override;
|
||||||
@ -617,9 +621,11 @@ type
|
|||||||
Ranges: TPasExprArray; // only valid if Parser po_arrayrangeexpr enabled
|
Ranges: TPasExprArray; // only valid if Parser po_arrayrangeexpr enabled
|
||||||
PackMode : TPackMode;
|
PackMode : TPackMode;
|
||||||
ElType: TPasType;
|
ElType: TPasType;
|
||||||
Function IsGenericArray : Boolean;
|
GenericTemplateTypes: TFPList; // list of TPasGenericTemplateType, can be nil
|
||||||
Function IsPacked : Boolean;
|
function IsGenericArray : Boolean;
|
||||||
|
function IsPacked : Boolean;
|
||||||
procedure AddRange(Range: TPasExpr);
|
procedure AddRange(Range: TPasExpr);
|
||||||
|
procedure SetGenericTemplates(AList: TFPList); virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPasFileType }
|
{ TPasFileType }
|
||||||
@ -1734,6 +1740,7 @@ const
|
|||||||
= ('cvar', 'external', 'public', 'export', 'class', 'static');
|
= ('cvar', 'external', 'public', 'export', 'class', 'static');
|
||||||
|
|
||||||
procedure ReleaseAndNil(var El: TPasElement {$IFDEF CheckPasTreeRefCount}; const Id: string{$ENDIF}); overload;
|
procedure ReleaseAndNil(var El: TPasElement {$IFDEF CheckPasTreeRefCount}; const Id: string{$ENDIF}); overload;
|
||||||
|
procedure ReleaseGenericTemplateTypes(var GenericTemplateTypes: TFPList{$IFDEF CheckPasTreeRefCount}; const Id: string{$ENDIF});
|
||||||
function GenericTemplateTypesAsString(List: TFPList): string;
|
function GenericTemplateTypesAsString(List: TFPList): string;
|
||||||
|
|
||||||
{$IFDEF HasPTDumpStack}
|
{$IFDEF HasPTDumpStack}
|
||||||
@ -1755,6 +1762,21 @@ begin
|
|||||||
El:=nil;
|
El:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ReleaseGenericTemplateTypes(var GenericTemplateTypes: TFPList{$IFDEF CheckPasTreeRefCount}; const Id: string{$ENDIF});
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
El: TPasElement;
|
||||||
|
begin
|
||||||
|
if GenericTemplateTypes=nil then exit;
|
||||||
|
for i := 0 to GenericTemplateTypes.Count - 1 do
|
||||||
|
begin
|
||||||
|
El:=TPasElement(GenericTemplateTypes[i]);
|
||||||
|
El.Parent:=nil;
|
||||||
|
El.Release{$IFDEF CheckPasTreeRefCount}(Id){$ENDIF};
|
||||||
|
end;
|
||||||
|
FreeAndNil(GenericTemplateTypes);
|
||||||
|
end;
|
||||||
|
|
||||||
function GenericTemplateTypesAsString(List: TFPList): string;
|
function GenericTemplateTypesAsString(List: TFPList): string;
|
||||||
var
|
var
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
@ -3056,11 +3078,28 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasArrayType.ClearChildReferences(El: TPasElement; arg: pointer);
|
||||||
|
begin
|
||||||
|
El.ClearTypeReferences(Self);
|
||||||
|
if arg=nil then ;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPasArrayType.SetParent(const AValue: TPasElement);
|
||||||
|
begin
|
||||||
|
if (AValue=nil) and (Parent<>nil) then
|
||||||
|
begin
|
||||||
|
// parent is cleared
|
||||||
|
// -> clear all child references to this array (releasing loops)
|
||||||
|
ForEachCall(@ClearChildReferences,nil);
|
||||||
|
end;
|
||||||
|
inherited SetParent(AValue);
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TPasArrayType.Destroy;
|
destructor TPasArrayType.Destroy;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
|
ReleaseGenericTemplateTypes(GenericTemplateTypes{$IFDEF CheckPasTreeRefCount},'TPasArrayType'{$ENDIF});
|
||||||
for i:=0 to length(Ranges)-1 do
|
for i:=0 to length(Ranges)-1 do
|
||||||
Ranges[i].Release{$IFDEF CheckPasTreeRefCount}('TPasArrayType.Ranges'){$ENDIF};
|
Ranges[i].Release{$IFDEF CheckPasTreeRefCount}('TPasArrayType.Ranges'){$ENDIF};
|
||||||
ReleaseAndNil(TPasElement(ElType){$IFDEF CheckPasTreeRefCount},'TPasArrayType.ElType'{$ENDIF});
|
ReleaseAndNil(TPasElement(ElType){$IFDEF CheckPasTreeRefCount},'TPasArrayType.ElType'{$ENDIF});
|
||||||
@ -3073,7 +3112,6 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor TPasEnumType.Create(const AName: string; AParent: TPasElement);
|
constructor TPasEnumType.Create(const AName: string; AParent: TPasElement);
|
||||||
begin
|
begin
|
||||||
inherited Create(AName, AParent);
|
inherited Create(AName, AParent);
|
||||||
@ -4032,29 +4070,39 @@ end;
|
|||||||
function TPasArrayType.GetDeclaration (full : boolean) : string;
|
function TPasArrayType.GetDeclaration (full : boolean) : string;
|
||||||
begin
|
begin
|
||||||
Result:='Array';
|
Result:='Array';
|
||||||
|
if Full then
|
||||||
|
begin
|
||||||
|
if GenericTemplateTypes<>nil then
|
||||||
|
Result:=Result+GenericTemplateTypesAsString(GenericTemplateTypes)+' = '+Result
|
||||||
|
else
|
||||||
|
Result:=Result+' = '+Result;
|
||||||
|
end;
|
||||||
If (IndexRange<>'') then
|
If (IndexRange<>'') then
|
||||||
Result:=Result+'['+IndexRange+']';
|
Result:=Result+'['+IndexRange+']';
|
||||||
Result:=Result+' of ';
|
Result:=Result+' of ';
|
||||||
If IsPacked then
|
If IsPacked then
|
||||||
Result := 'packed '+Result; // 12/04/04 Dave - Added
|
Result := 'packed '+Result; // 12/04/04 Dave - Added
|
||||||
If Assigned(Eltype) then
|
If Assigned(Eltype) then
|
||||||
Result:=Result+ElType.Name
|
Result:=Result+ElType.Name
|
||||||
else
|
else
|
||||||
Result:=Result+'const';
|
Result:=Result+'const';
|
||||||
If Full Then
|
|
||||||
Result:=FixTypeDecl(Result);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasArrayType.ForEachCall(const aMethodCall: TOnForEachPasElement;
|
procedure TPasArrayType.ForEachCall(const aMethodCall: TOnForEachPasElement;
|
||||||
const Arg: Pointer);
|
const Arg: Pointer);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
inherited ForEachCall(aMethodCall, Arg);
|
inherited ForEachCall(aMethodCall, Arg);
|
||||||
|
if GenericTemplateTypes<>nil then
|
||||||
|
for i:=0 to GenericTemplateTypes.Count-1 do
|
||||||
|
ForEachChildCall(aMethodCall,Arg,TPasElement(GenericTemplateTypes[i]),false);
|
||||||
ForEachChildCall(aMethodCall,Arg,ElType,true);
|
ForEachChildCall(aMethodCall,Arg,ElType,true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasArrayType.IsGenericArray: Boolean;
|
function TPasArrayType.IsGenericArray: Boolean;
|
||||||
begin
|
begin
|
||||||
Result:=ElType is TPasGenericTemplateType;
|
Result:=GenericTemplateTypes<>nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasArrayType.IsPacked: Boolean;
|
function TPasArrayType.IsPacked: Boolean;
|
||||||
@ -4071,6 +4119,22 @@ begin
|
|||||||
Ranges[i]:=Range;
|
Ranges[i]:=Range;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasArrayType.SetGenericTemplates(AList: TFPList);
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
El: TPasElement;
|
||||||
|
begin
|
||||||
|
if GenericTemplateTypes=nil then
|
||||||
|
GenericTemplateTypes:=TFPList.Create;
|
||||||
|
For I:=0 to AList.Count-1 do
|
||||||
|
begin
|
||||||
|
El:=TPasElement(AList[i]);
|
||||||
|
El.Parent:=Self;
|
||||||
|
GenericTemplateTypes.Add(El);
|
||||||
|
end;
|
||||||
|
AList.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasFileType.GetDeclaration (full : boolean) : string;
|
function TPasFileType.GetDeclaration (full : boolean) : string;
|
||||||
begin
|
begin
|
||||||
Result:='File';
|
Result:='File';
|
||||||
@ -4198,13 +4262,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
FreeAndNil(Members);
|
FreeAndNil(Members);
|
||||||
|
|
||||||
for i := 0 to GenericTemplateTypes.Count - 1 do
|
ReleaseGenericTemplateTypes(GenericTemplateTypes
|
||||||
begin
|
{$IFDEF CheckPasTreeRefCount},'TPasMembersType.GenericTemplateTypes'{$ENDIF});
|
||||||
El:=TPasElement(GenericTemplateTypes[i]);
|
|
||||||
El.Parent:=nil;
|
|
||||||
El.Release{$IFDEF CheckPasTreeRefCount}('TPasMembersType.GenericTemplateTypes'){$ENDIF};
|
|
||||||
end;
|
|
||||||
FreeAndNil(GenericTemplateTypes);
|
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
@ -312,7 +312,7 @@ type
|
|||||||
Procedure DoLog(MsgType: TMessageType; MsgNumber: integer; Const Fmt : String; Args : Array of {$ifdef pas2js}jsvalue{$else}const{$endif};SkipSourceInfo : Boolean = False);overload;
|
Procedure DoLog(MsgType: TMessageType; MsgNumber: integer; Const Fmt : String; Args : Array of {$ifdef pas2js}jsvalue{$else}const{$endif};SkipSourceInfo : Boolean = False);overload;
|
||||||
function GetProcTypeFromToken(tk: TToken; IsClass: Boolean=False ): TProcType;
|
function GetProcTypeFromToken(tk: TToken; IsClass: Boolean=False ): TProcType;
|
||||||
procedure ParseAsmBlock(AsmBlock: TPasImplAsmStatement); virtual;
|
procedure ParseAsmBlock(AsmBlock: TPasImplAsmStatement); virtual;
|
||||||
procedure ParseRecordFieldList(ARec: TPasRecordType; AEndToken: TToken; AllowMethods : Boolean);
|
procedure ParseRecordMembers(ARec: TPasRecordType; AEndToken: TToken; AllowMethods : Boolean);
|
||||||
procedure ParseRecordVariantParts(ARec: TPasRecordType; AEndToken: TToken);
|
procedure ParseRecordVariantParts(ARec: TPasRecordType; AEndToken: TToken);
|
||||||
function GetProcedureClass(ProcType : TProcType): TPTreeElement;
|
function GetProcedureClass(ProcType : TProcType): TPTreeElement;
|
||||||
procedure ParseClassFields(AType: TPasClassType; const AVisibility: TPasMemberVisibility; IsClassField : Boolean);
|
procedure ParseClassFields(AType: TPasClassType; const AVisibility: TPasMemberVisibility; IsClassField : Boolean);
|
||||||
@ -366,6 +366,7 @@ type
|
|||||||
function ParseExprOperand(AParent : TPasElement): TPasExpr;
|
function ParseExprOperand(AParent : TPasElement): TPasExpr;
|
||||||
function ParseExpIdent(AParent : TPasElement): TPasExpr; deprecated 'use ParseExprOperand instead'; // since fpc 3.3.1
|
function ParseExpIdent(AParent : TPasElement): TPasExpr; deprecated 'use ParseExprOperand instead'; // since fpc 3.3.1
|
||||||
procedure DoParseClassType(AType: TPasClassType);
|
procedure DoParseClassType(AType: TPasClassType);
|
||||||
|
procedure DoParseArrayType(ArrType: TPasArrayType);
|
||||||
function DoParseExpression(AParent: TPaselement;InitExpr: TPasExpr=nil; AllowEqual : Boolean = True): TPasExpr;
|
function DoParseExpression(AParent: TPaselement;InitExpr: TPasExpr=nil; AllowEqual : Boolean = True): TPasExpr;
|
||||||
function DoParseConstValueExpression(AParent: TPasElement): TPasExpr;
|
function DoParseConstValueExpression(AParent: TPasElement): TPasExpr;
|
||||||
function CheckPackMode: TPackMode;
|
function CheckPackMode: TPackMode;
|
||||||
@ -1957,67 +1958,13 @@ function TPasParser.ParseArrayType(Parent: TPasElement;
|
|||||||
): TPasArrayType;
|
): TPasArrayType;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
S : String;
|
|
||||||
ok: Boolean;
|
ok: Boolean;
|
||||||
RangeExpr: TPasExpr;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := TPasArrayType(CreateElement(TPasArrayType, TypeName, Parent, NamePos));
|
Result := TPasArrayType(CreateElement(TPasArrayType, TypeName, Parent, NamePos));
|
||||||
ok:=false;
|
ok:=false;
|
||||||
try
|
try
|
||||||
Result.PackMode:=PackMode;
|
Result.PackMode:=PackMode;
|
||||||
NextToken;
|
DoParseArrayType(Result);
|
||||||
S:='';
|
|
||||||
case CurToken of
|
|
||||||
tkSquaredBraceOpen:
|
|
||||||
begin
|
|
||||||
// static array
|
|
||||||
if Parent is TPasArgument then
|
|
||||||
ParseExcTokenError('of');
|
|
||||||
repeat
|
|
||||||
NextToken;
|
|
||||||
if po_arrayrangeexpr in Options then
|
|
||||||
begin
|
|
||||||
RangeExpr:=DoParseExpression(Result);
|
|
||||||
Result.AddRange(RangeExpr);
|
|
||||||
end
|
|
||||||
else if CurToken<>tkSquaredBraceClose then
|
|
||||||
S:=S+CurTokenText;
|
|
||||||
if CurToken=tkSquaredBraceClose then
|
|
||||||
break
|
|
||||||
else if CurToken=tkComma then
|
|
||||||
continue
|
|
||||||
else if po_arrayrangeexpr in Options then
|
|
||||||
ParseExcTokenError(']');
|
|
||||||
until false;
|
|
||||||
Result.IndexRange:=S;
|
|
||||||
ExpectToken(tkOf);
|
|
||||||
Result.ElType := ParseType(Result,CurSourcePos);
|
|
||||||
end;
|
|
||||||
tkOf:
|
|
||||||
begin
|
|
||||||
NextToken;
|
|
||||||
if CurToken = tkConst then
|
|
||||||
// array of const
|
|
||||||
begin
|
|
||||||
if not (Parent is TPasArgument) then
|
|
||||||
ParseExcExpectedIdentifier;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if (CurToken=tkarray) and (Parent is TPasArgument) then
|
|
||||||
ParseExcExpectedIdentifier;
|
|
||||||
UngetToken;
|
|
||||||
Result.ElType := ParseType(Result,CurSourcePos);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
ParseExc(nParserArrayTypeSyntaxError,SParserArrayTypeSyntaxError);
|
|
||||||
end;
|
|
||||||
// TPasProcedureType parsing has eaten the semicolon;
|
|
||||||
// We know it was a local definition if the array def (result) is the parent
|
|
||||||
if (Result.ElType is TPasProcedureType) and (Result.ElType.Parent=Result) then
|
|
||||||
UnGetToken;
|
|
||||||
Engine.FinishScope(stTypeDef,Result);
|
Engine.FinishScope(stTypeDef,Result);
|
||||||
ok:=true;
|
ok:=true;
|
||||||
finally
|
finally
|
||||||
@ -3669,7 +3616,7 @@ begin
|
|||||||
Declarations.Classes.Add(RecordEl);
|
Declarations.Classes.Add(RecordEl);
|
||||||
RecordEl.SetGenericTemplates(List);
|
RecordEl.SetGenericTemplates(List);
|
||||||
NextToken;
|
NextToken;
|
||||||
ParseRecordFieldList(RecordEl,tkend,
|
ParseRecordMembers(RecordEl,tkend,
|
||||||
(msAdvancedRecords in Scanner.CurrentModeSwitches)
|
(msAdvancedRecords in Scanner.CurrentModeSwitches)
|
||||||
and not (Declarations is TProcedureBody)
|
and not (Declarations is TProcedureBody)
|
||||||
and (RecordEl.Name<>''));
|
and (RecordEl.Name<>''));
|
||||||
@ -3678,18 +3625,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
tkArray:
|
tkArray:
|
||||||
begin
|
begin
|
||||||
if List.Count<>1 then
|
ArrEl := TPasArrayType(CreateElement(TPasArrayType, TypeName, Declarations, NamePos));
|
||||||
ParseExc(nParserGenericArray1Element,sParserGenericArray1Element);
|
|
||||||
ArrEl:=TPasArrayType(ParseArrayType(Declarations,NamePos,TypeName,pmNone));
|
|
||||||
Declarations.Declarations.Add(ArrEl);
|
Declarations.Declarations.Add(ArrEl);
|
||||||
Declarations.Types.Add(ArrEl);
|
Declarations.Types.Add(ArrEl);
|
||||||
|
ArrEl.SetGenericTemplates(List);
|
||||||
|
DoParseArrayType(ArrEl);
|
||||||
CheckHint(ArrEl,True);
|
CheckHint(ArrEl,True);
|
||||||
{$IFDEF VerbosePasResolver}
|
|
||||||
ParseExcTokenError('20190619145000');
|
|
||||||
{$ENDIF}
|
|
||||||
ArrEl.ElType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
|
|
||||||
ArrEl.ElType:=TPasGenericTemplateType(List[0]);
|
|
||||||
List.Clear;
|
|
||||||
Engine.FinishScope(stTypeDef,ArrEl);
|
Engine.FinishScope(stTypeDef,ArrEl);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
@ -6516,7 +6457,7 @@ begin
|
|||||||
NextToken;
|
NextToken;
|
||||||
M:=TPasRecordType(CreateElement(TPasRecordType,'',V));
|
M:=TPasRecordType(CreateElement(TPasRecordType,'',V));
|
||||||
V.Members:=M;
|
V.Members:=M;
|
||||||
ParseRecordFieldList(M,tkBraceClose,False);
|
ParseRecordMembers(M,tkBraceClose,False);
|
||||||
// Current token is closing ), so we eat that
|
// Current token is closing ), so we eat that
|
||||||
NextToken;
|
NextToken;
|
||||||
// If there is a semicolon, we eat that too.
|
// If there is a semicolon, we eat that too.
|
||||||
@ -6564,7 +6505,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Starts on first token after Record or (. Ends on AEndToken
|
// Starts on first token after Record or (. Ends on AEndToken
|
||||||
procedure TPasParser.ParseRecordFieldList(ARec: TPasRecordType;
|
procedure TPasParser.ParseRecordMembers(ARec: TPasRecordType;
|
||||||
AEndToken: TToken; AllowMethods: Boolean);
|
AEndToken: TToken; AllowMethods: Boolean);
|
||||||
var
|
var
|
||||||
isClass : Boolean;
|
isClass : Boolean;
|
||||||
@ -6756,7 +6697,7 @@ begin
|
|||||||
try
|
try
|
||||||
Result.PackMode:=PackMode;
|
Result.PackMode:=PackMode;
|
||||||
NextToken;
|
NextToken;
|
||||||
ParseRecordFieldList(Result,tkEnd,
|
ParseRecordMembers(Result,tkEnd,
|
||||||
(msAdvancedRecords in Scanner.CurrentModeSwitches) and not (Parent is TProcedureBody));
|
(msAdvancedRecords in Scanner.CurrentModeSwitches) and not (Parent is TProcedureBody));
|
||||||
Engine.FinishScope(stTypeDef,Result);
|
Engine.FinishScope(stTypeDef,Result);
|
||||||
ok:=true;
|
ok:=true;
|
||||||
@ -7172,6 +7113,65 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasParser.DoParseArrayType(ArrType: TPasArrayType);
|
||||||
|
var
|
||||||
|
S: String;
|
||||||
|
RangeExpr: TPasExpr;
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
S:='';
|
||||||
|
case CurToken of
|
||||||
|
tkSquaredBraceOpen:
|
||||||
|
begin
|
||||||
|
// static array
|
||||||
|
if ArrType.Parent is TPasArgument then
|
||||||
|
ParseExcTokenError('of');
|
||||||
|
repeat
|
||||||
|
NextToken;
|
||||||
|
if po_arrayrangeexpr in Options then
|
||||||
|
begin
|
||||||
|
RangeExpr:=DoParseExpression(ArrType);
|
||||||
|
ArrType.AddRange(RangeExpr);
|
||||||
|
end
|
||||||
|
else if CurToken<>tkSquaredBraceClose then
|
||||||
|
S:=S+CurTokenText;
|
||||||
|
if CurToken=tkSquaredBraceClose then
|
||||||
|
break
|
||||||
|
else if CurToken=tkComma then
|
||||||
|
continue
|
||||||
|
else if po_arrayrangeexpr in Options then
|
||||||
|
ParseExcTokenError(']');
|
||||||
|
until false;
|
||||||
|
ArrType.IndexRange:=S;
|
||||||
|
ExpectToken(tkOf);
|
||||||
|
ArrType.ElType := ParseType(ArrType,CurSourcePos);
|
||||||
|
end;
|
||||||
|
tkOf:
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
if CurToken = tkConst then
|
||||||
|
// array of const
|
||||||
|
begin
|
||||||
|
if not (ArrType.Parent is TPasArgument) then
|
||||||
|
ParseExcExpectedIdentifier;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (CurToken=tkarray) and (ArrType.Parent is TPasArgument) then
|
||||||
|
ParseExcExpectedIdentifier;
|
||||||
|
UngetToken;
|
||||||
|
ArrType.ElType := ParseType(ArrType,CurSourcePos);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ParseExc(nParserArrayTypeSyntaxError,SParserArrayTypeSyntaxError);
|
||||||
|
end;
|
||||||
|
// TPasProcedureType parsing has eaten the semicolon;
|
||||||
|
// We know it was a local definition if the array def (ArrType) is the parent
|
||||||
|
if (ArrType.ElType is TPasProcedureType) and (ArrType.ElType.Parent=ArrType) then
|
||||||
|
UnGetToken;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasParser.ParseClassDecl(Parent: TPasElement;
|
function TPasParser.ParseClassDecl(Parent: TPasElement;
|
||||||
const NamePos: TPasSourcePos; const AClassName: String;
|
const NamePos: TPasSourcePos; const AClassName: String;
|
||||||
AObjKind: TPasObjKind; PackMode: TPackMode; GenericArgs: TFPList): TPasType;
|
AObjKind: TPasObjKind; PackMode: TPackMode; GenericArgs: TFPList): TPasType;
|
||||||
|
Loading…
Reference in New Issue
Block a user