I know of the following undocumented intrinsic functions.
Delphi 2007: here and Hallvard's blog:
Default
function Default(T: Typeidentifier): value of T;
Returns the zero representation of type identifier T
.
The following intrinsics introduced in XE7 are explained in the XE7 beta blog and by Stefan Glienke
IsManagedType
function IsManagedType(T: TypeIdentifier): Boolean;
True if T
is a interface
, string
or dynamic array
, or a record containing such. A class containing a managed type will return false.
In XE6 and older you have to use System.Rtti.IsManaged(TypeInfo(T))
.
HasWeakRef
function HasWeakRef(T: TypeIdentifier): Boolean;
True if T
has been annotated as [weak]
. The compiler keeps a list of [weak]
references. You cannot use move
and other tricks with these types, because that will prevent the weak-list from getting updated.
In XE6 and older you have to use System.TypInfo.HasWeakRef(TypeInfo(T))
.
GetTypeKind
function GetTypeKind(T: TypeIdentifier): TTypeKind;
Does the same thing as PTypeInfo(System.TypeInfo(T))^.Kind;
, however because it is a compiler intrinsic the function is resolved at compiletime and conditional code that evaluates to false will be stripped by the compiler.
IsConstValue
function IsConstValue(const Value): Boolean;
True if Value is a constant, false if not.
This helps the compiler to eliminate dead code because the function is evaluated at compile time.
This is only useful in inline functions, where it allows for shorter generated code.
TypeInfo
function TypeInfo(T: typeindentifier): PTypeInfo;
This function is not undocumented as such, but what is undocumented is that it is an intrinsic function since XE7.
That means that the snippet if TypeInfo(T) = TypeInfo(byte) then ...
does not generate any code if T is not a byte and the test will be resolved at compiletime.
However the compile-time resolution only works inside generic routines and only when doing a if (TypeInfo(T) = TypeInfo(sometype)
test.
The test if TypeInfo(byte) = TypeInfo(smallint) then
does not get eliminated even though it always evaluates to false.
Nor does other use of TypeInfo(T)
.
ReturnAddress
The following are used with the raise exception at returnaddress
construct.
function ReturnAddress(Expression): pointer; //Delphi ?
function AddressOfReturnAddress(Expression): pointer; //Delphi ?
And as far as I know you can't call them directly from user code.
Example of IsConstValue
type
TFlavor = (Tasty, Nasty);
TIntegerHelper = record helper for integer
function GetSomething(Flavor: TFlavor): TPoint; inline;
private
function GetTastyPoint: TPoint;
function GetNastyPoint: TPoint;
end;
function TIntegerHelper.GetSomething(Flavor: TFlavor): TPoint;
begin
if IsConstValue(Flavor) then begin
if Flavor = Tasty then Result:= Self.GetTastyPoint
else Result:= Self.GetNastyPoint;
end else begin
Assert(1=0, 'This function can only be called with constant parameters');
end;
end;
procedure Test;
var
pt: TPoint;
begin
pt:= 100000.GetSomething(Tasty);
This call will get translated to GetTastyPoint and the
if/then
sequence will be eliminated by the linker.