Difference between revisions of "FPC New Features Trunk"

From Free Pascal wiki
Jump to navigationJump to search
(4 intermediate revisions by one other user not shown)
Line 103: Line 103:
 
** Inlining is supported as long as the body of the generic has already been parsed.
 
** Inlining is supported as long as the body of the generic has already been parsed.
 
* '''Examples''':
 
* '''Examples''':
<syntaxhighlight>
+
<syntaxhighlight lang="pascal">
 
unit UTest;
 
unit UTest;
 
{$mode objfpc}
 
{$mode objfpc}
Line 120: Line 120:
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
<syntaxhighlight>
+
<syntaxhighlight lang="pascal">
 
program Test;
 
program Test;
  
Line 166: Line 166:
 
* '''Examples''': All tests with the name ''tmshlp*.pp'' in https://svn.freepascal.org/svn/fpc/trunk/tests/test
 
* '''Examples''': All tests with the name ''tmshlp*.pp'' in https://svn.freepascal.org/svn/fpc/trunk/tests/test
 
* '''svn''': 42026
 
* '''svn''': 42026
 +
 +
==== Support for custom attributes ====
 +
* '''Overview''': Custom attributes allow to decorate types and published properties of classes to be decorated with additional metadata. The metadata are by itself descendants of ''TCustomAttribute'' and can take additional parameters if the classes have a suitable constructor to take these parameters. This feature requires the new modeswitch ''PrefixedAttributes''. This modeswitch is active by default in modes ''Delphi'' and ''DelphiUnicode''. Attributes can be queried using the ''TypInfo'' or ''Rtti'' units.
 +
* '''Notes''': More information can be seen in the announcement mail here: https://lists.freepascal.org/pipermail/fpc-announce/2019-July/000612.html
 +
* '''svn''': 42356 - 42411
 +
* '''Example''':
 +
<syntaxhighlight lang="pascal">
 +
program tcustomattr;
 +
 +
{$mode objfpc}{$H+}
 +
{$modeswitch prefixedattributes}
 +
 +
type
 +
  TMyAttribute = class(TCustomAttribute)
 +
    constructor Create;
 +
    constructor Create(aArg: String);
 +
    constructor Create(aArg: TGUID);
 +
    constructor Create(aArg: LongInt);
 +
  end;
 +
 +
  {$M+}
 +
  [TMyAttribute]
 +
  TTestClass = class
 +
  private
 +
    fTest: LongInt;
 +
  published
 +
    [TMyAttribute('Test')]
 +
    property Test: LongInt read fTest;
 +
  end;
 +
  {$M-}
 +
 +
  [TMyAttribute(1234)]
 +
  [TMy('Hello World')]
 +
  TTestEnum = (
 +
    teOne,
 +
    teTwo
 +
  );
 +
 +
  [TMyAttribute(IInterface), TMy(42)]
 +
  TLongInt = type LongInt;
 +
 +
constructor TMyAttribute.Create;
 +
begin
 +
end;
 +
 +
constructor TMyAttribute.Create(aArg: String);
 +
begin
 +
end;
 +
 +
constructor TMyAttribute.Create(aArg: LongInt);
 +
begin
 +
end;
 +
 +
constructor TMyAttribute.Create(aArg: TGUID);
 +
begin
 +
end;
 +
 +
begin
 +
 +
end.
 +
</syntaxhighlight>
  
 
=== Units ===
 
=== Units ===
Line 174: Line 235:
 
** This unit is intended to be Delphi-compatible
 
** This unit is intended to be Delphi-compatible
 
** This unit is currently experimental and not all features provided by the Delphi equivalent are yet available. Either types/methods are missing and thus compilation will fail or calling unsupported methods will trigger an exception.
 
