3.3. Type Mangling
daslang uses a compact text encoding called type mangling to represent
types as strings. Mangled names are used internally for function overload
resolution, ABI hashing, and debug information. They are also the format
accepted by the C integration API (daScriptC.h) when binding interop
functions.
The mangling is defined by TypeDecl::getMangledName and parsed by
MangledNameParser::parseTypeFromMangledName in
src/ast/ast_typedecl.cpp.
3.3.1. Primitive types
Each primitive type has a short mnemonic:
daslang |
Mangled |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
SIMD 2-component vector |
|
|
|
|
|
|
|
|
8-bit signed integer |
|
|
16-bit signed integer |
|
|
64-bit signed integer |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3.3.2. Qualifiers and modifiers
Qualifiers are prepended before the base type they modify. For
example, const int is Ci and const string& is C&s.
Qualifier |
Mangled |
Meaning |
|---|---|---|
const |
|
Constant |
ref ( |
|
Reference |
temporary |
|
Temporary value |
implicit |
|
Implicit type |
explicit |
|
Explicit type match |
3.3.3. Pointers
A raw pointer is ?, followed by an optional smart-pointer marker:
daslang |
Mangled |
|---|---|
|
|
|
|
|
|
The pointed-to type is encoded as a first-type prefix (see Composite prefixes below).
3.3.4. Composite prefixes
Some types carry sub-types. These use numbered prefix wrappers:
Prefix |
Meaning |
Example |
|---|---|---|
|
First sub-type (element type) |
|
|
Second sub-type (value type for tables) |
|
3.3.5. Container types
daslang |
Mangled |
Encoding pattern |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For example:
array<int>→1<i>Aarray<float>→1<f>Atable<string;int>→1<s>2<i>Titerator<int>→1<i>G
3.3.6. Fixed-size arrays (dim)
Fixed-size dimensions are encoded with square brackets before the base type:
int[3]→[3]ifloat[2][4]→[2][4]f
3.3.7. Callable types
daslang has three callable types, each with its own suffix:
daslang |
Mangled |
Characteristics |
|---|---|---|
function pointer |
|
No capture, cheapest call |
lambda |
|
Heap-allocated, captures variables |
block |
|
Stack-allocated, cannot outlive scope |
The argument list uses the 0<args...> prefix with arguments separated
by semicolons. The callable’s own return type is not encoded in the
mangled name — it is determined by the enclosing context.
Examples:
function<(a:int; b:float) : string>→0<i;f>@@lambda<(a:int; b:float) : string>→0<i;f>@block<(a:int; b:float) : string>→0<i;f>$block<(a:int) : void>→0<i>$function<() : void>→@@(no args → no0<>prefix)
3.3.8. Structures, handled types, and enumerations
Named types use angle-bracket wrappers with a type-class letter:
Type class |
Mangled |
Example |
|---|---|---|
Structure |
|
|
Handled type |
|
|
Enumeration |
|
|
Enumeration8 |
|
8-bit enum |
Enumeration16 |
|
16-bit enum |
Enumeration64 |
|
64-bit enum |
When the type belongs to a module, the module name is included:
H<tutorial_07::model> or E<math::MathOp>.
3.3.9. Type aliases
An alias wraps the underlying type:
Y<AliasName>type— e.g.Y<IntArray>1<i>Afortypedef IntArray = array<int>
3.3.10. Named arguments
Named arguments in callable types use the N<names...> prefix:
N<a;b>0<i;f>$— a block taking named argumentsa:intandb:float
3.3.11. Bitfields
daslang |
Mangled |
|---|---|
bitfield |
|
bitfield8 |
|
bitfield16 |
|
bitfield64 |
|
3.3.12. Special / internal types
These are used internally by the compiler and macro system:
Type |
Mangled |
Purpose |
|---|---|---|
auto (infer) |
|
Auto-inferred type |
option |
|
Type option (overload sets) |
typeDecl |
|
|
alias |
|
Unresolved alias reference |
anyArgument |
|
Wildcard argument |
fakeContext |
|
Implicit |
fakeLineInfo |
|
Implicit |
typeMacro |
|
Macro-expanded type |
aotAlias |
|
AOT alias marker |
3.3.13. Remove-qualifiers (generics)
In generic function signatures, qualifiers can be explicitly removed:
Trait |
Mangled |
Meaning |
|---|---|---|
remove ref |
|
Strip reference |
remove const |
|
Strip const |
remove temp |
|
Strip temporary |
remove dim |
|
Strip fixed dimensions |
3.3.14. Interop function signatures
The C API function das_module_bind_interop_function takes a mangled
signature string that describes the full function type. The format is:
"return_type arg1_type arg2_type ..."
Types are separated by spaces. The first type is the return type, followed by each argument type. Each type is a complete mangled name.
3.3.14.1. Examples
"v i" → void func(int)
"v s" → void func(string)
"i i i" → int func(int, int)
"f H<Point2D>" → float func(Point2D)
"s H<Point2D>" → string func(Point2D)
"s 0<i;f>@@ i f" → string func(function<(int,float):string>, int, float)
"s 0<i;f>@ i f" → string func(lambda<(int,float):string>, int, float)
"s 0<i;f>$ i f" → string func(block<(int,float):string>, int, float)
"v 0<i;f>$" → void func(block<(int,float)>)
"1<H<model>>? C1<f>A" → model? func(const array<float>)
3.3.15. Querying mangled names at runtime
From daslang code, mangled names can be obtained with typeinfo:
options gen2
def my_function(a : int; b : float) : string {
return "{a} {b}"
}
[export]
def main() {
// Function mangled name via @@
print("mangled: {typeinfo(mangled_name @@my_function)}\n")
}
This is useful for debugging type signatures and verifying that C-side mangled strings match the daslang-side expectations.
See also
tutorial_integration_c_binding_types — binding custom types with mangled names
tutorial_integration_c_callbacks — callable type mangling for function pointers, lambdas, and blocks
tutorial_integration_c_unaligned_advanced — unaligned ABI interop functions
Context — runtime context lookups by mangled name hash