hand source: sync five codegen/semantic gaps for self-hosting fixpoint

- TSymbol gains ConstString field; AnalyseConstDecls stores CD.StrVal
- TIdentExpr gains ConstString and NoArgFuncDecl fields
- AnalyseIdent propagates ConstString to identifier exprs
- EmitExpr: string constants emit 'l copy $__sN' not 'w copy 0'
- IsNoArgFuncCall now set unconditionally for any skFunction with a
  return type; NoArgFuncDecl is looked up from FProcIndex so codegen
  can emit a proper call $FuncName() for user-defined zero-arg functions
- EmitExpr no-arg call path forwards NoArgFuncDecl as ResolvedDecl so
  EmitFuncCall finds the declaration instead of falling through to
  builtin dispatch and raising ECodeGenError
- TFieldAccessExpr IsMethodCall/PropRead/IsClassAccess paths use
  VarRef(RecordName, IsGlobal) instead of hardcoded %%_var_ prefix,
  fixing global-variable receivers such as Source.GetText
This commit is contained in:
Graeme Geldenhuys 2026-04-25 13:06:04 +01:00
parent 2ca052a271
commit c547ab2f16

View file

@ -1750,6 +1750,7 @@ type
TypeDesc: TTypeDesc;
Params: TObjectList;
ConstValue: Int64;
ConstString: string;
IsWeak: Boolean;
@ -2551,7 +2552,9 @@ type
IsVarParam: Boolean;
IsConstant: Boolean;
ConstValue: Int64;
ConstString: string;
IsNoArgFuncCall: Boolean;
NoArgFuncDecl: TObject;
IsGlobal: Boolean;
IsImplicitSelf: Boolean;
ImplicitFieldInfo: TObject;
@ -6698,6 +6701,7 @@ begin
TD := FTable.TypeInteger;
Sym := TSymbol.Create(CD.Name, skConstant, TD);
Sym.ConstValue := CD.IntVal;
Sym.ConstString := CD.StrVal;
if not FTable.Define(Sym) then
Sym.Free;
end;
@ -8468,6 +8472,7 @@ var
Sym: TSymbol;
FldInfo: TFieldInfo;
PropInfo: TPropertyInfo;
NoArgIdx: Integer;
begin
if AExpr is TNilLiteral then
Result := FTable.TypeNil
@ -8547,11 +8552,16 @@ begin
begin
TIdentExpr(AExpr).IsConstant := True;
TIdentExpr(AExpr).ConstValue := Sym.ConstValue;
TIdentExpr(AExpr).ConstString := Sym.ConstString;
end;
if (Sym.Kind = skFunction) and (Sym.TypeDesc <> nil) and
(FProcIndex.IndexOf(TIdentExpr(AExpr).Name) < 0) then
if (Sym.Kind = skFunction) and (Sym.TypeDesc <> nil) then
begin
TIdentExpr(AExpr).IsNoArgFuncCall := True;
NoArgIdx := FProcIndex.IndexOf(TIdentExpr(AExpr).Name);
if NoArgIdx >= 0 then
TIdentExpr(AExpr).NoArgFuncDecl := FProcIndex.GetObject(NoArgIdx);
end;
Result := Sym.TypeDesc;
end
else if AExpr is TFuncCallExpr then
@ -11748,10 +11758,9 @@ begin
end
else if FldAccess.IsMethodCall then
begin
MDecl := TMethodDecl(FldAccess.ResolvedMethod);
L := AllocTemp;
EmitLine(Format(' %s =l loadl %%_var_%s', L, FldAccess.RecordName));
EmitLine(Format(' %s =l loadl %s', L, VarRef(FldAccess.RecordName, FldAccess.IsGlobal)));
QType := QbeTypeOf(MDecl.ResolvedReturnType);
T := AllocTemp;
EmitLine(Format(' %s =%s call $%s_%s(l %s)', T, QType, MDecl.OwnerTypeName, FldAccess.FieldName, L));
@ -11776,9 +11785,8 @@ begin
end
else if FldAccess.PropRead <> nil then
begin
L := AllocTemp;
EmitLine(Format(' %s =l loadl %%_var_%s', L, FldAccess.RecordName));
EmitLine(Format(' %s =l loadl %s', L, VarRef(FldAccess.RecordName, FldAccess.IsGlobal)));
T := AllocTemp;
QType := QbeTypeOf(FldAccess.PropRead.TypeDesc);
EmitLine(Format(' %s =%s call $%s_%s(l %s)', T, QType, QBEMangle(FldAccess.PropOwnerType),
@ -11787,9 +11795,8 @@ begin
end
else if FldAccess.IsClassAccess then
begin
L := AllocTemp;
EmitLine(Format(' %s =l loadl %%_var_%s', L, FldAccess.RecordName));
EmitLine(Format(' %s =l loadl %s', L, VarRef(FldAccess.RecordName, FldAccess.IsGlobal)));
if FldAccess.FieldInfo.Offset > 0 then
begin
Ptr := AllocTemp;
@ -11866,13 +11873,11 @@ begin
end
else if TIdentExpr(AExpr).IsNoArgFuncCall then
begin
NoArgCall := TFuncCallExpr.Create;
try
NoArgCall.Name := TIdentExpr(AExpr).Name;
NoArgCall.ResolvedType := AExpr.ResolvedType;
NoArgCall.ResolvedDecl := TIdentExpr(AExpr).NoArgFuncDecl;
Result := EmitExpr(NoArgCall);
finally
NoArgCall.Free;
@ -11881,6 +11886,9 @@ begin
end
else if TIdentExpr(AExpr).IsConstant then
begin
if (AExpr.ResolvedType <> nil) and (AExpr.ResolvedType.Kind = tyString) then
EmitLine(Format(' %s =l copy %s', T, EmitStrLit(TIdentExpr(AExpr).ConstString)))
else
EmitLine(Format(' %s =w copy %d', T, TIdentExpr(AExpr).ConstValue));
end
else if TIdentExpr(AExpr).IsVarParam then