Enumeration of array types

Select the type of array when creating an array result value with TLzDbgWatchDataIntf.CreateArrayValue.

Each type also has some different properties:

- Dynamic Array

  1. Does not have a LowBound, LowBound is always zero
  2. Length
     is part of the data
  3. Does have a DataAddress

- Static Array

  1. Does have a LowBound. LowBound is part of the type.
  2. Length
     is part of the type
  3. Does not have a DataAddress

- Unknown Array type

  1. Does have a LowBound, LowBound is part of the data
  2. Length
     is part of the data
  3. Does not have a DataAddress

"part of the data" vs "part of the type": If arrays are nested, then as all nested values, each array that is an element of an outer array must have identical types.
Like in Pascal, for an array of array [1..3] of the inner arrays all have the same Length and LowBound. But for array of array of the length of the inner array can vary.

TLzDbgWatchDataIntf.CreateArrayValue
Unknown array type
Dynamic array
Static array
Result data for a Watch

This interface is provide by the IDE (Debugger frontend) via TWatchValueIntf.ResData. The backend must use it to describe the "watch result" to the frontend.

The IDE can then apply different formatting to the result. For example, if a watch yields an Int64 result of "24" the backend will call CreateNumValue(24, True, 8) instead of delivering a pre-formated text result. This way the IDE knows the value, the signedness and the byte-size of the result. This allows the IDE to format the value in Hex, Decimal, Binary without having to make further queries to the backend.

The interface is designed for use in the Lazarus IDE, and therefore Pascal specific. The methods represent the types as defined in Pascal.
If the interface does not provide a method for a specific value, then the backend can provide a preformated result using CreatePrePrinted(text)

Restrictions

- The backend must first call one of the Create... methods. Only after that, can it add further info such as SetTypeName
- Once the backend has created a value, it must not change the result. That is the backend can not create a new different value to overwrite the result. The exception here is CreateError. If the backend encounters an error while working on a value, it can change the entire result to be an error.
- For methods that return an interface for a nested value, the backend must check if nil was returned. The frontend may return nil, if it does not require the information
- In an array all elements must be of the same type. That is, each element must be created with the same Create... method. Any parameters affecting the type rather than the value, must be kept the same too. E.g. for a CreateNumValue call only the num-value can change, the signedness and byte-size must be identical for all elements

Method providing TLzDbgWatchDataIntf
Create result as pre-formatted text

Create a result for any data, that is pre-formatted by the backend. The IDE will display this as is. The IDE can not change formatting, or any other operation (such as extending nested values).

- AVal: String

  The text to be displayed

Create result for a string type

- AVal: String

  The UTF8 encoded result

More parameters may still be added

Supported methods to add info to a string value:

- TLzDbgWatchDataIntf.SetTypeName
- TLzDbgWatchDataIntf.SetDataAddress

Create result for a widestring

- AVal: WideString

  The text

Supported methods to add info to a widestring value:

- TLzDbgWatchDataIntf.SetTypeName

Create result for Char or WideChar

- ACharValue: QWord

  Ordinal value of the char

- AByteSize: Integer = 0

  A size of 1 represents a pascal "char". And a size of 2 a widechar. Other values will be printed as "#12345". There is currently no encoding for the type "char". (it is a singel byte char, not utf-8)

Supported methods to add info to a char value:

- TLzDbgWatchDataIntf.SetTypeName

Create result for an ordinal number

- ANumValue: QWord

  The numerical value typecast to QWord. If the value is signed, it should be fully sign extended.

- ASigned: Boolean

  Indicate if the value is signed

- AByteSize: Integer = 0

  Should be 0,1,2,4 or 8. Zero indicates unknow size.

Supported methods to add info to a numeric value:

- TLzDbgWatchDataIntf.SetTypeName

Create result for a pointer

- AnAddrValue: TDbgPtr

  The address stored in the pointer

Supported methods to add info to a pointer value:

