For some unknown reason, the compiler (3.2.2, laz 3.4) seems to forget about the String type in the methods definition when the TTree from FCL gtree unit is used.
The exact conditions:
1) The gtree's TTree is used by any means (by making a TTree field or specializing a type)
2) The program has
more than 1 class with methods which take a String argument (the classes may be independent, or one inherited from other). The broken methods are all except the first one defined.
What does not fix the problem:
1) Setting mode either ObjFPC or Delphi
2) Setting the {$H+} switch before the uses section
3) Setting the {$H+} switch in the gtree and all of it's dependencies (gvector, gstack, gqueue, gdeque)
4) Doing Clean and Build
What does fix the problem:
1) Setting the {$H+} switch
after the definition of the first method that uses String argument (which stays undamaged)
What does not cause the problem:
1) Using TTreeNode from gtree
2) Using other FCL units (checked gvector and gpriorityqueue)
Example:
program project1;
{$mode ObjFPC}{$H+}
uses gtree;
type
TDumbTreeData = record
Value: Integer;
end;
TDumbTree = class
Tree: specialize TTree<TDumbTreeData>;
end;
TEntity1 = class
Name: String;
constructor Create(_Name: String);
end;
TEntity2 = class
Name: String;
constructor Create(_Name: String);
end;
constructor TEntity1.Create(_Name: String);
begin
Name := _Name;
end;
constructor TEntity2.Create(_Name: String);
begin
Name := _Name;
end;
begin
end.
project1.lpr(32,22) Error: function header doesn't match any method of this class "constructor Create(ShortString);"
project1.lpr(24,21) Error: Found declaration: constructor Create(AnsiString);
Here, it can be fixed by writing {$H+} at the line 31.
UPD: figured out that this problem is not reproduced on a Linux system, but does occur on a fresh Windows installation with fresh Lazarus
Also, having 1 class is enough - it's about the methods:
program project1;
{$mode ObjFPC}{$H+}
uses gtree;
type
TDumbTreeData = record
Value: Integer;
end;
TDumbTree = class
Tree: specialize TTree<TDumbTreeData>;
end;
TEntity1 = class
Name: String;
constructor Create(_Name: String);
procedure DoStuff(Arg: String);
end;
constructor TEntity1.Create(_Name: String);
begin
Name := _Name;
end;
procedure TEntity1.DoStuff(Arg: String);
begin
end;
begin
end.
All methods except the first one gets their String argument to be ShortString in the definition.