** This unit is currently experimental and not all features provided by the Delphi equivalent are yet available. Either types/methods are missing and thus compilation will fail or calling unsupported methods will trigger an exception.
** The ''Invoke()'' function as well as the callback functionality for ''TMethodImplementation'' is provided by a manager which is by default not set (an ''EInvocationError'' will be raised in that case). Currently an implementation using the [http://sourceware.org/libffi/ libffi] library is provided for selected platforms for which the unit ''ffi.manager'' needs to be used in the main project file.
+
** The ''Invoke()'' function as well as the callback functionality for ''TMethodImplementation'' is provided by a manager which is by default not set (an ''EInvocationError'' will be raised in that case). Currently an implementation using the [http://sourceware.org/libffi/ libffi] library is provided for selected platforms for which the unit ''ffi.manager'' needs to be used in the main project file, as well as a native implementation for x86_64 Windows which does not rely on the ''ffi.manager'' unit.
 
 
  
 
==== ProcessUnicode unit ====
 
==== ProcessUnicode unit ====

Revision as of 18:48, 13 July 2019

About this page

Below you can find a list of new features introduced since the previous release, along with some background information and examples. Note that since svn trunk is by definition still under development, some of the features here may still change before they end up in a release version.

A list of changes that may break existing code can be found here.

All systems

Language

Support for interfacing with C blocks functionality

  • Overview: Support has been added for interfacing with Apple's blocks C-extension.
  • Notes:
    • As C blocks are very similar to anonymous methods in Delphi, we use a similar syntax to declare block types (with an added cdecl to indicate the C nature). Note that the syntax to define the code executed in a block (inline, like with anonymous methods in Delphi, or in a separately defined function/method) and the functionality of a block (the ability to capture context and code to execute it at an arbitrary point in the future) are two separate things. At this time (r29594), only the code from a global function/procedure or from an Object Pascal instance/class method can be executed within the context of a block. In the future, support will be added for nested functions and later probably also for code that is defined inline, like in Delphi.
    • This functionality is currently only supported by FPC on Mac OS X 10.7 and later, and on iOS 4.0 and later. The reason it doesn't work on Mac OS X 10.6, is that we require functionality that was added to the blocks runtime in later versions.
    • The blocks functionality can be activated on supported platforms via {$modeswitch cblocks}
  • More information:
  • svn: r29517, r29594

Support for Default Namespaces

  • Overview: Namespaces can be supplied to the compiler to be prefixed to units that would otherwise not be found
  • Description:
    • Use the new -FN<x> parameter to add a default namespace <x> to the list of default namespaces. If a unit name can not be found as-is then it will be searched for using all provided default namespaces as prefix (separated by a ".") until it is found or the list of namespaces is exhausted.
    • The default namespaces can also be used as prefixes for identifiers outside the uses section.
  • More information: announcement mail at https://lists.freepascal.org/pipermail/fpc-pascal/2018-May/053769.html
  • svn: r38911 - r38922

Dynamic Arrays supported by Insert()

  • Overview: The Insert() intrinsic can be used to insert arrays and elements into an existing dynamic array.
  • Notes:
    • The element to be inserted can be either of the following:
      • dynamic array of the same type
      • static array of the same type
      • a single element of the array's element type
    • The insertion index is zero based
    • If the dynamic array to be modified is empty it will simply contain the new data afterwards
    • If the index is larger than the current highest index of the array then the new data is appended at the end
    • If the index is negative then the new data will be appended at the start of the array
    • This feature is Delphi compatible with the exception of inserting static arrays which is not supported by Delphi
  • More information: announcement mail at https://lists.freepascal.org/pipermail/fpc-pascal/2018-May/053892.html

Dynamic Arrays supported by Delete()

  • Overview: The Delete() intrinsic can be used to remove a sub range from an existing dynamic array.
  • Notes:
    • The start index is zero based
    • The resulting range of Index and Count will be capped at the dynamic array's boundaries (namely 0 and the highest element); this may mean that in an extreme case no element is removed as the range is outside of the array's
    • This feature is Delphi compatible
  • More information: announcement mail at http://lists.freepascal.org/pipermail/fpc-pascal/2018-May/053891.html

Dynamic Arrays supported by Concat()

  • Overview: The Concat() intrinsic can be used to concatenate two or more dynamic arrays together.
  • Notes:
    • The resulting array will look as if all array elements had been added manually to the new array in order
    • Empty arrays don't contribute to the new array
    • This feature is Delphi compatible
  • More information: announcement mail at http://lists.freepascal.org/pipermail/fpc-pascal/2018-May/053891.html

Dynamic Arrays have built in + operator support

  • Overview: The + operator can be used to concatenate two or more dynamic arrays together.
  • Notes:
    • Requires new modeswitch ArrayOperators (enabled by default in Delphi modes)
    • The resulting array will look as if all array elements had been added manually to the new array in order
    • Empty arrays don't contribute to the new array
    • This feature is Delphi compatible
  • More information: announcement mail at http://lists.freepascal.org/pipermail/fpc-pascal/2018-May/053891.html

Dynamic Array constants and variable initialization

  • Overview: Dynamic arrays constants are now possible just as well as initializing dynamic array variables during their declaration. In both cases the same syntax as for static arrays is used.
  • Notes:
    • Adheres to the $J switch regarding writable constants, both for the variable itself as well as its content
    • Static and dynamic array constants can be nested
    • Delphi compatibility:
      • In Delphi modes the syntax is […] instead of (…)
      • Static array constants can not be used inside dynamic array constants
      • Delphi does not adhere to the $J switch for the array's contents
  • More information: announcement mail at http://lists.freepascal.org/pipermail/fpc-pascal/2018-May/053891.html

Dynamic Arrays constructors

More settings supported by $Push/$Pop

  • Overview: The directives $Push and $Pop now also handle the directives $MinEnumSize, $PackSet and $PackRecords.

Support for threadvar sections inside class and record types

  • Overview: Class and record types can now contain a class threadvar section that allows for the addition of scoped threadvar variables.
  • Notes:
    • This feature is Delphi compatible
    • Not including the class specifier is considered an error
  • svn: 39285 - 39289

Support for generic routines

  • Overview: It is now possible to declare generic routines (functions, procedures, methods) either as part of structured types or globally. In non-Delphi modes they are declared with the generic keyword preceding the procedure or function keyword and specialized with the specialize keyword preceeding the identifier of the generic routine when issueing a call. In mode Delphi the syntax follows that of Delphi.
  • Notes:
    • This feature is Delphi-compatible, with the addition that Delphi does not support global generic functions or procedures, only methods. FPC allows them also in mode Delphi however.
    • It's currently not possible to declare a generic method inside a generic structured type. This will be changed in a future version.
    • It's currently not possible to take a pointer to the specialization of a generic routine.
    • In mode Delphi complex expressions involving multiple specializations are not yet possible.
    • Inlining is supported as long as the body of the generic has already been parsed.
  • Examples:
unit UTest;
{$mode objfpc}

interface

generic function Add<T>(aArg1, aArg2: T): T;

implementation

generic function Add<T>(aArg1, aArg2: T): T;
begin
  Result := aArg1 + aArg2;
end;

end.
program Test;

{$mode objfpc}{$H+}

uses
  UTest;

begin
  Writeln(specialize Add<String>('Hello', 'World'));
  Writeln(specialize Add<LongInt>(23, 19));
end.

Management operators for record types

  • Overview: It is now possible to declare operators inside a record so that the built-in initialization, finalization and copying of record types can be extended. The supported operators are Initialize, Finalize, Copy and AddRef. Initialize, Finalize and AddRef take the record as a var-parameter while the Copy operator takes the source record as first parameter and the destination record as second parameter whereby that one is a var-parameter. The Initialize and Finalize operators are called when such a record enters the scope or leaves it respectively. Copy is called when a record variable is assigned to another. AddRef is called when a new reference to an existing record is required which for example the case when by-value-parameters are passed.
  • Example: See http://svn.freepascal.org/svn/fpc/trunk/tests/test/tmoperator8.pp and the other tmoperator*.pp tests

Method RTTI for interfaces

  • Overview: Is the $M directive enabled when parsing an interface detailed RTTI for each method contained in the interface is generated. This information is detailed enough to not only enumerate the parameter declaration, but also to call interface functions with the help of the Rtti.Invoke() function.
  • Notes:
    • The idea of the feature is Delphi compatible, however the RTTI binary data is not.
    • It's recommended to either use the records provided by unit TypInfo or the types provided by unit Rtti for access to avoid any problems with parsing the data.
    • The generation of method RTTI data is currently restricted to COM-interfaces.
  • Example: See https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/tests/test/trtti15.pp

Support for "volatile" intrinsic

  • Overview: A volatile intrinsic has been added to indicate to the code generator that a particular load from or store to a memory location must not be removed.
  • Notes: Delphi uses an attribute rather than an intrinsic. Such support will be added once support for attributes is available in FPC. An intrinsic that applies only to a specific memory access also has the advantages outlined in https://lwn.net/Articles/233482/
  • Example: https://svn.freepascal.org/svn/fpc/trunk/tests/test/tmt1.pp
  • svn: 40465

Support for "noinline" modifier

  • Overview: A noinline modifier has been added that can be used to prevent a routine from ever being inlined (even by automatic inlining).
  • Notes: Mainly added for internal compiler usage related to LLVM support.
  • svn: 41198

Support for helper types extending interface types

  • Overview: A type helper can now also extend interface types. The implementations are not provided by the interface implementer, but by the helper itself.
  • Notes: This allows to add functionality to an interface that does not depend on the implementer, but merely on the interface.
  • svn: 37023

Support for multiple active helpers per type

  • Overview: With the modeswitch multihelpers multiple helpers for a single type can be active at once. If a member of the type is accessed it's first checked in all helpers that are in scope in reverse order before the extended type itself is checked.
  • Examples: All tests with the name tmshlp*.pp in https://svn.freepascal.org/svn/fpc/trunk/tests/test
  • svn: 42026

Support for custom attributes

  • Overview: Custom attributes allow to decorate types and published properties of classes to be decorated with additional metadata. The metadata are by itself descendants of TCustomAttribute and can take additional parameters if the classes have a suitable constructor to take these parameters. This feature requires the new modeswitch PrefixedAttributes. This modeswitch is active by default in modes Delphi and DelphiUnicode. Attributes can be queried using the TypInfo or Rtti units.
  • Notes: More information can be seen in the announcement mail here: https://lists.freepascal.org/pipermail/fpc-announce/2019-July/000612.html
  • svn: 42356 - 42411
  • Example:
program tcustomattr;

{$mode objfpc}{$H+}
{$modeswitch prefixedattributes}

type
  TMyAttribute = class(TCustomAttribute)
    constructor Create;
    constructor Create(aArg: String);
    constructor Create(aArg: TGUID);
    constructor Create(aArg: LongInt);
  end;

  {$M+}
  [TMyAttribute]
  TTestClass = class
  private
    fTest: LongInt;
  published
    [TMyAttribute('Test')]
    property Test: LongInt read fTest;
  end;
  {$M-}

  [TMyAttribute(1234)]
  [TMy('Hello World')]
  TTestEnum = (
    teOne,
    teTwo
  );

  [TMyAttribute(IInterface), TMy(42)]
  TLongInt = type LongInt;

constructor TMyAttribute.Create;
begin
end;

constructor TMyAttribute.Create(aArg: String);
begin
end;

constructor TMyAttribute.Create(aArg: LongInt);
begin
end;

constructor TMyAttribute.Create(aArg: TGUID);
begin
end;

begin

end.

Units

Rtti unit

  • Overview: A new unit named Rtti has been added which provides a high-level, object oriented access to the type information stored in the binary.
  • Notes:
    • This unit is intended to be Delphi-compatible
    • This unit is currently experimental and not all features provided by the Delphi equivalent are yet available. Either types/methods are missing and thus compilation will fail or calling unsupported methods will trigger an exception.
    • The Invoke() function as well as the callback functionality for TMethodImplementation is provided by a manager which is by default not set (an EInvocationError will be raised in that case). Currently an implementation using the libffi library is provided for selected platforms for which the unit ffi.manager needs to be used in the main project file, as well as a native implementation for x86_64 Windows which does not rely on the ffi.manager unit.

ProcessUnicode unit

  • Overview: A new unit named ProcessUnicode has been added which provides an unicodestring version of TProcess. This allows unicodesupport on Windows without setting the default type to UTF-8.
  • Notes:
    • Both the old and the new TProcess units were reworked. Parts of the Runcommand support are now accessible in the class and parametrized with events. This makes custom versions easier.


Registry unit

  • Overview: The TRegistry class was made to be fully Unicode capable.
  • Notes:
    • All public and protected methods (the public API) that used string parameters now default to use UnicodeString parameters.
    • For all these methods overloads exist using String parameters (these call their UnicodeString counterparts).
    • Methods using TStrings have counterparts using TUnicodeStringArray, and ReadStringList/WriteStringList let you specify if the TStrings should be treated as UTF8 encoded.
    • The public API of TXMLRegistry was changed to use UnicodeString everywhere, without having String overloads. TXMLRegistry interfaces with a TXMLDocument structure internally, which uses DOMString (which in turn is an alias to WideString).
    • TRegIniFile and TRegistryIniFile have been deprecated on non-Windows platforms.
    • The public API of TRegIniFile has not been changed.
  • More information: https://lists.freepascal.org/pipermail/fpc-devel/2019-February/040446.html
  • svn: r41784

IDE

GDB/MI support

  • Overview: GDB/MI support has been added to the text mode IDE.
  • Notes:
    • It is enabled default, but can be disabled by building FPC with make NOGDBMI=1
    • The old and deprecated libgdb.a support is still there for platforms that do not have a modern GDB port (or e.g. don't support true multitasking, like go32v2).
    • When debugging a console application in Windows in GDB/MI mode, the debugged program is always run in a separate console. This is due to a limitation of the Windows GDB port.
  • svn: r30573

(Mac) OS X/iOS

New iosxwstr unit

  • Overview: The new unit called iosxwstr can be used to install a widestring manager on (Mac) OS X and iOS.
  • Notes: The cwstring unit fulfils the same purpose, but is no longer able to provide full functionality on iOS 7 and newer due to Apple no longer shipping the locale and codepage information this unit depends on. The iosxwstr unit gets its locale information for upper/lowercase conversions from the System Preferences. Adding both cwstring and iosxwstr to the uses clause will cause the second in line to override the settings from the first one.
  • More information: Adding this unit to the uses clause is enough to use its functionality.
  • svn: r29828

i8086-msdos

Huge memory model

  • Overview: Support has been added for the i8086 huge memory model.
  • Notes: The huge memory model (compared to the large memory model) removes the 64kb limitation of static data for the whole program. However, there's still a 64kb limit for the static data of a single unit.
  • More information: Huge memory model
  • svn: r31518

Internal assembler (object writer)

  • Overview: There's an internal assembler/object writer implemented for the i8086-msdos platform. It replaces NASM and the WLIB tool.
  • Notes: NASM is still required for building an i8086-msdos snapshot, because of the msdos startup code in the rtl. However, WLIB (from Open Watcom) is no longer required, so you can now build a fully functional smartlinked i8086-msdos snapshot from a platform that doesn't have the Open Watcom tools (such as DJGPP or Mac OS X).
  • svn: r30809

Internal linker

  • Overview: There's an internal linker implemented for the i8086-msdos platform. It replaces WLINK from Open Watcom.
  • Notes: Together with the internal assembler, the internal linker removes the dependency on Open Watcom tools. NASM is still required for building an i8086-msdos snapshot, because of the msdos startup code in the rtl.
  • svn: r31425

FarAddr internal function

  • Overview: There's a new i8086-specific internal function, similar to Addr(), called FarAddr(), which always returns a far pointer to the address of its argument.
  • Notes: The built-in Addr() function and the @ operator return a pointer type (near or far), that depends on the memory model. When interfacing with DOS, BIOS and other 16-bit APIs, it is sometimes useful to be able to obtain a far pointer to a pascal variable or procedure/function, regardless of the selected memory model. Previously, you would have to use ifdefs, or do something like Ptr(Seg(x), Ofs(x)). Now, this can be replaced with the much nicer FarAddr(x).
  • svn: r37629

Near and far procedure variables

  • Overview: Support has been added for procedure variables with an explicitly specified near or far call model.
  • Notes: By default, procedure variables follow the default call model of the current memory model - near in the tiny, small and compact memory models; far in the medium, large and huge models. However, now you can specify an explicit near or far call model, regardless of the default for the current memory model. Note that near and far procedure variables are not compatible with each other. Syntax is really simple:
type
  TFarProc = procedure(a, b: Integer); far;
  TNearProc = procedure(a, b: Integer); near;

Near procedure variables are 2 bytes long, so they contain only an offset. They are invoked with a near call instruction. Far procedure variables are 4 bytes long (16-bit offset + 16-bit offset) and are invoked with a far call. Note that you cannot simply convert a near procedure to a far procedure, by just filling in the segment part, because the call model is also different between near and far procedures. A far call instruction pushes a 4-byte far (segment:offset) return address and the function must terminate with a far return instruction - retf. A near call instruction pushes only a 2-byte offset on the stack and the function must terminate with a near return instruction - retn.

  • svn: r38691

x86_64-win64

Support for Microsoft's vectorcall calling convention

  • Overview: Under x86_64 (not i386), support for the "vectorcall" calling convention is now possible on Windows targets by specifying the vectorcall modifier.
  • Notes: Utilises the XMM registers better than the default Microsoft ABI, allowing aligned arrays of Singles and Doubles to be passed in a single register akin to the System V ABI as used by Linux and other OS's. Also allows projects to interface with external libraries that use the convention. "vectorcall" is silently ignored if the target is not x86_64-win64.
  • svn: 38206

New compiler targets

Support for the AArch64 target

  • Overview: Support has been added for the AArch64 architecture. Both Darwin (iOS) and Linux supported.
  • Notes: Apple's A7 CPU (and potentially other AArch64 CPUs too) does not support raising a signal when a floating point exception occurs.
  • More information: https://lists.freepascal.org/pipermail/fpc-devel/2015-February/035524.html
  • svn: r29986 (Darwin/iOS), r30897 (Linux)

Support for the Linux/ppc64le target

  • Overview: Support has been added for the Linux/ppc64le target. This is a PowerPC64 little endian platform that uses a new ABI termed ELFv2.
  • Notes: It is not easy to build this target on a big endian Linux/ppc64 target, due to the fact that the build system does not yet contain support to deal with different ABIs/endianess.
  • More information: To cross-compile a ppc64le compiler, use CROSSOPT="-Cb- -Caelfv2". Those options don't have to be specified when compiling on a ppc64le system using a native ppcppc64, as they will be set by default for that compiler.
  • svn: r30228

Support for the i8086-win16 (16-bit Windows) target

  • Overview: Experimental support has been added for the 16-bit Windows target. It is a cross compiler only target (cross compilation is possible from e.g. Win32, Win64 or Linux).
  • Notes: Windows 3.0 or later is supported.
  • More information: Win16

Support for code generation through LLVM

  • Overview: The compiler now has a code generator that generates LLVM bitcode.
  • Notes: LLVM still requires target-specific support and modifications in the compiler. Initially, the LLVM code generator only works when targeting Darwin/x86-64, Linux/x86-64, Linux/ARMHF and Linux/AArch64.
  • More information: LLVM
  • svn: 42260

New Features from other versions