- TLzDbgWatchDataIntf.SetTypeName
- TLzDbgWatchDataIntf.SetDerefData

Create result for a floating number

- ANumValue: QWord

  The numerical value typecast to QWord. If the value is signed, it should be fully sign extended.

- ASigned: Boolean

  Indicate if the value is signed

- AByteSize: Integer = 0

  Should be 0,1,2,4 or 8. Zero indicates unknow size.

Supported methods to add info to a numeric value:

- TLzDbgWatchDataIntf.SetTypeName

Create result for a boolean value

- AnOrdBoolValue: QWord

  Ordinal value of the char. This can be any numerical value (within the range of the byte-size) as the value may hold non conform data

- AByteSize: Integer = 0

  Size of the underlaying type. In case the IDE is asked to dispaly the numerical value.
  A value of 0 represents an unknown size. This can currently also be used for bitpacked values.

Supported methods to add info to a char value:

- TLzDbgWatchDataIntf.SetTypeName

Create result for an enumerated value.

- ANumValue: QWord

  The ordinal value of the enum. For example "1" (as result of "ord(alTop)")

- AName: String

  The identifier representing the value. For example "alTop"

- AByteSize: Integer = 0

  The byte size of the variable.

- AnIsEnumIdent: Boolean = False

  - False: The value was read from a variable (or constant) of an enum type. E.g.: Form1.FAlign

  - True: The value was the identifier representing that enum value. E.g., the watch actually contained the term: "alTop"

Supported methods to add info to a enum value:

- TLzDbgWatchDataIntf.SetTypeName

Create a result for a set of enum
Subject to change

- const ANames: TStringDynArray

  A list of all enum identifiers that are included in the set value

Create / Add variant fields

This is used to create fields for the variant part(s) of any record "record ... case ... end". Included but not limited to the type "variant" itself.

Create a result for a function
This is if the user entered the name of a function (without setting function-eval).

Subject to change
Create a result for a function reference (variable containing a function)
Subject to change
Create result for Arrays

- AnArrayType: TLzDbgArrayType

  See TLzDbgWatchDataIntf.TLzDbgArrayType

- ATotalCount: Integer = 0

  The declared length of the array. In case of dynamic array the length set with SetLength().
  The amount of actually evaluated elements may differ.

- ALowIdx: Integer = 0

  The lower bound of the array.

  Only for static arrays, or arrays of unknown type.

Supported methods to add info to an array value:

- TLzDbgWatchDataIntf.SetTypeName
- TLzDbgWatchDataIntf.SetDataAddress
- TLzDbgWatchDataIntf.SetNextArrayData

Create result for an object, record or other structure

- AStructType: TLzDbgStructType

  See TLzDbgWatchDataIntf.TLzDbgStructType

- ADataAddress: TDBGPtr = 0

  DataAddress, if applicable (SetDataAddress does not work)

Supported methods to add info to a structure value:

- TLzDbgWatchDataIntf.SetTypeName
- TLzDbgWatchDataIntf.SetAnchestor
- TLzDbgWatchDataIntf.AddField

Create extra storage for value converter result

When storing a result from a value converter, the result (which must be created using any of the other "Create..." methods) should be encapsulated by this.

This will allow storing the value converter's result and the result the backend would otherwise have created. Should the value handler create an error, the original data is available to be shown

The call to CreateValueHandlerResultreturns a new TLzDbgWatchDataIntf which should be used to create the result of the value converter.
To add the non converted result use SetDerefData, which will alse returns a TLzDbgWatchDataIntf.

Supported methods to add info to a converter's result wrapper:

- TLzDbgWatchDataIntf.SetDerefData

Create an error

- AVal: String

  The error text to be displayed

The interface may still change

CreateError can be called immediately, without need to create any other value first. Or it can be called on a result that already had a value created. If the existing result had nested values they will all be dropped.

Provides the interface for building the watch-result.