mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 21:02:09 +02:00
* Empty sections in advanced records
git-svn-id: trunk@47509 -
This commit is contained in:
parent
96dd5d4f76
commit
713d6a0649
@ -534,6 +534,7 @@ type
|
|||||||
procedure ClearTypeReferences(aType: TPasElement); override;
|
procedure ClearTypeReferences(aType: TPasElement); override;
|
||||||
public
|
public
|
||||||
DestType: TPasType;
|
DestType: TPasType;
|
||||||
|
SubType: TPasType;
|
||||||
Expr: TPasExpr;
|
Expr: TPasExpr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3303,6 +3304,7 @@ end;
|
|||||||
|
|
||||||
destructor TPasAliasType.Destroy;
|
destructor TPasAliasType.Destroy;
|
||||||
begin
|
begin
|
||||||
|
ReleaseAndNil(TPasElement(SubType){$IFDEF CheckPasTreeRefCount},'TPasAliasType.SubType'{$ENDIF});
|
||||||
ReleaseAndNil(TPasElement(DestType){$IFDEF CheckPasTreeRefCount},'TPasAliasType.DestType'{$ENDIF});
|
ReleaseAndNil(TPasElement(DestType){$IFDEF CheckPasTreeRefCount},'TPasAliasType.DestType'{$ENDIF});
|
||||||
ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'TPasAliasType.Expr'{$ENDIF});
|
ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'TPasAliasType.Expr'{$ENDIF});
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
|
@ -1408,11 +1408,11 @@ end;
|
|||||||
|
|
||||||
procedure TPasWriter.WriteImplRaise(aRaise: TPasImplRaise);
|
procedure TPasWriter.WriteImplRaise(aRaise: TPasImplRaise);
|
||||||
begin
|
begin
|
||||||
if assigned(aRaise.ExceptObject) then
|
if assigned(aRaise.ExceptObject) then
|
||||||
begin
|
begin
|
||||||
Add('raise %s',[GetExpr(aRaise.ExceptObject)]);
|
Add('raise %s',[GetExpr(aRaise.ExceptObject)]);
|
||||||
if aRaise.ExceptAddr<>Nil then
|
if aRaise.ExceptAddr<>Nil then
|
||||||
Add(' at %s',[GetExpr(aRaise.ExceptAddr)]);
|
Add(' at %s',[GetExpr(aRaise.ExceptAddr)]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Add('raise');
|
Add('raise');
|
||||||
|
@ -1759,12 +1759,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
// read nested specialize arguments
|
// read nested specialize arguments
|
||||||
ReadSpecializeArguments(ST,ST.Params);
|
ReadSpecializeArguments(ST,ST.Params);
|
||||||
// Important: resolve type reference AFTER args, because arg count is needed
|
|
||||||
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
|
||||||
|
|
||||||
if CurToken<>tkGreaterThan then
|
if CurToken<>tkGreaterThan then
|
||||||
ParseExcTokenError('[20190801113005]');
|
ParseExcTokenError('[20190801113005]');
|
||||||
// ToDo: cascaded specialize A<B>.C<D>
|
|
||||||
|
// Check for cascaded specialize A<B>.C or A<B>.C<D>
|
||||||
|
NextToken;
|
||||||
|
if CurToken<>tkDot then
|
||||||
|
UnGetToken
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
ST.SubType:=ParseSimpleType(ST,CurSourcePos,GenName,False);
|
||||||
|
end;
|
||||||
|
// Important: resolve type reference AFTER args, because arg count is needed
|
||||||
|
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
||||||
|
|
||||||
Engine.FinishScope(stTypeDef,ST);
|
Engine.FinishScope(stTypeDef,ST);
|
||||||
Result:=ST;
|
Result:=ST;
|
||||||
@ -6846,6 +6854,24 @@ var
|
|||||||
Scanner.UnSetTokenOption(toOperatorToken);
|
Scanner.UnSetTokenOption(toOperatorToken);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Function CheckSection : Boolean;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Advanced records can have empty sections.
|
||||||
|
{ Use Case:
|
||||||
|
Record
|
||||||
|
type
|
||||||
|
const
|
||||||
|
var
|
||||||
|
Case Integer of
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
NextToken;
|
||||||
|
Result:=CurToken in [tkvar,tktype,tkConst,tkCase];
|
||||||
|
if Not Result then
|
||||||
|
UngetToken;
|
||||||
|
end;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
VariantName : String;
|
VariantName : String;
|
||||||
v : TPasMemberVisibility;
|
v : TPasMemberVisibility;
|
||||||
@ -6874,6 +6900,8 @@ begin
|
|||||||
DisableIsClass;
|
DisableIsClass;
|
||||||
if Not AllowMethods then
|
if Not AllowMethods then
|
||||||
ParseExc(nErrRecordTypesNotAllowed,SErrRecordTypesNotAllowed);
|
ParseExc(nErrRecordTypesNotAllowed,SErrRecordTypesNotAllowed);
|
||||||
|
if CheckSection then
|
||||||
|
continue;
|
||||||
ExpectToken(tkIdentifier);
|
ExpectToken(tkIdentifier);
|
||||||
ParseMembersLocalTypes(ARec,v);
|
ParseMembersLocalTypes(ARec,v);
|
||||||
end;
|
end;
|
||||||
@ -6882,6 +6910,8 @@ begin
|
|||||||
DisableIsClass;
|
DisableIsClass;
|
||||||
if Not AllowMethods then
|
if Not AllowMethods then
|
||||||
ParseExc(nErrRecordConstantsNotAllowed,SErrRecordConstantsNotAllowed);
|
ParseExc(nErrRecordConstantsNotAllowed,SErrRecordConstantsNotAllowed);
|
||||||
|
if CheckSection then
|
||||||
|
continue;
|
||||||
ExpectToken(tkIdentifier);
|
ExpectToken(tkIdentifier);
|
||||||
ParseMembersLocalConsts(ARec,v);
|
ParseMembersLocalConsts(ARec,v);
|
||||||
end;
|
end;
|
||||||
@ -6889,6 +6919,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
if Not AllowMethods then
|
if Not AllowMethods then
|
||||||
ParseExc(nErrRecordVariablesNotAllowed,SErrRecordVariablesNotAllowed);
|
ParseExc(nErrRecordVariablesNotAllowed,SErrRecordVariablesNotAllowed);
|
||||||
|
if CheckSection then
|
||||||
|
continue;
|
||||||
ExpectToken(tkIdentifier);
|
ExpectToken(tkIdentifier);
|
||||||
OldCount:=ARec.Members.Count;
|
OldCount:=ARec.Members.Count;
|
||||||
ParseInlineVarDecl(ARec, ARec.Members, v, AEndToken=tkBraceClose);
|
ParseInlineVarDecl(ARec, ARec.Members, v, AEndToken=tkBraceClose);
|
||||||
|
@ -363,6 +363,8 @@ type
|
|||||||
Procedure TestAdvRec_ProcOverrideFail;
|
Procedure TestAdvRec_ProcOverrideFail;
|
||||||
Procedure TestAdvRec_ProcMessageFail;
|
Procedure TestAdvRec_ProcMessageFail;
|
||||||
Procedure TestAdvRec_DestructorFail;
|
Procedure TestAdvRec_DestructorFail;
|
||||||
|
Procedure TestAdvRec_CaseInVar;
|
||||||
|
Procedure TestAdvRec_EmptySections;
|
||||||
Procedure TestAdvRecordInFunction;
|
Procedure TestAdvRecordInFunction;
|
||||||
Procedure TestAdvRecordInAnonFunction;
|
Procedure TestAdvRecordInAnonFunction;
|
||||||
Procedure TestAdvRecordClassOperator;
|
Procedure TestAdvRecordClassOperator;
|
||||||
@ -2612,6 +2614,29 @@ begin
|
|||||||
ParseRecordFail(SParserNoConstructorAllowed,nParserNoConstructorAllowed);
|
ParseRecordFail(SParserNoConstructorAllowed,nParserNoConstructorAllowed);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestRecordTypeParser.TestAdvRec_CaseInVar;
|
||||||
|
|
||||||
|
// Found in System.UITypes.pas
|
||||||
|
|
||||||
|
begin
|
||||||
|
StartRecord(true);
|
||||||
|
AddMember('var');
|
||||||
|
AddMember('Case Integer of');
|
||||||
|
AddMember(' 1 : (x: integer);');
|
||||||
|
AddMember(' 2 : (y,z: integer)');
|
||||||
|
ParseRecord;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestRecordTypeParser.TestAdvRec_EmptySections;
|
||||||
|
begin
|
||||||
|
StartRecord(true);
|
||||||
|
AddMember('const');
|
||||||
|
AddMember('type');
|
||||||
|
AddMember('var');
|
||||||
|
AddMember(' x: integer;');
|
||||||
|
ParseRecord;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestRecordTypeParser.TestAdvRecordInFunction;
|
procedure TTestRecordTypeParser.TestAdvRecordInFunction;
|
||||||
|
|
||||||
// Src from bug report 36179
|
// Src from bug report 36179
|
||||||
|
Loading…
Reference in New Issue
Block a user