fcl-passrc: fixed some mem leaks

git-svn-id: trunk@39453 -
This commit is contained in:
Mattias Gaertner 2018-07-15 22:27:23 +00:00
parent 53e10c99d4
commit 127c3eccb8
9 changed files with 495 additions and 304 deletions

View File

@ -4927,10 +4927,10 @@ procedure TResolveData.SetElement(AValue: TPasElement);
begin
if FElement=AValue then Exit;
if Element<>nil then
Element.Release;
Element.Release{$IFDEF CheckPasTreeRefCount}(ClassName+'.SetElement'){$ENDIF};
FElement:=AValue;
if Element<>nil then
Element.AddRef;
Element.AddRef{$IFDEF CheckPasTreeRefCount}(ClassName+'.SetElement'){$ENDIF};
end;
constructor TResolveData.Create;

View File

@ -2474,7 +2474,7 @@ end;
destructor TResElDataBuiltInProc.Destroy;
begin
ReleaseAndNil(TPasElement(Proc));
ReleaseAndNil(TPasElement(Proc){$IFDEF CheckPasTreeRefCount},'TResElDataBuiltInProc.Proc'{$ENDIF});
inherited Destroy;
end;
@ -2511,10 +2511,10 @@ procedure TPasScopeReference.SetElement(const AValue: TPasElement);
begin
if FElement=AValue then Exit;
if FElement<>nil then
FElement.Release;
FElement.Release{$IFDEF CheckPasTreeRefCount}('TPasScopeReference.SetElement'){$ENDIF};
FElement:=AValue;
if FElement<>nil then
FElement.AddRef;
FElement.AddRef{$IFDEF CheckPasTreeRefCount}('TPasScopeReference.SetElement'){$ENDIF};
end;
destructor TPasScopeReference.Destroy;
@ -2680,7 +2680,7 @@ begin
{$IFDEF VerbosePasResolverMem}
writeln('TPasPropertyScope.Destroy START ',ClassName);
{$ENDIF}
ReleaseAndNil(TPasElement(AncestorProp));
AncestorProp:=nil;
inherited Destroy;
{$IFDEF VerbosePasResolverMem}
writeln('TPasPropertyScope.Destroy END',ClassName);
@ -2694,7 +2694,7 @@ begin
{$IFDEF VerbosePasResolverMem}
writeln('TPasEnumTypeScope.Destroy START ',ClassName);
{$ENDIF}
ReleaseAndNil(TPasElement(CanonicalSet));
ReleaseAndNil(TPasElement(CanonicalSet){$IFDEF CheckPasTreeRefCount},'TPasEnumTypeScope.CanonicalSet'{$ENDIF});
inherited Destroy;
{$IFDEF VerbosePasResolverMem}
writeln('TPasEnumTypeScope.Destroy END ',ClassName);
@ -2847,7 +2847,7 @@ begin
writeln('TPasProcedureScope.Destroy START ',ClassName);
{$ENDIF}
inherited Destroy;
ReleaseAndNil(TPasElement(SelfArg));
ReleaseAndNil(TPasElement(SelfArg){$IFDEF CheckPasTreeRefCount},'TPasProcedureScope.SelfArg'{$ENDIF});
{$IFDEF VerbosePasResolverMem}
writeln('TPasProcedureScope.Destroy END ',ClassName);
{$ENDIF}
@ -2893,7 +2893,7 @@ begin
if CanonicalClassOf<>nil then
begin
CanonicalClassOf.Parent:=nil;
ReleaseAndNil(TPasElement(CanonicalClassOf));
ReleaseAndNil(TPasElement(CanonicalClassOf){$IFDEF CheckPasTreeRefCount},'TPasClassScope.CanonicalClassOf'{$ENDIF});
end;
inherited Destroy;
end;
@ -2939,10 +2939,10 @@ procedure TPasIdentifier.SetElement(AValue: TPasElement);
begin
if FElement=AValue then Exit;
if Element<>nil then
Element.Release;
Element.Release{$IFDEF CheckPasTreeRefCount}('TPasIdentifier.SetElement'){$ENDIF};
FElement:=AValue;
if Element<>nil then
Element.AddRef;
Element.AddRef{$IFDEF CheckPasTreeRefCount}('TPasIdentifier.SetElement'){$ENDIF};
end;
destructor TPasIdentifier.Destroy;
@ -2963,10 +2963,10 @@ procedure EPasResolve.SetPasElement(AValue: TPasElement);
begin
if FPasElement=AValue then Exit;
if PasElement<>nil then
PasElement.Release;
PasElement.Release{$IFDEF CheckPasTreeRefCount}('EPasResolve.SetPasElement'){$ENDIF};
FPasElement:=AValue;
if PasElement<>nil then
PasElement.AddRef;
PasElement.AddRef{$IFDEF CheckPasTreeRefCount}('EPasResolve.SetPasElement'){$ENDIF};
end;
destructor EPasResolve.Destroy;
@ -2987,10 +2987,10 @@ procedure TResolvedReference.SetDeclaration(AValue: TPasElement);
begin
if FDeclaration=AValue then Exit;
if Declaration<>nil then
Declaration.Release;
Declaration.Release{$IFDEF CheckPasTreeRefCount}('TResolvedReference.SetDeclaration'){$ENDIF};
FDeclaration:=AValue;
if Declaration<>nil then
Declaration.AddRef;
Declaration.AddRef{$IFDEF CheckPasTreeRefCount}('TResolvedReference.SetDeclaration'){$ENDIF};
end;
destructor TResolvedReference.Destroy;
@ -3030,10 +3030,10 @@ procedure TPasModuleDotScope.SetModule(AValue: TPasModule);
begin
if FModule=AValue then Exit;
if Module<>nil then
Module.Release;
Module.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleDotScope.SetModule'){$ENDIF};
FModule:=AValue;
if Module<>nil then
Module.AddRef;
Module.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleDotScope.SetModule'){$ENDIF};
end;
destructor TPasModuleDotScope.Destroy;
@ -3202,25 +3202,25 @@ end;
{ TPasModuleScope }
procedure TPasModuleScope.SetAssertClass(const AValue: TPasClassType);
begin
if FAssertClass=AValue then Exit;
if FAssertClass<>nil then
FAssertClass.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetAssertClass'){$ENDIF};
FAssertClass:=AValue;
if FAssertClass<>nil then
FAssertClass.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetAssertClass'){$ENDIF};
end;
procedure TPasModuleScope.SetAssertDefConstructor(const AValue: TPasConstructor
);
begin
if FAssertDefConstructor=AValue then Exit;
if FAssertDefConstructor<>nil then
FAssertDefConstructor.Release;
FAssertDefConstructor.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetAssertDefConstructor'){$ENDIF};
FAssertDefConstructor:=AValue;
if FAssertDefConstructor<>nil then
FAssertDefConstructor.AddRef;
end;
procedure TPasModuleScope.SetAssertClass(const AValue: TPasClassType);
begin
if FAssertClass=AValue then Exit;
if FAssertClass<>nil then
FAssertClass.Release;
FAssertClass:=AValue;
if FAssertClass<>nil then
FAssertClass.AddRef;
FAssertDefConstructor.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetAssertDefConstructor'){$ENDIF};
end;
procedure TPasModuleScope.SetAssertMsgConstructor(const AValue: TPasConstructor
@ -3228,20 +3228,20 @@ procedure TPasModuleScope.SetAssertMsgConstructor(const AValue: TPasConstructor
begin
if FAssertMsgConstructor=AValue then Exit;
if FAssertMsgConstructor<>nil then
FAssertMsgConstructor.Release;
FAssertMsgConstructor.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetAssertMsgConstructor'){$ENDIF};
FAssertMsgConstructor:=AValue;
if FAssertMsgConstructor<>nil then
FAssertMsgConstructor.AddRef;
FAssertMsgConstructor.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetAssertMsgConstructor'){$ENDIF};
end;
procedure TPasModuleScope.SetRangeErrorClass(const AValue: TPasClassType);
begin
if FRangeErrorClass=AValue then Exit;
if FRangeErrorClass<>nil then
FRangeErrorClass.Release;
FRangeErrorClass.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetRangeErrorClass'){$ENDIF};
FRangeErrorClass:=AValue;
if FRangeErrorClass<>nil then
FRangeErrorClass.AddRef;
FRangeErrorClass.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetRangeErrorClass'){$ENDIF};
end;
procedure TPasModuleScope.SetRangeErrorConstructor(const AValue: TPasConstructor
@ -3249,10 +3249,10 @@ procedure TPasModuleScope.SetRangeErrorConstructor(const AValue: TPasConstructor
begin
if FRangeErrorConstructor=AValue then Exit;
if FRangeErrorConstructor<>nil then
FRangeErrorConstructor.Release;
FRangeErrorConstructor.Release{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetRangeErrorConstructor'){$ENDIF};
FRangeErrorConstructor:=AValue;
if FRangeErrorConstructor<>nil then
FRangeErrorConstructor.AddRef;
FRangeErrorConstructor.AddRef{$IFDEF CheckPasTreeRefCount}('TPasModuleScope.SetRangeErrorConstructor'){$ENDIF};
end;
constructor TPasModuleScope.Create;
@ -4567,7 +4567,8 @@ end;
procedure TPasResolver.FinishTypeSection(El: TPasDeclarations);
function ReplaceDestType(Decl: TPasType; var DestType: TPasType;
const DestName: string; MustExist: boolean; ErrorEl: TPasElement): boolean;
const DestName: string; MustExist: boolean; ErrorEl: TPasElement
{$IFDEF CheckPasTreeRefCount}; const RefId: string{$ENDIF}): boolean;
// returns true if replaces
var
Abort: boolean;
@ -4584,6 +4585,7 @@ procedure TPasResolver.FinishTypeSection(El: TPasDeclarations);
RaiseIdentifierNotFound(20170216151543,DestName,ErrorEl)
else
exit(false);
if Data.Found=DestType then exit;
if Decl is TPasClassOfType then
begin
if Data.Found.ClassType<>TPasClassType then
@ -4592,9 +4594,10 @@ procedure TPasResolver.FinishTypeSection(El: TPasDeclarations);
// replace unresolved
OldDestType:=DestType;
DestType:=TPasType(Data.Found);
DestType.AddRef;
OldDestType.Release; // once for the create in TPasResolver
OldDestType.Release; // and once for the reference in TPasParser
DestType.AddRef{$IFDEF CheckPasTreeRefCount}(RefId){$ENDIF};
if OldDestType is TUnresolvedPendingRef then
OldDestType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
OldDestType.Release{$IFDEF CheckPasTreeRefCount}(RefId){$ENDIF};
// check cycles
if Decl is TPasPointerType then
CheckPointerCycle(TPasPointerType(Decl));
@ -4632,7 +4635,8 @@ begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishTypeSection resolving "',ClassOfEl.Name,'" = class of unresolved "',TypeEl.Name,'"');
{$ENDIF}
ReplaceDestType(ClassOfEl,ClassOfEl.DestType,TypeEl.Name,true,UnresolvedEl);
ReplaceDestType(ClassOfEl,ClassOfEl.DestType,TypeEl.Name,true,UnresolvedEl
{$IFDEF CheckPasTreeRefCount},'TPasAliasType.DestType'{$ENDIF});
end
else if TypeEl.ClassType=TPasClassType then
begin
@ -4645,7 +4649,8 @@ begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishTypeSection improving "',ClassOfEl.Name,'" = class of resolved "',TypeEl.Name,'"');
{$ENDIF}
ReplaceDestType(ClassOfEl,ClassOfEl.DestType,TypeEl.Name,false,ClassOfEl);
ReplaceDestType(ClassOfEl,ClassOfEl.DestType,ClassOfEl.DestType.Name,false,ClassOfEl
{$IFDEF CheckPasTreeRefCount},'TPasAliasType.DestType'{$ENDIF});
end;
end
else if C=TPasPointerType then
@ -4659,7 +4664,8 @@ begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishTypeSection resolving "',PtrType.Name,'" = pointer of unresolved "',TypeEl.Name,'"');
{$ENDIF}
ReplaceDestType(PtrType,PtrType.DestType,TypeEl.Name,true,UnresolvedEl);
ReplaceDestType(PtrType,PtrType.DestType,TypeEl.Name,true,UnresolvedEl
{$IFDEF CheckPasTreeRefCount},'TPasPointerType.DestType'{$ENDIF});
end
else
begin
@ -4671,7 +4677,8 @@ begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishTypeSection improving "',PtrType.Name,'" = pointer of resolved "',TypeEl.Name,'"');
{$ENDIF}
ReplaceDestType(PtrType,PtrType.DestType,TypeEl.Name,false,PtrType);
ReplaceDestType(PtrType,PtrType.DestType,TypeEl.Name,false,PtrType
{$IFDEF CheckPasTreeRefCount},'TPasPointerType.DestType'{$ENDIF});
end;
end;
end;
@ -4773,7 +4780,7 @@ begin
{$ENDIF}
Decl:=TPasDeclarations(Parent.Parent);
Decl.Declarations.Add(El);
El.AddRef;
El.AddRef{$IFDEF CheckPasTreeRefCount}('TPasDeclarations.Declarations'){$ENDIF};
El.Parent:=Decl;
Decl.Types.Add(El);
if (El.ClassType=TPasEnumType) and (Parent.ClassType=TPasSetType) then
@ -4785,9 +4792,9 @@ begin
// When a TPasEnumType is created a CanonicalSet is created.
// Release the autocreated CanonicalSet and use the parent.
if EnumScope.CanonicalSet<>nil then
EnumScope.CanonicalSet.Release;
EnumScope.CanonicalSet.Release{$IFDEF CheckPasTreeRefCount}('TPasEnumTypeScope.CanonicalSet'){$ENDIF};
EnumScope.CanonicalSet:=TPasSetType(Parent);
Parent.AddRef;
Parent.AddRef{$IFDEF CheckPasTreeRefCount}('TPasEnumTypeScope.CanonicalSet'){$ENDIF};
end;
end;
end;
@ -5498,9 +5505,10 @@ begin
// 'Self' in a class proc is the hidden classtype argument
SelfArg:=TPasArgument.Create('Self',DeclProc);
ImplProcScope.SelfArg:=SelfArg;
{$IFDEF CheckPasTreeRefCount}SelfArg.RefIds.Add('TPasProcedureScope.SelfArg');{$ENDIF}
SelfArg.Access:=argConst;
SelfArg.ArgType:=CurClassScope.CanonicalClassOf;
SelfArg.ArgType.AddRef;
SelfArg.ArgType.AddRef{$IFDEF CheckPasTreeRefCount}('TPasArgument.ArgType'){$ENDIF};
AddIdentifier(ImplProcScope,'Self',SelfArg,pikSimple);
end;
end
@ -5509,9 +5517,10 @@ begin
// 'Self' in a proc is the hidden instance argument
SelfArg:=TPasArgument.Create('Self',DeclProc);
ImplProcScope.SelfArg:=SelfArg;
{$IFDEF CheckPasTreeRefCount}SelfArg.RefIds.Add('TPasProcedureScope.SelfArg');{$ENDIF}
SelfArg.Access:=argConst;
SelfArg.ArgType:=CurClassType;
CurClassType.AddRef;
CurClassType.AddRef{$IFDEF CheckPasTreeRefCount}('TPasArgument.ArgType'){$ENDIF};
AddIdentifier(ImplProcScope,'Self',SelfArg,pikSimple);
end;
end;
@ -5639,7 +5648,6 @@ var
// override or redeclaration property
AncestorProp:=TPasProperty(AncEl);
TPasPropertyScope(PropEl.CustomData).AncestorProp:=AncestorProp;
AncestorProp.AddRef;
if proFixCaseOfOverrides in Options then
PropEl.Name:=AncestorProp.Name;
end
@ -6387,8 +6395,9 @@ begin
// create canonical class-of for the "Self" in class functions
CanonicalSelf:=TPasClassOfType.Create('Self',aClass);
ClassScope.CanonicalClassOf:=CanonicalSelf;
{$IFDEF CheckPasTreeRefCount}CanonicalSelf.RefIds.Add('TPasClassScope.CanonicalClassOf');{$ENDIF}
CanonicalSelf.DestType:=aClass;
aClass.AddRef; // for the CanonicalSelf.DestType
aClass.AddRef{$IFDEF CheckPasTreeRefCount}('TPasAliasType.DestType'){$ENDIF};
CanonicalSelf.Visibility:=visStrictPrivate;
CanonicalSelf.SourceFilename:=aClass.SourceFilename;
CanonicalSelf.SourceLinenumber:=aClass.SourceLinenumber;
@ -9034,14 +9043,16 @@ begin
// add canonical set
if El.Parent is TPasSetType then
begin
// anonymous enumtype, e.g. "set of ()"
CanonicalSet:=TPasSetType(El.Parent);
CanonicalSet.AddRef;
CanonicalSet.AddRef{$IFDEF CheckPasTreeRefCount}('TPasEnumTypeScope.CanonicalSet'){$ENDIF};
end
else
begin
CanonicalSet:=TPasSetType.Create('',El);
{$IFDEF CheckPasTreeRefCount}CanonicalSet.RefIds.Add('TPasEnumTypeScope.CanonicalSet'){$ENDIF};
CanonicalSet.EnumType:=El;
El.AddRef;
El.AddRef{$IFDEF CheckPasTreeRefCount}('TPasSetType.EnumType'){$ENDIF};
end;
TPasEnumTypeScope(TopScope).CanonicalSet:=CanonicalSet;
end;
@ -13705,6 +13716,7 @@ begin
// create element
El:=AClass.Create(AName,AParent);
{$IFDEF CheckPasTreeRefCount}El.RefIds.Add('CreateElement');{$ENDIF}
FLastElement:=El;
Result:=El;
El.Visibility:=AVisibility;
@ -14407,10 +14419,11 @@ begin
OldType := TPasTypeAliasType(NewType);
NewType := aClass;
TPasTypeAliasType(OldType).DestType:=nil; // clear reference
OldType.Release;
OldType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
// set ancestor
aClass.AncestorType := DestType;
{$IFDEF CheckPasTreeRefCount}DestType.ChangeRefId('TPasAliasType.DestType','TPasClassType.AncestorType');{$ENDIF}
FinishScope(stAncestors,aClass);
end;
end;
@ -14658,7 +14671,7 @@ var
begin
ClearResolveDataList(lkBuiltIn);
for bt in TResolverBaseType do
ReleaseAndNil(TPasElement(FBaseTypes[bt]));
ReleaseAndNil(TPasElement(FBaseTypes[bt]){$IFDEF CheckPasTreeRefCount},'TPasResolver.AddBaseType'{$ENDIF});
for bp in TResolverBuiltInProc do
FBuiltInProcs[bp]:=nil;
end;
@ -14787,6 +14800,7 @@ var
El: TPasUnresolvedSymbolRef;
begin
El:=TPasUnresolvedSymbolRef.Create(aName,nil);
{$IFDEF CheckPasTreeRefCount}El.RefIds.Add('TPasResolver.AddBaseType');{$ENDIF}
if not (Typ in [btNone,btCustom]) then
FBaseTypes[Typ]:=El;
Result:=TResElDataBaseType.Create;
@ -14801,6 +14815,7 @@ var
CustomData: TResElDataBaseType;
begin
Result:=TPasUnresolvedSymbolRef.Create(aName,nil);
{$IFDEF CheckPasTreeRefCount}Result.RefIds.Add('TPasResolver.AddCustomBaseType');{$ENDIF}
CustomData:=aClass.Create;
CustomData.BaseType:=btCustom;
AddResolveData(Result,CustomData,lkBuiltIn);
@ -14830,6 +14845,7 @@ begin
El:=TPasUnresolvedSymbolRef.Create(aName,nil);
Result:=TResElDataBuiltInProc.Create;
Result.Proc:=El;
{$IFDEF CheckPasTreeRefCount}El.RefIds.Add('TResElDataBuiltInProc.Proc');{$ENDIF}
Result.Signature:=Signature;
Result.BuiltIn:=BuiltIn;
Result.GetCallCompatibility:=GetCallCompatibility;

File diff suppressed because it is too large Load Diff

View File

@ -363,10 +363,10 @@ procedure TPAOverrideList.SetElement(AValue: TPasElement);
begin
if FElement=AValue then Exit;
if FElement<>nil then
FElement.Release;
FElement.Release{$IFDEF CheckPasTreeRefCount}('TPAOverrideList.Element'){$ENDIF};
FElement:=AValue;
if FElement<>nil then
FElement.AddRef;
FElement.AddRef{$IFDEF CheckPasTreeRefCount}('TPAOverrideList.Element'){$ENDIF};
end;
constructor TPAOverrideList.Create;
@ -379,7 +379,7 @@ var
i: Integer;
begin
for i:=0 to FOverrides.Count-1 do
TPasElement(FOverrides[i]).Release;
TPasElement(FOverrides[i]).Release{$IFDEF CheckPasTreeRefCount}('TPAOverrideList.Overrides'){$ENDIF};
FreeAndNil(FOverrides);
Element:=nil;
inherited Destroy;
@ -388,7 +388,7 @@ end;
procedure TPAOverrideList.Add(OverrideEl: TPasElement);
begin
FOverrides.Add(OverrideEl);
OverrideEl.AddRef;
OverrideEl.AddRef{$IFDEF CheckPasTreeRefCount}('TPAOverrideList.Overrides'){$ENDIF};
end;
function TPAOverrideList.Count: integer;
@ -402,10 +402,10 @@ procedure TPAElement.SetElement(AValue: TPasElement);
begin
if FElement=AValue then Exit;
if FElement<>nil then
FElement.Release;
FElement.Release{$IFDEF CheckPasTreeRefCount}('TPAElement.Element'){$ENDIF};
FElement:=AValue;
if FElement<>nil then
FElement.AddRef;
FElement.AddRef{$IFDEF CheckPasTreeRefCount}('TPAElement.Element'){$ENDIF};
end;
destructor TPAElement.Destroy;

View File

@ -1337,7 +1337,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -1454,7 +1454,7 @@ begin
if Result=nil then
begin
Expr.Free;
ReleaseAndNil(TPasElement(Ref));
ReleaseAndNil(TPasElement(Ref){$IFDEF CheckPasTreeRefCount},'ResolveTypeReference'{$ENDIF});
ST.Free;
end;
end;
@ -1475,7 +1475,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -1527,10 +1527,10 @@ begin
begin
// simple type reference
if not NeedExpr then
ReleaseAndNil(TPasElement(Expr));
ReleaseAndNil(TPasElement(Expr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
end;
finally
if ST<>nil then St.Release;
if ST<>nil then St.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -1548,7 +1548,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -1588,7 +1588,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
Engine.FinishScope(stTypeDef,Result);
end;
@ -1608,7 +1608,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
Engine.FinishScope(stTypeDef,Result);
end;
@ -1706,7 +1706,7 @@ begin
finally
if not ok then
if Result<>nil then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -1809,7 +1809,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
Engine.FinishScope(stTypeDef,Result);
end;
@ -1920,7 +1920,7 @@ begin
Result:=TPasUnresolvedTypeRef(CreateElement(TPasUnresolvedTypeRef,Name,Parent))
else
begin
Ref.AddRef;
Ref.AddRef{$IFDEF CheckPasTreeRefCount}('ResolveTypeReference'){$ENDIF};
Result:=TPasType(Ref);
end;
end;
@ -1988,7 +1988,8 @@ begin
NextToken;
Result:=Params;
finally
if not Assigned(Result) then Params.Release;
if Result=nil then
Params.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -2059,7 +2060,7 @@ function TPasParser.ParseExpIdent(AParent: TPasElement): TPasExpr;
b:=CreateBinaryExpr(AParent,Last, ParseExpIdent(AParent), TokenToExprOp(optk));
if not Assigned(b.right) then
begin
b.Release;
b.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
ParseExcExpectedIdentifier;
end;
Last:=b;
@ -2162,7 +2163,7 @@ begin
Bin:=CreateBinaryExpr(AParent,Last,ParseExpIdent(AParent),eopNone,SrcPos);
if not Assigned(Bin.right) then
begin
Bin.Release;
Bin.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
ParseExcExpectedIdentifier;
end;
Result:=Bin;
@ -2268,7 +2269,7 @@ begin
finally
if not ok then
begin
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
ISE.Free;
end;
end;
@ -2301,7 +2302,7 @@ type
end;
var
ExpStack : TFPList;
ExpStack : TFPList; // list of TPasExpr
OpStack : array of TOpStackItem;
OpStackTop: integer;
PrefixCnt : Integer;
@ -2412,7 +2413,7 @@ begin
ParseExcSyntaxError;
if (CurToken<>tkBraceClose) then
begin
x.Release;
x.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
CheckToken(tkBraceClose);
end;
NextToken;
@ -2498,11 +2499,8 @@ begin
// only 1 expression should be left on the OpStack
if ExpStack.Count<>1 then
ParseExcSyntaxError;
if ExpStack.Count=1 then
begin
Result:=TPasExpr(ExpStack[0]);
Result.Parent:=AParent;
end;
Result:=TPasExpr(ExpStack[0]);
Result.Parent:=AParent;
finally
{if Not Assigned(Result) then
@ -2512,7 +2510,7 @@ begin
if not Assigned(Result) then begin
// expression error!
for i:=0 to ExpStack.Count-1 do
TPasExpr(ExpStack[i]).Release;
TPasExpr(ExpStack[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
SetLength(OpStack,0);
ExpStack.Free;
@ -2629,7 +2627,7 @@ begin
Result:=DoParseExpression(AParent,x);
if CurToken<>tkBraceClose then
begin
ReleaseAndNil(TPasElement(Result));
ReleaseAndNil(TPasElement(Result){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
ParseExc(nParserExpectedCommaRBracket,SParserExpectedCommaRBracket);
end;
NextToken;
@ -2640,7 +2638,7 @@ begin
end;
if CurToken<>tkBraceClose then
begin
ReleaseAndNil(TPasElement(Result));
ReleaseAndNil(TPasElement(Result){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
ParseExc(nParserExpectedCommaRBracket,SParserExpectedCommaRBracket);
end;
NextToken;
@ -2777,7 +2775,7 @@ begin
begin
Module.PackageName := Engine.Package.Name;
Engine.Package.Modules.Add(Module);
Module.AddRef;
Module.AddRef{$IFDEF CheckPasTreeRefCount}('TPasPackage.Modules'){$ENDIF};
end;
CheckHint(Module,True);
ExpectToken(tkInterface);
@ -3344,7 +3342,7 @@ begin
Declarations.Declarations.Delete(j);
break;
end;
ClassEl.Release;
ClassEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
break;
end;
end;
@ -3365,7 +3363,7 @@ begin
finally
if not ok then
for i := 0 to List.Count - 1 do
TPasExportSymbol(List[i]).Release;
TPasExportSymbol(List[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
for i := 0 to List.Count - 1 do
begin
@ -3448,7 +3446,7 @@ begin
ParseExc(nParserGenericArray1Element,sParserGenericArray1Element);
ArrEl:=TPasArrayType(ParseArrayType(Declarations,NamePos,TypeName,pmNone));
CheckHint(ArrEl,True);
ArrEl.ElType.Release;
ArrEl.ElType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
ArrEl.ElType:=TPasGenericTemplateType(List[0]);
Declarations.Declarations.Add(ArrEl);
Declarations.Types.Add(ArrEl);
@ -3552,7 +3550,7 @@ begin
UnitRef := Engine.FindModule(AUnitName,NameExpr,InFileExpr);
if Assigned(UnitRef) then
UnitRef.AddRef
UnitRef.AddRef{$IFDEF CheckPasTreeRefCount}('TPasUsesUnit.Module'){$ENDIF}
else
UnitRef := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef,
AUnitName, ASection, NamePos));
@ -3573,13 +3571,13 @@ begin
if Result=nil then
begin
if UsesUnit<>nil then
UsesUnit.Release;
UsesUnit.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if NameExpr<>nil then
NameExpr.Release;
NameExpr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if InFileExpr<>nil then
InFileExpr.Release;
InFileExpr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if UnitRef<>nil then
UnitRef.Release;
UnitRef.Release{$IFDEF CheckPasTreeRefCount}('FindModule'){$ENDIF};
end;
end;
end;
@ -3660,8 +3658,8 @@ begin
finally
if FreeExpr then
begin
ReleaseAndNil(TPasElement(NameExpr));
ReleaseAndNil(TPasElement(InFileExpr));
ReleaseAndNil(TPasElement(NameExpr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
ReleaseAndNil(TPasElement(InFileExpr){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
end;
end;
end;
@ -3759,7 +3757,7 @@ begin
ok:=true;
finally
if not ok then
ReleaseAndNil(TPasElement(Result));
ReleaseAndNil(TPasElement(Result){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
end;
end;
@ -3780,7 +3778,7 @@ begin
ok:=true;
finally
if not ok then
ReleaseAndNil(TPasElement(Result));
ReleaseAndNil(TPasElement(Result){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
end;
end;
@ -3903,8 +3901,8 @@ begin
until false;
finally
Expr.Free;
if Ref<>nil then Ref.Release;
if NestedSpec<>nil then NestedSpec.Release;
if Ref<>nil then Ref.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if NestedSpec<>nil then NestedSpec.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -3955,7 +3953,7 @@ begin
PE:=DoParseExpression(Result,Nil,False);
if not ((PE is TBinaryExpr) and (TBinaryExpr(PE).Kind=pekRange)) then
begin
PE.Release;
PE.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
ParseExc(nRangeExpressionExpected,SRangeExpressionExpected);
end;
Result.RangeExpr:=PE as TBinaryExpr;
@ -3963,7 +3961,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
Engine.FinishScope(stTypeDef,Result);
end;
@ -4020,7 +4018,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -4202,7 +4200,7 @@ begin
VarEl.VarType := VarType;
//VarType.Parent := VarEl; // this is wrong for references
if (i>OldListCount) then
VarType.AddRef;
VarType.AddRef{$IFDEF CheckPasTreeRefCount}('TPasVariable.VarType'){$ENDIF};
end;
H:=CheckHint(Nil,False);
@ -4278,15 +4276,15 @@ begin
end;
ok:=true;
finally
if aLibName<>nil then aLibName.Release;
if aExpName<>nil then aExpName.Release;
if AbsoluteExpr<>nil then AbsoluteExpr.Release;
if not ok then
begin
if Value<>nil then Value.Release;
for i:=OldListCount to VarList.Count-1 do
TPasElement(VarList[i]).Release;
VarList.Count:=OldListCount;
if aLibName<>nil then aLibName.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if aExpName<>nil then aExpName.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if AbsoluteExpr<>nil then AbsoluteExpr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
if Value<>nil then Value.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
for i:=OldListCount to VarList.Count-1 do
TPasElement(VarList[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
VarList.Count:=OldListCount;
end;
end;
end;
@ -4456,7 +4454,7 @@ begin
begin
if (Args.Count>OldArgCount+1) then
begin
ArgType.Release;
ArgType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
ArgType:=nil;
ParseExc(nParserOnlyOneArgumentCanHaveDefault,SParserOnlyOneArgumentCanHaveDefault);
end;
@ -4475,7 +4473,7 @@ begin
ok:=true;
finally
if (not ok) and (ArgType<>nil) then
ArgType.Release;
ArgType.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -4486,7 +4484,7 @@ begin
if Assigned(ArgType) then
begin
if (i > OldArgCount) then
ArgType.AddRef;
ArgType.AddRef{$IFDEF CheckPasTreeRefCount}('TPasArgument.ArgType'){$ENDIF};
end;
Arg.ValueExpr := Value;
Value:=Nil; // Only the first gets a value. OK, since Var A,B : Integer = 1 is not allowed.
@ -4964,7 +4962,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -5171,7 +5169,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -5526,7 +5524,7 @@ begin
ok:=true;
finally
if not ok then
El.Release;
El.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
CreateBlock(TPasImplForLoop(El));
//WriteLn(i,'FOR "',VarName,'" := ',StartValue,' to ',EndValue,' Token=',CurTokenText);
@ -5774,7 +5772,7 @@ begin
TPasImplExceptOn(El).VarEl:=TPasVariable(CreateElement(TPasVariable,
Name,El,SrcPos));
TPasImplExceptOn(El).VarEl.VarType:=TypeEl;
TypeEl.AddRef;
TypeEl.AddRef{$IFDEF CheckPasTreeRefCount}('TPasVariable.VarType'){$ENDIF};
end
else
begin
@ -5897,7 +5895,7 @@ function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement; ProcType:
ReadGenericArguments(L,Parent);
finally
For I:=0 to L.Count-1 do
TPasElement(L[i]).Release;
TPasElement(L[i]).Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
L.Free;
end;
end
@ -5970,7 +5968,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -6185,7 +6183,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;
@ -6635,7 +6633,7 @@ begin
ok:=true;
finally
if not ok then
Result.Release;
Result.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
end;
end;

View File

@ -407,6 +407,7 @@ function TTestEngine.CreateElement(AClass: TPTreeElement; const AName: String;
begin
//writeln('TTestEngine.CreateElement ',AName,' ',AClass.ClassName);
Result := AClass.Create(AName, AParent);
{$IFDEF CheckPasTreeRefCount}Result.RefIds.Add('CreateElement');{$ENDIF}
Result.Visibility := AVisibility;
Result.SourceFilename := ASourceFilename;
Result.SourceLinenumber := ASourceLinenumber;
@ -485,8 +486,7 @@ begin
{$IFDEF VerbosePasResolverMem}
writeln('TTestParser.CleanupParser FModule');
{$ENDIF}
if Assigned(FModule) then
ReleaseAndNil(TPasElement(FModule));
ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
{$IFDEF VerbosePasResolverMem}
writeln('TTestParser.CleanupParser FSource');
{$ENDIF}

View File

@ -65,6 +65,7 @@ type
public
constructor Create;
destructor Destroy; override;
procedure ReleaseUsedUnits;
function CreateElement(AClass: TPTreeElement; const AName: String;
AParent: TPasElement; AVisibility: TPasMemberVisibility;
const ASrcPos: TPasSourcePos): TPasElement;
@ -110,6 +111,7 @@ type
TCustomTestResolver = Class(TTestParser)
Private
FStartElementRefCount: int64;
FFirstStatement: TPasImplBlock;
FModules: TObjectList;// list of TTestEnginePasResolver
FResolverEngine: TTestEnginePasResolver;
@ -347,6 +349,7 @@ type
// units
Procedure TestUnitForwardOverloads;
Procedure TestUnitIntfInitialization;
Procedure TestUnitUseSystem;
Procedure TestUnitUseIntf;
Procedure TestUnitUseImplFail;
Procedure TestUnit_DuplicateUsesFail;
@ -843,10 +846,12 @@ procedure TTestEnginePasResolver.SetModule(AValue: TPasModule);
begin
if FModule=AValue then Exit;
if Module<>nil then
Module.Release;
Module.Release{$IFDEF CheckPasTreeRefCount}('TTestEnginePasResolver.Module'){$ENDIF};
FModule:=AValue;
{$IFDEF CheckPasTreeRefCount}
if Module<>nil then
Module.AddRef;
Module.ChangeRefId('CreateElement','TTestEnginePasResolver.Module');
{$ENDIF}
end;
constructor TTestEnginePasResolver.Create;
@ -858,10 +863,16 @@ end;
destructor TTestEnginePasResolver.Destroy;
begin
FStreamResolver:=nil;
Module:=nil;
FreeAndNil(FParser);
FreeAndNil(FScanner);
inherited Destroy;
Module:=nil;
end;
procedure TTestEnginePasResolver.ReleaseUsedUnits;
begin
if Module<>nil then
Module.ReleaseUsedUnits;
end;
function TTestEnginePasResolver.CreateElement(AClass: TPTreeElement;
@ -890,6 +901,9 @@ end;
procedure TCustomTestResolver.SetUp;
begin
{$IF defined(VerbosePasResolver) or defined(VerbosePasResolverMem)}
FStartElementRefCount:=TPasElement.GlobalRefCount;
{$ENDIF}
FModules:=TObjectList.Create(true);
inherited SetUp;
Parser.Options:=Parser.Options+[po_ResolveStandardTypes];
@ -897,6 +911,12 @@ begin
end;
procedure TCustomTestResolver.TearDown;
{$IFDEF CheckPasTreeRefCount}
var El: TPasElement;
{$ENDIF}
{$IF defined(VerbosePasResolver) or defined(VerbosePasResolverMem)}
var i: Integer;
{$ENDIF}
begin
FResolverMsgs.Clear;
FResolverGoodMsgs.Clear;
@ -915,6 +935,8 @@ begin
{$IFDEF VerbosePasResolverMem}
writeln('TTestResolver.TearDown FModules');
{$ENDIF}
for i:=0 to FModules.Count-1 do
TTestEnginePasResolver(FModules[i]).ReleaseUsedUnits;
FModules.OwnsObjects:=false;
FModules.Remove(ResolverEngine); // remove reference
FModules.OwnsObjects:=true;
@ -923,8 +945,27 @@ begin
{$IFDEF VerbosePasResolverMem}
writeln('TTestResolver.TearDown inherited');
{$ENDIF}
if Module<>nil then
Module.AddRef{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}; // for the Release in ancestor TTestParser
inherited TearDown;
FResolverEngine:=nil;
{$IF defined(VerbosePasResolver) or defined(VerbosePasResolverMem)}
if FStartElementRefCount<>TPasElement.GlobalRefCount then
begin
writeln('TCustomTestResolver.TearDown GlobalRefCount Was='+IntToStr(FStartElementRefCount)+' Now='+IntToStr(TPasElement.GlobalRefCount));
{$IFDEF CheckPasTreeRefCount}
El:=TPasElement.FirstRefEl;
while El<>nil do
begin
writeln(' ',GetObjName(El),' RefIds.Count=',El.RefIds.Count,':');
for i:=0 to El.RefIds.Count-1 do
writeln(' ',El.RefIds[i]);
El:=El.NextRefEl;
end;
{$ENDIF}
//Fail('TCustomTestResolver.TearDown Was='+IntToStr(FStartElementRefCount)+' Now='+IntToStr(TPasElement.GlobalRefCount));
end;
{$ENDIF}
{$IFDEF VerbosePasResolverMem}
writeln('TTestResolver.TearDown END');
{$ENDIF}
@ -1137,6 +1178,7 @@ var
StartP:=p;
inc(p);
while p^ in ['a'..'z','A'..'Z','_','0'..'9'] do inc(p);
Result:='';
SetLength(Result,p-StartP);
Move(StartP^,Result[1],length(Result));
end;
@ -2002,6 +2044,8 @@ function TCustomTestResolver.OnPasResolverFindUnit(SrcResolver: TPasResolver;
function InitUnit(CurEngine: TTestEnginePasResolver): TPasModule;
begin
if CurEngine.Module<>nil then
Fail('InitUnit '+GetObjName(CurEngine.Module));
CurEngine.StreamResolver:=Resolver;
//writeln('TTestResolver.OnPasResolverFindUnit SOURCE=',CurEngine.Source);
CurEngine.StreamResolver.AddStream(CurEngine.FileName,
@ -2517,7 +2561,7 @@ begin
StartProgram(false);
Add('const');
Add(' c1 = 3');
Add(' c2: longint=c1;'); // defined in system.pp
Add(' c2: longint=c1;');
Add('begin');
CheckResolverUnexpectedHints;
end;
@ -5218,6 +5262,15 @@ begin
AssertSame('other unit assign var exitcode',(OtherUnit as TPasUsesUnit).Module,DeclEl.GetModule);
end;
procedure TTestResolver.TestUnitUseSystem;
begin
StartProgram(true);
Add('type number = system.integer;');
Add('begin');
Add(' if ExitCode=2 then ;');
ParseProgram;
end;
procedure TTestResolver.TestUnitUseIntf;
begin
AddModuleWithIntfImplSrc('unit2.pp',
@ -10274,15 +10327,16 @@ begin
' TObject = class',
' end;',
' TCar = class',
' end;']),
' end;',
' TCarry = TCar;']),
LinesToStr([
'']));
StartProgram(true);
Add('uses unit2;');
Add('type');
Add(' {#C}{=A}TCars = class of TCar;');
Add(' {#A}TCar = class');
Add(' {#C}{=A}TCars = class of TCarry;');
Add(' {#A}TCarry = class');
Add(' class var {#B}B: longint;');
Add(' end;');
Add('begin');

View File

@ -510,6 +510,7 @@ var
var
i: Integer;
begin
Entries:=nil;
SetLength(Entries,High(RefNames)-low(RefNames)+1);
for i:=low(RefNames) to high(RefNames) do
begin

View File

@ -3,6 +3,7 @@ program testpassrc;
{$mode objfpc}{$H+}
uses
//MemCheck,
Classes, consoletestrunner, tcscanner, tctypeparser, tcstatements,
tcbaseparser, tcmoduleparser, tconstparser, tcvarparser, tcclasstype,
tcexprparser, tcprocfunc, tcpassrcutil, tcresolver, tcgenerics,