3 * Part of the D programming language runtime library.
4 * Forms the symbols available to all D programs. Includes
5 * Object, which is the root of the class object hierarchy.
7 * This module is implicitly imported.
13 * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
14 * Written by Walter Bright
16 * This software is provided 'as-is', without any express or implied
17 * warranty. In no event will the authors be held liable for any damages
18 * arising from the use of this software.
20 * Permission is granted to anyone to use this software for any purpose,
21 * including commercial applications, and to alter it and redistribute it
22 * freely, in both source and binary form, subject to the following
25 * o The origin of this software must not be misrepresented; you must not
26 * claim that you wrote the original software. If you use this software
27 * in a product, an acknowledgment in the product documentation would be
28 * appreciated but is not required.
29 * o Altered source versions must be plainly marked as such, and must not
30 * be misrepresented as being the original software.
31 * o This notice may not be removed or altered from any source
35 /* NOTE: This file has been patched from the original DMD distribution to
36 work with the GDC compiler.
38 Modified by David Friedman, April 2005
44 import std
.outofmemory
;
46 /// Standard boolean type.
50 * An unsigned integral type large enough to span the memory space. Use for
51 * array indices and pointer offsets for maximal portability to
52 * architectures that have different memory address ranges. This is
53 * analogous to C's size_t.
55 alias typeof(int.sizeof
) size_t
;
58 * A signed integral type large enough to span the memory space. Use for
59 * pointer differences and for size_t differences for maximal portability to
60 * architectures that have different memory address ranges. This is
61 * analogous to C's ptrdiff_t.
63 alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t
;
67 alias invariant(char)[] string
;
68 alias invariant(wchar)[] wstring
;
69 alias invariant(dchar)[] dstring
;
72 { /// C's printf function.
73 int printf(const char *, ...);
76 int memcmp(in void *, in void *, size_t
);
77 void* memcpy(void *, in void *, size_t
);
78 void* calloc(size_t
, size_t
);
79 void* realloc(void*, size_t
);
82 Object
_d_newclass(ClassInfo ci
);
85 /* *************************
86 * Internal struct pointed to by the hidden .monitor member.
90 void delegate(Object
)[] delegates
;
92 /* More stuff goes here defined by internal/monitor.c */
96 * All D class objects inherit from Object.
102 string s
= toString();
103 printf("%.*s\n", cast(int) s
.length
, s
.ptr
);
107 * Convert Object to a human readable string.
111 return this.classinfo
.name
;
115 * Compute hash function for Object.
119 // BUG: this prevents a compacting GC from working, needs to be fixed
120 return cast(size_t
)cast(void *)this;
124 * Compare with another Object obj.
127 * $(TR $(TD this < obj) $(TD < 0))
128 * $(TR $(TD this == obj) $(TD 0))
129 * $(TR $(TD this > obj) $(TD > 0))
134 // BUG: this prevents a compacting GC from working, needs to be fixed
135 //return cast(int)cast(void *)this - cast(int)cast(void *)o;
137 throw new Error(cast(string
) ("need opCmp for class "
138 ~ this.classinfo
.name
));
142 * Returns !=0 if this object does have the same contents as obj.
144 int opEquals(Object o
)
146 return cast(int)(this is o
);
150 * Call delegate dg, passing this to it, when this object gets destroyed.
151 * Use extreme caution, as the list of delegates is stored in a place
152 * not known to the gc. Thus, if any objects pointed to by one of these
153 * delegates gets freed by the gc, calling the delegate will cause a
155 * This is only for use by library developers, as it will need to be
156 * redone if weak pointers are added or a moving gc is developed.
158 final void notifyRegister(void delegate(Object
) dg
)
160 //printf("notifyRegister(dg = %llx, o = %p)\n", dg, this);
163 Monitor
* m
= cast(Monitor
*)(cast(void**)this)[1];
164 foreach (inout x
; m
.delegates
)
172 // Increase size of delegates[]
173 auto len
= m
.delegates
.length
;
178 auto p
= calloc((void delegate(Object
)).sizeof
, len
);
181 m
.delegates
= (cast(void delegate(Object
)*)p
)[0 .. len
];
186 auto p
= realloc(m
.delegates
.ptr
, (void delegate(Object
)).sizeof
* len
);
189 m
.delegates
= (cast(void delegate(Object
)*)p
)[0 .. len
];
190 m
.delegates
[startlen
.. len
] = null;
192 m
.delegates
[startlen
] = dg
;
197 * Remove delegate dg from the notify list.
198 * This is only for use by library developers, as it will need to be
199 * redone if weak pointers are added or a moving gc is developed.
201 final void notifyUnRegister(void delegate(Object
) dg
)
205 Monitor
* m
= cast(Monitor
*)(cast(void**)this)[1];
206 foreach (inout x
; m
.delegates
)
215 * Create instance of class specified by classname.
216 * The class must either have no constructors or have
217 * a default constructor.
221 static Object
factory(string classname
)
223 auto ci
= ClassInfo
.find(classname
);
232 extern (C
) void _d_notify_release(Object o
)
234 //printf("_d_notify_release(o = %p)\n", o);
235 Monitor
* m
= cast(Monitor
*)(cast(void**)o
)[1];
236 if (m
.delegates
.length
)
238 auto dgs
= m
.delegates
;
248 { //printf("calling dg = %llx (%p)\n", dg, o);
259 * Information about an interface.
260 * When an object is accessed via an interface, an Interface* appears as the
261 * first entry in its vtbl.
265 ClassInfo classinfo
; /// .classinfo for this interface (not for containing class)
267 ptrdiff_t offset
; /// offset to Interface 'this' from Object 'this'
270 import std
.moduleinit
;
272 * Runtime type information about a class. Can be retrieved for any class type
273 * or instance by using the .classinfo property.
274 * A pointer to this appears as the first entry in the class's vtbl[].
276 class ClassInfo
: Object
278 byte[] init
; /** class static initializer
279 * (init.length gives size in bytes of class)
281 string name
; /// class name
282 void *[] vtbl
; /// virtual function pointer table
283 Interface
[] interfaces
; /// interfaces this class implements
284 ClassInfo base
; /// base class
286 void (*classInvariant
)(Object
);
288 // 1: // is IUnknown or is derived from IUnknown
289 // 2: // has no possible pointers into GC memory
290 // 4: // has offTi[] member
291 // 8: // has constructors
292 // 16: // has xgetMembers member
294 OffsetTypeInfo
[] offTi
;
295 void function(Object
) defaultConstructor
; // default Constructor
296 const(MemberInfo
[]) function(string
) xgetMembers
;
299 * Search all modules for ClassInfo corresponding to classname.
300 * Returns: null if not found
302 static ClassInfo
find(string classname
)
304 foreach (m
; ModuleInfo
.modules())
306 //writefln("module %s, %d", m.name, m.localClasses.length);
307 foreach (c
; m
.localClasses
)
309 //writefln("\tclass %s", c.name);
310 if (c
.name
== classname
)
317 /********************
318 * Create instance of Object represented by 'this'.
320 * the object created, or null if the Object does
321 * does not have a default constructor
325 if (flags
& 8 && !defaultConstructor
)
327 Object o
= _d_newclass(this);
328 if (flags
& 8 && defaultConstructor
)
330 defaultConstructor(o
);
335 /*************************
336 * Search for all members with the name 'name'.
337 * If name[] is null, return all members.
339 const(MemberInfo
[]) getMembers(string name
)
341 if (flags
& 16 && xgetMembers
)
343 return xgetMembers(name
);
349 /* ========================================================================== */
351 private import std
.string
;
354 * Array of pairs giving the offset and type information for each
355 * member in an aggregate.
357 struct OffsetTypeInfo
359 size_t offset
; /// Offset of member from start of object
360 TypeInfo ti
; /// TypeInfo for this member
365 * Runtime type information about a type.
366 * Can be retrieved for any type using a
367 * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
371 override hash_t
toHash()
374 foreach (char c
; this.toString())
379 override int opCmp(Object o
)
383 TypeInfo ti
= cast(TypeInfo
)o
;
386 return std
.string
.cmp(this.toString(), ti
.toString());
389 override int opEquals(Object o
)
391 /* TypeInfo instances are singletons, but duplicates can exist
392 * across DLL's. Therefore, comparing for a name match is
397 TypeInfo ti
= cast(TypeInfo
)o
;
398 return cast(int)(ti
&& this.toString() == ti
.toString());
401 /// Returns a hash of the instance of a type.
402 hash_t
getHash(in void *p
) { return cast(size_t
)p
; }
404 /// Compares two instances for equality.
405 int equals(in void *p1
, in void *p2
) { return cast(int)(p1
== p2
); }
407 /// Compares two instances for <, ==, or >.
408 int compare(in void *p1
, in void *p2
) { return 0; }
410 /// Returns size of the type.
411 size_t
tsize() { return 0; }
413 /// Swaps two instances of the type.
414 void swap(void *p1
, void *p2
)
417 for (size_t i
= 0; i
< n
; i
++)
420 t
= (cast(byte *)p1
)[i
];
421 (cast(byte *)p1
)[i
] = (cast(byte *)p2
)[i
];
422 (cast(byte *)p2
)[i
] = t
;
426 /// Get TypeInfo for 'next' type, as defined by what kind of type this is,
428 TypeInfo
next() { return null; }
430 /// Return default initializer, null if default initialize to 0
431 void[] init() { return null; }
433 /// Get flags for type: 1 means GC should scan for pointers
434 uint flags() { return 0; }
436 /// Get type information on the contents of the type; null if not available
437 OffsetTypeInfo
[] offTi() { return null; }
439 /// Run the destructor on the object and all its sub-objects
440 void destroy(void *p
) { }
442 /// Run the postblit on the object and all its sub-objects
443 void postblit(void *p
) { }
446 class TypeInfo_Typedef
: TypeInfo
448 override string
toString() { return name
; }
450 override int opEquals(Object o
)
451 { TypeInfo_Typedef c
;
455 ((c
= cast(TypeInfo_Typedef
)o
) !is null &&
456 this.name
== c
.name
&&
457 this.base
== c
.base
));
460 override hash_t
getHash(in void *p
) { return base
.getHash(p
); }
461 override int equals(in void *p1
, in void *p2
) { return base
.equals(p1
, p2
); }
462 override int compare(in void *p1
, in void *p2
) { return base
.compare(p1
, p2
); }
463 override size_t
tsize() { return base
.tsize(); }
464 override void swap(void *p1
, void *p2
) { return base
.swap(p1
, p2
); }
466 override TypeInfo
next() { return base
.next(); }
467 override uint flags() { return base
.flags(); }
468 override void[] init() { return m_init
.length ? m_init
: base
.init(); }
470 override void destroy(void *p
) { base
.destroy(p
); }
471 override void postblit(void *p
) { base
.postblit(p
); }
478 class TypeInfo_Enum
: TypeInfo_Typedef
482 class TypeInfo_Pointer
: TypeInfo
484 override string
toString() { return cast(string
) (m_next
.toString() ~ "*"); }
486 override int opEquals(Object o
)
487 { TypeInfo_Pointer c
;
490 ((c
= cast(TypeInfo_Pointer
)o
) !is null &&
491 this.m_next
== c
.m_next
);
494 override hash_t
getHash(in void *p
)
496 return cast(size_t
)*cast(void* *)p
;
499 override int equals(in void *p1
, in void *p2
)
501 return cast(int)(*cast(void* *)p1
== *cast(void* *)p2
);
504 override int compare(in void *p1
, in void *p2
)
506 if (*cast(void* *)p1
< *cast(void* *)p2
)
508 else if (*cast(void* *)p1
> *cast(void* *)p2
)
514 override size_t
tsize()
516 return (void*).sizeof
;
519 override void swap(void *p1
, void *p2
)
521 tmp
= *cast(void**)p1
;
522 *cast(void**)p1
= *cast(void**)p2
;
523 *cast(void**)p2
= tmp
;
526 override TypeInfo
next() { return m_next
; }
527 override uint flags() { return 1; }
532 class TypeInfo_Array
: TypeInfo
534 override string
toString() { return cast(string
) (value
.toString() ~ "[]"); }
536 override int opEquals(Object o
)
541 ((c
= cast(TypeInfo_Array
)o
) !is null &&
542 this.value
== c
.value
));
545 override hash_t
getHash(in void *p
)
546 { size_t sz
= value
.tsize();
548 void[] a
= *cast(void[]*)p
;
549 for (size_t i
= 0; i
< a
.length
; i
++)
550 hash
+= value
.getHash(a
.ptr
+ i
* sz
);
554 override int equals(in void *p1
, in void *p2
)
556 void[] a1
= *cast(void[]*)p1
;
557 void[] a2
= *cast(void[]*)p2
;
558 if (a1
.length
!= a2
.length
)
560 size_t sz
= value
.tsize();
561 for (size_t i
= 0; i
< a1
.length
; i
++)
563 if (!value
.equals(a1
.ptr
+ i
* sz
, a2
.ptr
+ i
* sz
))
569 override int compare(in void *p1
, in void *p2
)
571 void[] a1
= *cast(void[]*)p1
;
572 void[] a2
= *cast(void[]*)p2
;
573 size_t sz
= value
.tsize();
574 size_t len
= a1
.length
;
578 for (size_t u
= 0; u
< len
; u
++)
580 int result
= value
.compare(a1
.ptr
+ u
* sz
, a2
.ptr
+ u
* sz
);
584 return cast(int)a1
.length
- cast(int)a2
.length
;
587 override size_t
tsize()
589 return (void[]).sizeof
;
592 override void swap(void *p1
, void *p2
)
594 tmp
= *cast(void[]*)p1
;
595 *cast(void[]*)p1
= *cast(void[]*)p2
;
596 *cast(void[]*)p2
= tmp
;
601 override TypeInfo
next()
606 override uint flags() { return 1; }
609 class TypeInfo_StaticArray
: TypeInfo
611 override string
toString()
614 (value
.toString() ~ "[" ~ std
.string
.toString(len
) ~ "]");
617 override int opEquals(Object o
)
618 { TypeInfo_StaticArray c
;
622 ((c
= cast(TypeInfo_StaticArray
)o
) !is null &&
624 this.value
== c
.value
));
627 override hash_t
getHash(in void *p
)
628 { size_t sz
= value
.tsize();
630 for (size_t i
= 0; i
< len
; i
++)
631 hash
+= value
.getHash(p
+ i
* sz
);
635 override int equals(in void *p1
, in void *p2
)
637 size_t sz
= value
.tsize();
639 for (size_t u
= 0; u
< len
; u
++)
641 if (!value
.equals(p1
+ u
* sz
, p2
+ u
* sz
))
647 override int compare(in void *p1
, in void *p2
)
649 size_t sz
= value
.tsize();
651 for (size_t u
= 0; u
< len
; u
++)
653 int result
= value
.compare(p1
+ u
* sz
, p2
+ u
* sz
);
660 override size_t
tsize()
662 return len
* value
.tsize();
665 override void swap(void *p1
, void *p2
)
667 size_t sz
= value
.tsize();
671 if (sz
< buffer
.sizeof
)
674 tmp
= pbuffer
= (new void[sz
]).ptr
;
676 for (size_t u
= 0; u
< len
; u
+= sz
)
678 memcpy(tmp
, p1
+ o
, sz
);
679 memcpy(p1
+ o
, p2
+ o
, sz
);
680 memcpy(p2
+ o
, tmp
, sz
);
686 override void[] init() { return value
.init(); }
687 override TypeInfo
next() { return value
; }
688 override uint flags() { return value
.flags(); }
690 override void destroy(void *p
)
692 auto sz
= value
.tsize();
694 foreach (i
; 0 .. len
)
701 override void postblit(void *p
)
703 auto sz
= value
.tsize();
704 foreach (i
; 0 .. len
)
715 class TypeInfo_AssociativeArray
: TypeInfo
717 override string
toString()
719 return cast(string
) (value
.toString() ~ "[" ~ key
.toString() ~ "]");
722 override int opEquals(Object o
)
723 { TypeInfo_AssociativeArray c
;
726 ((c
= cast(TypeInfo_AssociativeArray
)o
) !is null &&
728 this.value
== c
.value
);
731 // BUG: need to add the rest of the functions
733 override size_t
tsize()
735 return (char[int]).sizeof
;
738 override TypeInfo
next() { return value
; }
739 override uint flags() { return 1; }
745 class TypeInfo_Function
: TypeInfo
747 override string
toString()
749 return cast(string
) (next
.toString() ~ "()");
752 override int opEquals(Object o
)
753 { TypeInfo_Function c
;
756 ((c
= cast(TypeInfo_Function
)o
) !is null &&
757 this.next
== c
.next
);
760 // BUG: need to add the rest of the functions
762 override size_t
tsize()
764 return 0; // no size for functions
767 TypeInfo next
; // function return type
770 class TypeInfo_Delegate
: TypeInfo
772 override string
toString()
774 return cast(string
) (next
.toString() ~ " delegate()");
777 override int opEquals(Object o
)
778 { TypeInfo_Delegate c
;
781 ((c
= cast(TypeInfo_Delegate
)o
) !is null &&
782 this.next
== c
.next
);
785 // BUG: need to add the rest of the functions
787 override size_t
tsize()
788 { alias int delegate() dg
;
792 override uint flags() { return 1; }
794 TypeInfo next
; // delegate return type
797 class TypeInfo_Class
: TypeInfo
799 override string
toString() { return info
.name
; }
801 override int opEquals(Object o
)
805 ((c
= cast(TypeInfo_Class
)o
) !is null &&
806 this.info
.name
== c
.classinfo
.name
);
809 override hash_t
getHash(in void *p
)
811 Object o
= *cast(Object
*)p
;
812 return o ? o
.toHash() : 0;
815 override int equals(in void *p1
, in void *p2
)
817 Object o1
= *cast(Object
*)p1
;
818 Object o2
= *cast(Object
*)p2
;
820 return (o1
is o2
) ||
(o1
&& o1
.opEquals(o2
));
823 override int compare(in void *p1
, in void *p2
)
825 Object o1
= *cast(Object
*)p1
;
826 Object o2
= *cast(Object
*)p2
;
829 // Regard null references as always being "less than"
844 override size_t
tsize()
846 return Object
.sizeof
;
849 override uint flags() { return 1; }
851 override OffsetTypeInfo
[] offTi()
853 return (info
.flags
& 4) ? info
.offTi
: null;
859 class TypeInfo_Interface
: TypeInfo
861 override string
toString() { return info
.name
; }
863 override int opEquals(Object o
)
864 { TypeInfo_Interface c
;
867 ((c
= cast(TypeInfo_Interface
)o
) !is null &&
868 this.info
.name
== c
.classinfo
.name
);
871 override hash_t
getHash(in void *p
)
873 Interface
* pi
= **cast(Interface
***)*cast(void**)p
;
874 Object o
= cast(Object
)(*cast(void**)p
- pi
.offset
);
879 override int equals(in void *p1
, in void *p2
)
881 Interface
* pi
= **cast(Interface
***)*cast(void**)p1
;
882 Object o1
= cast(Object
)(*cast(void**)p1
- pi
.offset
);
883 pi
= **cast(Interface
***)*cast(void**)p2
;
884 Object o2
= cast(Object
)(*cast(void**)p2
- pi
.offset
);
886 return o1
== o2 ||
(o1
&& o1
.opCmp(o2
) == 0);
889 override int compare(in void *p1
, in void *p2
)
891 Interface
* pi
= **cast(Interface
***)*cast(void**)p1
;
892 Object o1
= cast(Object
)(*cast(void**)p1
- pi
.offset
);
893 pi
= **cast(Interface
***)*cast(void**)p2
;
894 Object o2
= cast(Object
)(*cast(void**)p2
- pi
.offset
);
897 // Regard null references as always being "less than"
912 override size_t
tsize()
914 return Object
.sizeof
;
917 override uint flags() { return 1; }
922 class TypeInfo_Struct
: TypeInfo
924 override string
toString() { return name
; }
926 override int opEquals(Object o
)
930 ((s
= cast(TypeInfo_Struct
)o
) !is null &&
931 this.name
== s
.name
&&
932 this.init
.length
== s
.init
.length
);
935 override hash_t
getHash(in void *p
)
940 { //printf("getHash() using xtoHash\n");
945 //printf("getHash() using default hash\n");
946 // A sorry hash algorithm.
947 // Should use the one for strings.
948 // BUG: relies on the GC not moving objects
949 auto q
= cast(const(ubyte)*)p
;
950 for (size_t i
= 0; i
< init
.length
; i
++)
958 override int equals(in void *p2
, in void *p1
)
968 // GDC and DMD use different calling conventions
969 c
= (*xopEquals
)(p2
, p1
);
971 c
= (*xopEquals
)(p1
, p2
);
974 // BUG: relies on the GC not moving objects
975 c
= (memcmp(p1
, p2
, init
.length
) == 0);
979 override int compare(in void *p2
, in void *p1
)
983 // Regard null references as always being "less than"
992 // GDC and DMD use different calling conventions
993 c
= (*xopCmp
)(p2
, p1
);
995 c
= (*xopCmp
)(p1
, p2
);
998 // BUG: relies on the GC not moving objects
999 c
= memcmp(p1
, p2
, init
.length
);
1007 override size_t
tsize()
1012 override void[] init() { return m_init
; }
1014 override uint flags() { return m_flags
; }
1016 override void destroy(void *p
)
1022 override void postblit(void *p
)
1029 void[] m_init
; // initializer; init.ptr == null if 0 initialize
1031 hash_t
function(in void*) xtoHash
;
1032 int function(in void*, in void*) xopEquals
;
1033 int function(in void*, in void*) xopCmp
;
1034 string
function(const(void)*) xtoString
;
1038 const(MemberInfo
[]) function(string
) xgetMembers
;
1039 void function(void*) xdtor
;
1040 void function(void*) xpostblit
;
1043 class TypeInfo_Tuple
: TypeInfo
1045 TypeInfo
[] elements
;
1047 override string
toString()
1051 foreach (i
, element
; elements
)
1055 s
~= element
.toString();
1061 override int opEquals(Object o
)
1066 auto t
= cast(TypeInfo_Tuple
)o
;
1067 if (t
&& elements
.length
== t
.elements
.length
)
1069 for (size_t i
= 0; i
< elements
.length
; i
++)
1071 if (elements
[i
] != t
.elements
[i
])
1079 override hash_t
getHash(in void *p
)
1084 override int equals(in void *p1
, in void *p2
)
1089 override int compare(in void *p1
, in void *p2
)
1094 override size_t
tsize()
1099 override void swap(void *p1
, void *p2
)
1104 override void destroy(void *p
)
1109 override void postblit(void *p
)
1115 class TypeInfo_Const
: TypeInfo
1117 override string
toString() { return cast(string
)
1118 ("const(" ~ base
.toString() ~ ")"); }
1120 override int opEquals(Object o
) { return base
.opEquals(o
); }
1121 override hash_t
getHash(in void *p
) { return base
.getHash(p
); }
1122 override int equals(in void *p1
, in void *p2
) { return base
.equals(p1
, p2
); }
1123 override int compare(in void *p1
, in void *p2
) { return base
.compare(p1
, p2
); }
1124 override size_t
tsize() { return base
.tsize(); }
1125 override void swap(void *p1
, void *p2
) { return base
.swap(p1
, p2
); }
1127 override TypeInfo
next() { return base
.next(); }
1128 override uint flags() { return base
.flags(); }
1129 override void[] init() { return base
.init(); }
1134 class TypeInfo_Invariant
: TypeInfo_Const
1136 override string
toString() { return cast(string
)
1137 ("invariant(" ~ base
.toString() ~ ")"); }
1140 /* ========================================================================== */
1142 abstract class MemberInfo
1147 class MemberInfo_field
: MemberInfo
1149 this(string name
, TypeInfo ti
, size_t offset
)
1156 override string
name() { return m_name
; }
1157 TypeInfo
typeInfo() { return m_typeinfo
; }
1158 size_t
offset() { return m_offset
; }
1161 TypeInfo m_typeinfo
;
1165 class MemberInfo_function
: MemberInfo
1167 this(string name
, TypeInfo ti
, void* fp
, uint flags
)
1175 override string
name() { return m_name
; }
1176 TypeInfo
typeInfo() { return m_typeinfo
; }
1177 void* fp() { return m_fp
; }
1178 uint flags() { return m_flags
; }
1182 TypeInfo m_typeinfo
;
1188 /* ========================================================================== */
1192 * All recoverable exceptions should be derived from class Exception.
1194 class Exception
: Object
1200 * Constructor; msg is a descriptive message for the exception.
1207 this(string msg
, Exception next
)
1213 override void print()
1215 string s
= toString();
1216 printf("%.*s\n", cast(int) s
.length
, s
.ptr
);
1219 override string
toString() { return msg
; }
1223 * All irrecoverable exceptions should be derived from class Error.
1225 class Error
: Exception
1229 * Constructor; msg is a descriptive message for the exception.
1236 this(string msg
, Exception next
)
1242 //extern (C) int nullext = 0;
1244 /**If the top-level main throws this, the message will be printed to stderr
1245 * and the program terminates with the given exit code.
1247 class SystemExit
: Exception
{
1250 this(string msg
, int exitCode
= 1)
1252 this.exitCode
= exitCode
;