# HG changeset patch # User Abscissa # Date 1307504254 14400 # Node ID b0d41ff5e0dfd9c597ced9fdedeb273927ad230d # Parent 1a0c1126bc464d99b3d0b317188fe82c5f8c5425 Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218 diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AddAssignExp.d --- a/dmd/AddAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AddAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,8 +26,12 @@ import dmd.backend.OPER; import dmd.backend.elem; +import dmd.DDMDExtensions; + class AddAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AddExp.d --- a/dmd/AddExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AddExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class AddExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AddrExp.d --- a/dmd/AddrExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AddrExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -32,8 +32,12 @@ import dmd.backend.Util; import dmd.codegen.Util; +import dmd.DDMDExtensions; + class AddrExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AggregateDeclaration.d --- a/dmd/AggregateDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AggregateDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -51,6 +51,8 @@ import dmd.backend.SFL; import dmd.codegen.Util; +import dmd.DDMDExtensions; + /**************************************** * Determine if scope sc has package level access to s. */ @@ -141,6 +143,8 @@ class AggregateDeclaration : ScopeDsymbol { + mixin insertMemberExtension!(typeof(this)); + Type type; StorageClass storage_class; PROT protection = PROT.PROTpublic; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AliasDeclaration.d --- a/dmd/AliasDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AliasDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.Expression; import dmd.Global; +import dmd.DDMDExtensions; + class AliasDeclaration : Declaration { + mixin insertMemberExtension!(typeof(this)); + Dsymbol aliassym; Dsymbol overnext; // next in overload list int inSemantic; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AliasThis.d --- a/dmd/AliasThis.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AliasThis.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.HdrGenState; import dmd.AggregateDeclaration; +import dmd.DDMDExtensions; + class AliasThis : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + // alias Identifier this; Identifier ident; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AlignDeclaration.d --- a/dmd/AlignDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AlignDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,8 +8,12 @@ import dmd.Dsymbol; import dmd.Array; +import dmd.DDMDExtensions; + class AlignDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + uint salign; this(uint sa, Dsymbols decl) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AndAndExp.d --- a/dmd/AndAndExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AndAndExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class AndAndExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AndAssignExp.d --- a/dmd/AndAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AndAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.backend.elem; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class AndAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AndExp.d --- a/dmd/AndExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AndExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.expression.Util; import dmd.expression.And; +import dmd.DDMDExtensions; + class AndExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AnonDeclaration.d --- a/dmd/AnonDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AnonDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import dmd.VarDeclaration; import dmd.Global; +import dmd.DDMDExtensions; + class AnonDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + int isunion; int sem = 0; // 1 if successful semantic() diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AnonymousAggregateDeclaration.d --- a/dmd/AnonymousAggregateDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AnonymousAggregateDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -4,8 +4,12 @@ import dmd.AggregateDeclaration; import dmd.Loc; +import dmd.DDMDExtensions; + class AnonymousAggregateDeclaration : AggregateDeclaration { + mixin insertMemberExtension!(typeof(this)); + this() { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ArrayExp.d --- a/dmd/ArrayExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ArrayExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.expression.Util; +import dmd.DDMDExtensions; + class ArrayExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Expressions arguments; this(Loc loc, Expression e1, Expressions args) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ArrayInitializer.d --- a/dmd/ArrayInitializer.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ArrayInitializer.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,8 +27,12 @@ import dmd.backend.TYM; import dmd.backend.Symbol; +import dmd.DDMDExtensions; + class ArrayInitializer : Initializer { + mixin insertMemberExtension!(typeof(this)); + Expressions index; // indices Initializers value; // of Initializer *'s uint dim = 0; // length of array being initialized diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ArrayLengthExp.d --- a/dmd/ArrayLengthExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ArrayLengthExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -34,8 +34,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class ArrayLengthExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ArrayLiteralExp.d --- a/dmd/ArrayLiteralExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ArrayLiteralExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -34,8 +34,12 @@ import dmd.backend.mTY; import dmd.codegen.Util; +import dmd.DDMDExtensions; + class ArrayLiteralExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Expressions elements; this(Loc loc, Expressions elements) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ArrayScopeSymbol.d --- a/dmd/ArrayScopeSymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ArrayScopeSymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,8 +26,12 @@ import dmd.ArrayLiteralExp; import dmd.expression.Util; +import dmd.DDMDExtensions; + class ArrayScopeSymbol : ScopeDsymbol { + mixin insertMemberExtension!(typeof(this)); + Expression exp; // IndexExp or SliceExp TypeTuple type; // for tuple[length] TupleDeclaration td; // for tuples of objects diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AsmStatement.d --- a/dmd/AsmStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AsmStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -38,8 +38,12 @@ import std.stdio; +import dmd.DDMDExtensions; + class AsmStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Token* tokens; code* asmcode; uint asmalign; // alignment of this statement diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AssertExp.d --- a/dmd/AssertExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AssertExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -44,12 +44,16 @@ import core.stdc.string; import std.string : toStringz; +import dmd.DDMDExtensions; + //static __gshared Symbol* assertexp_sfilename = null; //static __gshared string assertexp_name = null; //static __gshared Module assertexp_mn = null; class AssertExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Expression msg; this(Loc loc, Expression e, Expression msg = null) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AssignExp.d --- a/dmd/AssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -51,8 +51,12 @@ import dmd.codegen.Util; import dmd.expression.Util; +import dmd.DDMDExtensions; + class AssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + int ismemset = 0; this(Loc loc, Expression e1, Expression e2) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AssocArrayLiteralExp.d --- a/dmd/AssocArrayLiteralExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AssocArrayLiteralExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -29,8 +29,12 @@ import dmd.backend.OPER; import dmd.backend.RTLSYM; +import dmd.DDMDExtensions; + class AssocArrayLiteralExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Expressions keys; Expressions values; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/AttribDeclaration.d --- a/dmd/AttribDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/AttribDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -12,8 +12,12 @@ import dmd.OutBuffer; import dmd.HdrGenState; +import dmd.DDMDExtensions; + class AttribDeclaration : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + Dsymbols decl; // array of Dsymbol's this(Dsymbols decl) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/BaseClass.d --- a/dmd/BaseClass.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/BaseClass.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class BaseClass : TObject { + mixin insertMemberExtension!(typeof(this)); + Type type; // (before semantic processing) PROT protection; // protection for the base interface diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/BinExp.d --- a/dmd/BinExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/BinExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -83,6 +83,8 @@ import core.stdc.stdlib : calloc; import std.stdio : writef; +import dmd.DDMDExtensions; + /************************************** * Combine types. * Output: @@ -389,6 +391,8 @@ class BinExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Expression e1; Expression e2; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/BoolExp.d --- a/dmd/BoolExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/BoolExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class BoolExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e, Type t) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/BreakStatement.d --- a/dmd/BreakStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/BreakStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.backend.Blockx; import dmd.backend.BC; +import dmd.DDMDExtensions; + class BreakStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; this(Loc loc, Identifier ident) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CallExp.d --- a/dmd/CallExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CallExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -78,8 +78,12 @@ import std.stdio; +import dmd.DDMDExtensions; + class CallExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Expressions arguments; this(Loc loc, Expression e, Expressions exps) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CaseRangeStatement.d --- a/dmd/CaseRangeStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CaseRangeStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.HdrGenState; import dmd.Scope; +import dmd.DDMDExtensions; + class CaseRangeStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression first; Expression last; Statement statement; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CaseStatement.d --- a/dmd/CaseStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CaseStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,8 +27,12 @@ import dmd.backend.Util; import dmd.backend.BC; +import dmd.DDMDExtensions; + class CaseStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; Statement statement; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CastExp.d --- a/dmd/CastExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CastExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -45,8 +45,12 @@ import dmd.backend.RTLSYM; import dmd.expression.Util; +import dmd.DDMDExtensions; + class CastExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + // Possible to cast to one type while painting to another type Type to; // type to cast to MOD mod; // MODxxxxx diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CatAssignExp.d --- a/dmd/CatAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CatAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -24,8 +24,12 @@ import dmd.expression.Cat; import dmd.expression.Util; +import dmd.DDMDExtensions; + class CatAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CatExp.d --- a/dmd/CatExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CatExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,8 +27,12 @@ import dmd.codegen.Util; import dmd.expression.Cat; +import dmd.DDMDExtensions; + class CatExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Catch.d --- a/dmd/Catch.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Catch.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class Catch : TObject { + mixin insertMemberExtension!(typeof(this)); + Loc loc; Type type; Identifier ident; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ClassDeclaration.d --- a/dmd/ClassDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ClassDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -1,1938 +1,1942 @@ -module dmd.ClassDeclaration; - -import dmd.common; -import dmd.AggregateDeclaration; -import dmd.InterfaceDeclaration; -import dmd.ThisDeclaration; -import dmd.CompoundStatement; -import dmd.DeleteDeclaration; -import dmd.NewDeclaration; -import dmd.CtorDeclaration; -import dmd.TypeIdentifier; -import dmd.STC; -import dmd.Parameter; -import dmd.TypeTuple; -import dmd.TY; -import dmd.LINK; -import dmd.DsymbolTable; -import dmd.FuncDeclaration; -import dmd.Array; -import dmd.TypeClass; -import dmd.Module; -import dmd.Id; -import dmd.Type; -import dmd.OverloadSet; -import dmd.ArrayTypes; -import dmd.BaseClass; -import dmd.ClassInfoDeclaration; -import dmd.TypeInfoClassDeclaration; -import dmd.Loc; -import dmd.Identifier; -import dmd.Dsymbol; -import dmd.Scope; -import dmd.TypeFunction; -import dmd.OutBuffer; -import dmd.HdrGenState; -import dmd.VarDeclaration; -import dmd.Initializer; -import dmd.ExpInitializer; -import dmd.TypeSArray; -import dmd.ScopeDsymbol; -import dmd.PROT; -import dmd.Util; -import dmd.Global; - -import dmd.expression.Util; - -import dmd.backend.Symbol; -import dmd.backend.dt_t; -import dmd.backend.TYPE; -import dmd.backend.FL; -import dmd.backend.SFL; -import dmd.backend.mTY; -import dmd.backend.SC; -import dmd.backend.mTYman; -import dmd.backend.Util; -import dmd.backend.TYM; -import dmd.backend.Classsym; -import dmd.backend.glue; -import dmd.backend.RTLSYM; -import dmd.backend.LIST; - -import dmd.codegen.Util; - -import std.string; - -version (DMDV2) { - enum CLASSINFO_SIZE = (0x3C+12+4); // value of ClassInfo.size -} else { - enum CLASSINFO_SIZE = (0x3C+12+4); // value of ClassInfo.size -} - -enum OFFSET_RUNTIME = 0x76543210; - -struct FuncDeclarationFinder -{ - bool visit(FuncDeclaration fd2) - { - //printf("param = %p, fd = %p %s\n", param, fd, fd.toChars()); - return fd is fd2; - } - - FuncDeclaration fd; -} - -class ClassDeclaration : AggregateDeclaration -{ - ClassDeclaration baseClass; // null only if this is Object -version(DMDV1) { - CtorDeclaration *ctor; - CtorDeclaration *defaultCtor; // default constructor -} - FuncDeclaration staticCtor; - FuncDeclaration staticDtor; - Array vtbl; // Array of FuncDeclaration's making up the vtbl[] - Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] - - BaseClasses baseclasses; // Array of BaseClass's; first is super, - // rest are Interface's - - int interfaces_dim; - BaseClass* interfaces; // interfaces[interfaces_dim] for this class - // (does not include baseClass) - - BaseClasses vtblInterfaces; // array of base interfaces that have - // their own vtbl[] - - TypeInfoClassDeclaration vclassinfo; // the ClassInfo object for this ClassDeclaration - bool com; // true if this is a COM class (meaning - // it derives from IUnknown) - bool isauto; // true if this is an auto class - bool isabstract; // true if abstract class -version(DMDV1) { - int isnested; // !=0 if is nested -} - int inuse; // to prevent recursive attempts - - this(Loc loc, Identifier id, BaseClasses baseclasses) - { - register(); - - super(loc, id); - - vtbl = new Array(); - vtblFinal = new Array(); - - enum msg = "only object.d can define this reserved class name"; - - if (baseclasses) { - this.baseclasses = baseclasses; - } else { - this.baseclasses = new BaseClasses(); - } - - //printf("ClassDeclaration(%s), dim = %d\n", id.toChars(), this.baseclasses.dim); - - // For forward references - type = new TypeClass(this); - - if (id) - { - // Look for special class names - - if (id is Id.__sizeof || id is Id.alignof_ || id is Id.mangleof_) - error("illegal class name"); - - // BUG: What if this is the wrong TypeInfo, i.e. it is nested? - if (id.toChars()[0] == 'T') - { - if (id is Id.TypeInfo) - { - if (global.typeinfo) { - global.typeinfo.error("%s", msg); - } - - global.typeinfo = this; - } - - if (id is Id.TypeInfo_Class) - { - if (global.typeinfoclass) - global.typeinfoclass.error("%s", msg); - global.typeinfoclass = this; - } - - if (id is Id.TypeInfo_Interface) - { - if (global.typeinfointerface) - global.typeinfointerface.error("%s", msg); - global.typeinfointerface = this; - } - - if (id is Id.TypeInfo_Struct) - { - if (global.typeinfostruct) - global.typeinfostruct.error("%s", msg); - global.typeinfostruct = this; - } - - if (id is Id.TypeInfo_Typedef) - { - if (global.typeinfotypedef) - global.typeinfotypedef.error("%s", msg); - global.typeinfotypedef = this; - } - - if (id is Id.TypeInfo_Pointer) - { - if (global.typeinfopointer) - global.typeinfopointer.error("%s", msg); - global.typeinfopointer = this; - } - - if (id is Id.TypeInfo_Array) - { - if (global.typeinfoarray) - global.typeinfoarray.error("%s", msg); - global.typeinfoarray = this; - } - - if (id is Id.TypeInfo_StaticArray) - { //if (global.typeinfostaticarray) - //global.typeinfostaticarray.error("%s", msg); - global.typeinfostaticarray = this; - } - - if (id is Id.TypeInfo_AssociativeArray) - { - if (global.typeinfoassociativearray) - global.typeinfoassociativearray.error("%s", msg); - global.typeinfoassociativearray = this; - } - - if (id is Id.TypeInfo_Enum) - { - if (global.typeinfoenum) - global.typeinfoenum.error("%s", msg); - global.typeinfoenum = this; - } - - if (id is Id.TypeInfo_Function) - { - if (global.typeinfofunction) - global.typeinfofunction.error("%s", msg); - global.typeinfofunction = this; - } - - if (id is Id.TypeInfo_Delegate) - { - if (global.typeinfodelegate) - global.typeinfodelegate.error("%s", msg); - global.typeinfodelegate = this; - } - - if (id is Id.TypeInfo_Tuple) - { - if (global.typeinfotypelist) - global.typeinfotypelist.error("%s", msg); - global.typeinfotypelist = this; - } - - version (DMDV2) { - if (id is Id.TypeInfo_Const) - { - if (global.typeinfoconst) - global.typeinfoconst.error("%s", msg); - global.typeinfoconst = this; - } - - if (id is Id.TypeInfo_Invariant) - { - if (global.typeinfoinvariant) - global.typeinfoinvariant.error("%s", msg); - global.typeinfoinvariant = this; - } - - if (id is Id.TypeInfo_Shared) - { - if (global.typeinfoshared) - global.typeinfoshared.error("%s", msg); - global.typeinfoshared = this; - } - - if (id == Id.TypeInfo_Wild) - { - if (global.typeinfowild) - global.typeinfowild.error("%s", msg); - global.typeinfowild = this; - } - } - } - - if (id is Id.Object_) - { - if (global.object) - global.object.error("%s", msg); - global.object = this; - } - -// if (id is Id.ClassInfo) - if (id is Id.TypeInfo_Class) - { - if (global.classinfo) - global.classinfo.error("%s", msg); - global.classinfo = this; - } - - if (id is Id.ModuleInfo) - { - if (global.moduleinfo) - global.moduleinfo.error("%s", msg); - global.moduleinfo = this; - } - } - - com = 0; - isauto = false; - isabstract = false; - inuse = 0; - } - - override Dsymbol syntaxCopy(Dsymbol s) - { - ClassDeclaration cd; - - //printf("ClassDeclaration.syntaxCopy('%s')\n", toChars()); - if (s) - cd = cast(ClassDeclaration)s; - else - cd = new ClassDeclaration(loc, ident, null); - - cd.storage_class |= storage_class; - - cd.baseclasses.setDim(this.baseclasses.dim); - for (size_t i = 0; i < cd.baseclasses.dim; i++) - { - auto b = this.baseclasses[i]; - auto b2 = new BaseClass(b.type.syntaxCopy(), b.protection); - cd.baseclasses[i] = b2; - } - - ScopeDsymbol.syntaxCopy(cd); - return cd; - } - - override void semantic(Scope sc) - { - uint offset; - - //printf("ClassDeclaration.semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); - //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : ""); - //printf("sc.stc = %x\n", sc.stc); - - //{ static int n; if (++n == 20) *(char*)0=0; } - - if (!ident) // if anonymous class - { - string id = "__anonclass"; - ident = Identifier.generateId(id); - } - - if (!sc) - sc = scope_; - - if (!parent && sc.parent && !sc.parent.isModule()) - parent = sc.parent; - - type = type.semantic(loc, sc); - handle = type; - - if (!members) // if forward reference - { - //printf("\tclass '%s' is forward referenced\n", toChars()); - return; - } - if (symtab) - { if (sizeok == 1 || !scope_) - { //printf("\tsemantic for '%s' is already completed\n", toChars()); - return; // semantic() already completed - } - } - else - symtab = new DsymbolTable(); - - Scope scx = null; - if (scope_) - { - sc = scope_; - scx = scope_; // save so we don't make redundant copies - scope_ = null; - } - uint dprogress_save = global.dprogress; -version (IN_GCC) { - methods.setDim(0); -} - - if (sc.stc & STC.STCdeprecated) - { - isdeprecated = 1; - } - - if (sc.linkage == LINK.LINKcpp) - error("cannot create C++ classes"); - - // Expand any tuples in baseclasses[] - for (size_t i = 0; i < baseclasses.dim; ) - { - auto b = baseclasses[i]; - //printf("test1 %s %s\n", toChars(), b.type.toChars()); - b.type = b.type.semantic(loc, sc); - //printf("test2\n"); - Type tb = b.type.toBasetype(); - - if (tb.ty == TY.Ttuple) - { - TypeTuple tup = cast(TypeTuple)tb; - enum PROT protection = b.protection; - baseclasses.remove(i); - size_t dim = Parameter.dim(tup.arguments); - for (size_t j = 0; j < dim; j++) - { - auto arg = Parameter.getNth(tup.arguments, j); - b = new BaseClass(arg.type, protection); - baseclasses.insert(i + j, b); - } - } - else - i++; - } - - // See if there's a base class as first in baseclasses[] - if (baseclasses.dim) - { - TypeClass tc; - BaseClass b; - Type tb; - - b = baseclasses[0]; - //b.type = b.type.semantic(loc, sc); - tb = b.type.toBasetype(); - if (tb.ty != TY.Tclass) - { error("base type must be class or interface, not %s", b.type.toChars()); - baseclasses.remove(0); - } - else - { - tc = cast(TypeClass)(tb); - - if (tc.sym.isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = 1; - - tc.checkDeprecated(loc, sc); - } - } - - if (tc.sym.isInterfaceDeclaration()) { - ; - } else { - for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass) - { - if (cdb == this) - { - error("circular inheritance"); - baseclasses.remove(0); - goto L7; - } - } - if (!tc.sym.symtab || tc.sym.sizeok == 0) - { // Try to resolve forward reference - if (sc.mustsemantic && tc.sym.scope_) - tc.sym.semantic(null); - } - if (!tc.sym.symtab || tc.sym.scope_ || tc.sym.sizeok == 0) - { - //printf("%s: forward reference of base class %s\n", toChars(), tc.sym.toChars()); - //error("forward reference of base class %s", baseClass.toChars()); - // Forward reference of base class, try again later - //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars()); - scope_ = scx ? scx : sc.clone(); - scope_.setNoFree(); - if (tc.sym.scope_) - tc.sym.scope_.module_.addDeferredSemantic(tc.sym); - scope_.module_.addDeferredSemantic(this); - return; - } - else - { baseClass = tc.sym; - b.base = baseClass; - } - L7: ; - } - } - } - - // Treat the remaining entries in baseclasses as interfaces - // Check for errors, handle forward references - for (int i = (baseClass ? 1 : 0); i < baseclasses.dim; ) - { TypeClass tc; - BaseClass b; - Type tb; - - b = baseclasses[i]; - b.type = b.type.semantic(loc, sc); - tb = b.type.toBasetype(); - if (tb.ty == TY.Tclass) - tc = cast(TypeClass)tb; - else - tc = null; - if (!tc || !tc.sym.isInterfaceDeclaration()) - { - error("base type must be interface, not %s", b.type.toChars()); - baseclasses.remove(i); - continue; - } - else - { - if (tc.sym.isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = 1; - - tc.checkDeprecated(loc, sc); - } - } - - // Check for duplicate interfaces - for (size_t j = (baseClass ? 1 : 0); j < i; j++) - { - auto b2 = baseclasses[j]; - if (b2.base == tc.sym) - error("inherits from duplicate interface %s", b2.base.toChars()); - } - - if (!tc.sym.symtab) - { // Try to resolve forward reference - if (sc.mustsemantic && tc.sym.scope_) - tc.sym.semantic(null); - } - - b.base = tc.sym; - if (!b.base.symtab || b.base.scope_) - { - //error("forward reference of base class %s", baseClass.toChars()); - // Forward reference of base, try again later - //printf("\ttry later, forward reference of base %s\n", baseClass.toChars()); - scope_ = scx ? scx : sc.clone(); - scope_.setNoFree(); - if (tc.sym.scope_) - tc.sym.scope_.module_.addDeferredSemantic(tc.sym); - scope_.module_.addDeferredSemantic(this); - return; - } - } - i++; - } - - - // If no base class, and this is not an Object, use Object as base class - if (!baseClass && ident !is Id.Object_) - { - // BUG: what if Object is redefined in an inner scope? - Type tbase = new TypeIdentifier(Loc(0), Id.Object_); - BaseClass b; - TypeClass tc; - Type bt; - - if (!global.object) - { - error("missing or corrupt object.d"); - fatal(); - } - bt = tbase.semantic(loc, sc).toBasetype(); - b = new BaseClass(bt, PROT.PROTpublic); - baseclasses.shift(b); - assert(b.type.ty == TY.Tclass); - tc = cast(TypeClass)(b.type); - baseClass = tc.sym; - assert(!baseClass.isInterfaceDeclaration()); - b.base = baseClass; - } - - interfaces_dim = baseclasses.dim; - interfaces = baseclasses.ptr; - - if (baseClass) - { - if (baseClass.storage_class & STC.STCfinal) - error("cannot inherit from final class %s", baseClass.toChars()); - - interfaces_dim--; - interfaces++; - - // Copy vtbl[] from base class - vtbl.setDim(baseClass.vtbl.dim); - memcpy(vtbl.data, baseClass.vtbl.data, (void*).sizeof * vtbl.dim); - - // Inherit properties from base class - com = baseClass.isCOMclass(); - isauto = baseClass.isauto; - vthis = baseClass.vthis; - storage_class |= baseClass.storage_class & STC.STC_TYPECTOR; - } - else - { - // No base class, so this is the root of the class hierarchy - vtbl.setDim(0); - vtbl.push(cast(void*)this); // leave room for classinfo as first member - } - - protection = sc.protection; - storage_class |= sc.stc; - - if (sizeok == 0) - { - interfaceSemantic(sc); - - foreach (s; members) - s.addMember(sc, this, true); - - /* If this is a nested class, add the hidden 'this' - * member which is a pointer to the enclosing scope. - */ - if (vthis) // if inheriting from nested class - { // Use the base class's 'this' member - isnested = true; - if (storage_class & STC.STCstatic) - error("static class cannot inherit from nested class %s", baseClass.toChars()); - if (toParent2() != baseClass.toParent2()) - { - if (toParent2()) - { - error("is nested within %s, but super class %s is nested within %s", - toParent2().toChars(), - baseClass.toChars(), - baseClass.toParent2().toChars()); - } - else - { - error("is not nested, but super class %s is nested within %s", - baseClass.toChars(), - baseClass.toParent2().toChars()); - } - isnested = false; - } - } - else if (!(storage_class & STC.STCstatic)) - { - Dsymbol s = toParent2(); - if (s) - { - AggregateDeclaration ad = s.isClassDeclaration(); - FuncDeclaration fd = s.isFuncDeclaration(); - - if (ad || fd) - { isnested = true; - Type t; - if (ad) - t = ad.handle; - else if (fd) - { - AggregateDeclaration ad2 = fd.isMember2(); - if (ad2) - t = ad2.handle; - else - { - t = global.tvoidptr; - } - } - else - assert(0); - if (t.ty == TY.Tstruct) // ref to struct - t = global.tvoidptr; - assert(!vthis); - vthis = new ThisDeclaration(loc, t); - members.push(vthis); - } - } - } - } - - if (storage_class & (STC.STCauto | STC.STCscope)) - isauto = true; - if (storage_class & STC.STCabstract) - isabstract = true; - if (storage_class & STC.STCimmutable) - type = type.invariantOf(); - else if (storage_class & STC.STCconst) - type = type.constOf(); - else if (storage_class & STC.STCshared) - type = type.sharedOf(); - - sc = sc.push(this); - sc.stc &= ~(STC.STCfinal | STC.STCauto | STC.STCscope | STC.STCstatic | - STC.STCabstract | STC.STCdeprecated | STC.STC_TYPECTOR | STC.STCtls | STC.STCgshared); - sc.stc |= storage_class & STC.STC_TYPECTOR; - sc.parent = this; - sc.inunion = 0; - - if (isCOMclass()) - { -version (Windows) { - sc.linkage = LINK.LINKwindows; -} else { - /* This enables us to use COM objects under Linux and - * work with things like XPCOM - */ - sc.linkage = LINK.LINKc; -} - } - sc.protection = PROT.PROTpublic; - sc.explicitProtection = 0; - sc.structalign = 8; - structalign = sc.structalign; - if (baseClass) - { sc.offset = baseClass.structsize; - alignsize = baseClass.alignsize; - // if (isnested) - // sc.offset += PTRSIZE; // room for uplevel context pointer - } - else - { sc.offset = PTRSIZE * 2; // allow room for __vptr and __monitor - alignsize = PTRSIZE; - } - structsize = sc.offset; - Scope scsave = sc.clone(); - sizeok = 0; - - /* Set scope so if there are forward references, we still might be able to - * resolve individual members like enums. - */ - foreach (s; members) - { - /* There are problems doing this in the general case because - * Scope keeps track of things like 'offset' - */ - if (s.isEnumDeclaration() || (s.isAggregateDeclaration() && s.ident)) - { - //printf("setScope %s %s\n", s->kind(), s->toChars()); - s.setScope(sc); - } - } - - foreach (Dsymbol s; members) { - s.semantic(sc); - } - - if (sizeok == 2) - { - // semantic() failed because of forward references. - // Unwind what we did, and defer it for later - fields.setDim(0); - structsize = 0; - alignsize = 0; - structalign = 0; - - sc = sc.pop(); - - scope_ = scx ? scx : sc.clone(); - scope_.setNoFree(); - scope_.module_.addDeferredSemantic(this); - - global.dprogress = dprogress_save; - - //printf("\tsemantic('%s') failed due to forward references\n", toChars()); - return; - } - - //printf("\tsemantic('%s') successful\n", toChars()); - - structsize = sc.offset; - //members.print(); - - /* Look for special member functions. - * They must be in this class, not in a base class. - */ - ctor = cast(CtorDeclaration)search(Loc(0), Id.ctor, 0); - if (ctor && (ctor.toParent() != this || !ctor.isCtorDeclaration())) - ctor = null; - - // dtor = (DtorDeclaration *)search(Id.dtor, 0); - // if (dtor && dtor.toParent() != this) - // dtor = null; - - // inv = (InvariantDeclaration *)search(Id.classInvariant, 0); - // if (inv && inv.toParent() != this) - // inv = null; - - // Can be in base class - aggNew = cast(NewDeclaration)search(Loc(0), Id.classNew, 0); - aggDelete = cast(DeleteDeclaration)search(Loc(0), Id.classDelete, 0); - - // If this class has no constructor, but base class does, create - // a constructor: - // this() { } - if (!ctor && baseClass && baseClass.ctor) - { - //printf("Creating default this(){} for class %s\n", toChars()); - CtorDeclaration ctor = new CtorDeclaration(loc, Loc(0), null, 0); - ctor.fbody = new CompoundStatement(Loc(0), new Statements()); - members.push(ctor); - ctor.addMember(sc, this, true); - sc = scsave; // why? What about sc.nofree? /// - sc.offset = structsize; - ctor.semantic(sc); - this.ctor = ctor; - defaultCtor = ctor; - } - -static if (false) { - if (baseClass) - { - if (!aggDelete) - aggDelete = baseClass.aggDelete; - if (!aggNew) - aggNew = baseClass.aggNew; - } -} - - // Allocate instance of each new interface - foreach (b; vtblInterfaces) - { - uint thissize = PTRSIZE; - - alignmember(structalign, thissize, &sc.offset); - assert(b.offset == 0); - b.offset = sc.offset; - - // Take care of single inheritance offsets - while (b.baseInterfaces.length) - { - b = b.baseInterfaces[0]; - b.offset = sc.offset; - } - - sc.offset += thissize; - if (alignsize < thissize) - alignsize = thissize; - } - structsize = sc.offset; - sizeok = 1; - global.dprogress++; - - dtor = buildDtor(sc); - - sc.pop(); - -static if (false) { // Do not call until toObjfile() because of forward references - // Fill in base class vtbl[]s - for (int i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - - //b.fillVtbl(this, &b.vtbl, 1); - } -} - //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); - } - - override void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - if (!isAnonymous()) - { - buf.printf("%s ", kind()); - buf.writestring(toChars()); - if (baseclasses.dim) - buf.writestring(" : "); - } - foreach (size_t i, BaseClass b; baseclasses) - { - if (i) - buf.writeByte(','); - //buf.writestring(b.base.ident.toChars()); - b.type.toCBuffer(buf, null, hgs); - } - if (members) - { - buf.writenl(); - buf.writeByte('{'); - buf.writenl(); - foreach (s; members) - { - buf.writestring(" "); - s.toCBuffer(buf, hgs); - } - buf.writestring("}"); - } - else - buf.writeByte(';'); - buf.writenl(); - } - - /********************************************* - * Determine if 'this' is a base class of cd. - * This is used to detect circular inheritance only. - */ - int isBaseOf2(ClassDeclaration cd) - { - if (!cd) - return 0; - //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); - foreach (b; cd.baseclasses) - { - if (b.base is this || isBaseOf2(b.base)) - return 1; - } - return 0; - } - - /******************************************* - * Determine if 'this' is a base class of cd. - */ -/// #define OFFSET_RUNTIME 0x76543210 - bool isBaseOf(ClassDeclaration cd, int* poffset) - { - if (!cd) - return 0; - //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); - foreach (b; cd.baseclasses) - { - if (b.base == this || isBaseOf2(b.base)) - return 1; - } - - return 0; - } - - override Dsymbol search(Loc, Identifier ident, int flags) - { - Dsymbol s; - //printf("%s.ClassDeclaration.search('%s')\n", toChars(), ident.toChars()); - - if (scope_) - { - Scope sc = scope_; - sc.mustsemantic++; - semantic(sc); - sc.mustsemantic--; - } - - if (!members || !symtab || scope_) - { - error("is forward referenced when looking for '%s'", ident.toChars()); - //*(char*)0=0; - return null; - } - - s = ScopeDsymbol.search(loc, ident, flags); - if (!s) - { - // Search bases classes in depth-first, left to right order - - int i; - - foreach (b; baseclasses) - { - if (b.base) - { - if (!b.base.symtab) - error("base %s is forward referenced", b.base.ident.toChars()); - else - { - s = b.base.search(loc, ident, flags); - if (s is this) // happens if s is nested in this and derives from this - s = null; - else if (s) - break; - } - } - } - } - return s; - } - -version (DMDV2) { - bool isFuncHidden(FuncDeclaration fd) - { - //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); - Dsymbol s = search(Loc(0), fd.ident, 4|2); - if (!s) - { - //printf("not found\n"); - /* Because, due to a hack, if there are multiple definitions - * of fd.ident, null is returned. - */ - return false; - } - - FuncDeclarationFinder p; p.fd = fd; - - s = s.toAlias(); - OverloadSet os = s.isOverloadSet(); - if (os) - { - foreach (s2; os.a) - { - auto f2 = s2.isFuncDeclaration(); - if (f2 && overloadApply(f2, p)) - return false; - } - return true; - } - else - { - FuncDeclaration fdstart = s.isFuncDeclaration(); - //printf("%s fdstart = %p\n", s.kind(), fdstart); - return !overloadApply(fdstart, p); - } - } -} - FuncDeclaration findFunc(Identifier ident, TypeFunction tf) - { - //printf("ClassDeclaration.findFunc(%s, %s) %s\n", ident.toChars(), tf.toChars(), toChars()); - - ClassDeclaration cd = this; - Array vtbl = cd.vtbl; - while (true) - { - for (size_t i = 0; i < vtbl.dim; i++) - { - FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); - if (!fd) - continue; // the first entry might be a ClassInfo - - //printf("\t[%d] = %s\n", i, fd.toChars()); - if (ident == fd.ident && - //tf.equals(fd.type) - fd.type.covariant(tf) == 1 - ) - { //printf("\t\tfound\n"); - return fd; - } - //else printf("\t\t%d\n", fd.type.covariant(tf)); - } - if (!cd) - break; - - vtbl = cd.vtblFinal; - cd = cd.baseClass; - } - - return null; - } - - void interfaceSemantic(Scope sc) - { - InterfaceDeclaration id = isInterfaceDeclaration(); - - vtblInterfaces = new BaseClasses(); - vtblInterfaces.reserve(interfaces_dim); - - for (size_t i = 0; i < interfaces_dim; i++) - { - BaseClass b = interfaces[i]; - - // If this is an interface, and it derives from a COM interface, - // then this is a COM interface too. - if (b.base.isCOMinterface()) - com = 1; - - if (b.base.isCPPinterface() && id) - id.cpp = 1; - - vtblInterfaces.push(b); - b.copyBaseInterfaces(vtblInterfaces); - } - } - -version(DMDV1) -{ - int isNested() - { - assert(false); - } -} - bool isCOMclass() - { - return com; - } - - bool isCOMinterface() - { - return false; - } - -version (DMDV2) { - bool isCPPinterface() - { - return false; - } -} - bool isAbstract() - { - if (isabstract) - return true; - - for (int i = 1; i < vtbl.dim; i++) - { - FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); - - //printf("\tvtbl[%d] = %p\n", i, fd); - if (!fd || fd.isAbstract()) - { - isabstract = true; - return true; - } - } - - return false; - } - - int vtblOffset() - { - assert(false); - } - - override string kind() - { - return "class"; - } - - override string mangle() - { - Dsymbol parentsave = parent; - - //printf("ClassDeclaration.mangle() %s.%s\n", parent.toChars(), toChars()); - - /* These are reserved to the compiler, so keep simple - * names for them. - */ - if (ident is Id.Exception) - { - if (parent.ident is Id.object) - parent = null; - } - else if (ident is Id.TypeInfo || - // ident is Id.Exception || - ident is Id.TypeInfo_Struct || - ident is Id.TypeInfo_Class || - ident is Id.TypeInfo_Typedef || - ident is Id.TypeInfo_Tuple || - this is global.object || - this is global.classinfo || - this is global.moduleinfo || - ident.toChars().startsWith("TypeInfo_") - ) - { - parent = null; - } - - string id = Dsymbol.mangle(); - parent = parentsave; - return id; - } - - override void toDocBuffer(OutBuffer buf) - { - assert(false); - } - - override PROT getAccess(Dsymbol smember) // determine access to smember - { - PROT access_ret = PROT.PROTnone; - - version (LOG) { - printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n", - toChars(), smember.toChars()); - } - if (smember.toParent() is this) - { - access_ret = smember.prot(); - } - else - { - PROT access; - - if (smember.isDeclaration().isStatic()) - { - access_ret = smember.prot(); - } - - foreach (b; baseclasses) - { - access = b.base.getAccess(smember); - switch (access) - { - case PROT.PROTnone: - break; - - case PROT.PROTprivate: - access = PROT.PROTnone; // private members of base class not accessible - break; - - case PROT.PROTpackage: - case PROT.PROTprotected: - case PROT.PROTpublic: - case PROT.PROTexport: - // If access is to be tightened - if (b.protection < access) - access = b.protection; - - // Pick path with loosest access - if (access > access_ret) - access_ret = access; - break; - - default: - assert(0); - } - } - } - - version (LOG) { - printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n", - toChars(), smember.toChars(), access_ret); - } - - return access_ret; - } - - override void addLocalClass(ClassDeclarations aclasses) - { - aclasses.push(this); - } - - // Back end - override void toObjFile(int multiobj) // compile to .obj file - { - uint offset; - Symbol* sinit; - enum_SC scclass; - - //printf("ClassDeclaration.toObjFile('%s')\n", toChars()); - - if (!members) - return; - - if (multiobj) - { - obj_append(this); - return; - } - - if (global.params.symdebug) - toDebug(); - - assert(!scope_); // semantic() should have been run to completion - - scclass = SCglobal; - if (inTemplateInstance()) - scclass = SCcomdat; - - // Put out the members - foreach (member; members) - member.toObjFile(0); - -static if (false) { - // Build destructor by aggregating dtors[] - Symbol* sdtor; - switch (dtors.dim) - { - case 0: - // No destructors for this class - sdtor = null; - break; - - case 1: - // One destructor, just use it directly - sdtor = (cast(DtorDeclaration)dtors.data[0]).toSymbol(); - break; - - default: - { - /* Build a destructor that calls all the - * other destructors in dtors[]. - */ - - elem* edtor = null; - - // Declare 'this' pointer for our new destructor - Symbol* sthis = symbol_calloc("this"); - sthis.Stype = type_fake(TYnptr); - sthis.Stype.Tcount++; - sthis.Sclass = SCfastpar; - sthis.Spreg = AX; - sthis.Sfl = FLauto; - - // Call each of the destructors in dtors[] - // in reverse order - for (size_t i = 0; i < dtors.dim; i++) - { - DtorDeclaration d = cast(DtorDeclaration)dtors.data[i]; - Symbol* s = d.toSymbol(); - elem* e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); - edtor = el_combine(e, edtor); - } - - // Create type for the function - .type* t = type_alloc(TYjfunc); - t.Tflags |= TFprototype | TFfixed; - t.Tmangle = mTYman_d; - t.Tnext = tsvoid; - tsvoid.Tcount++; - - // Create the function, sdtor, and write it out - localgot = null; - sdtor = toSymbolX("__dtor", SCglobal, t, "FZv"); - block* b = block_calloc(); - b.BC = BCret; - b.Belem = edtor; - sdtor.Sfunc.Fstartblock = b; - cstate.CSpsymtab = &sdtor.Sfunc.Flocsym; - symbol_add(sthis); - writefunc(sdtor); - } - } -} - - // Generate C symbols - toSymbol(); - toVtblSymbol(); - sinit = toInitializer(); - - ////////////////////////////////////////////// - - // Generate static initializer - sinit.Sclass = scclass; - sinit.Sfl = FLdata; - version (ELFOBJ) { // Burton - sinit.Sseg = Segment.CDATA; - } - version (MACHOBJ) { - sinit.Sseg = Segment.DATA; - } - toDt(&sinit.Sdt); - outdata(sinit); - - ////////////////////////////////////////////// - - // Put out the TypeInfo - type.getTypeInfo(null); - //type.vtinfo.toObjFile(multiobj); - - ////////////////////////////////////////////// - - // Put out the ClassInfo - csym.Sclass = scclass; - csym.Sfl = FLdata; - - /* The layout is: - { - void **vptr; - monitor_t monitor; - byte[] initializer; // static initialization data - char[] name; // class name - void *[] vtbl; - Interface[] interfaces; - ClassInfo *base; // base class - void *destructor; - void *invariant; // class invariant - uint flags; - void *deallocator; - OffsetTypeInfo[] offTi; - void *defaultConstructor; - const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function - //TypeInfo typeinfo; - } - */ - dt_t* dt = null; - offset = CLASSINFO_SIZE; // must be ClassInfo.size - if (global.classinfo) - { - if (global.classinfo.structsize != CLASSINFO_SIZE) - error("D compiler and phobos' object.d are mismatched"); - - dtxoff(&dt, global.classinfo.toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo - } - else - { - dtdword(&dt, 0); // BUG: should be an assert() - } - - dtdword(&dt, 0); // monitor - - // initializer[] - assert(structsize >= 8); - dtdword(&dt, structsize); // size - dtxoff(&dt, sinit, 0, TYnptr); // initializer - - // name[] - string name = ident.toChars(); - size_t namelen = name.length; - if (!(namelen > 9 && name[0..9] == "TypeInfo_")) - { - name = toPrettyChars(); - namelen = name.length; - } - dtdword(&dt, namelen); - dtabytes(&dt, TYnptr, 0, namelen + 1, toStringz(name)); - - // vtbl[] - dtdword(&dt, vtbl.dim); - dtxoff(&dt, vtblsym, 0, TYnptr); - - // interfaces[] - dtdword(&dt, vtblInterfaces.dim); - if (vtblInterfaces.dim) - dtxoff(&dt, csym, offset, TYnptr); // (*) - else - dtdword(&dt, 0); - - // base - if (baseClass) - dtxoff(&dt, baseClass.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // destructor - if (dtor) - dtxoff(&dt, dtor.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // invariant - if (inv) - dtxoff(&dt, inv.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // flags - int flags = 4 | isCOMclass(); - version (DMDV2) { - flags |= 16; - } - flags |= 32; - - if (ctor) - flags |= 8; - for (ClassDeclaration cd = this; cd; cd = cd.baseClass) - { - if (cd.members) - { - foreach (sm; cd.members) - { - //printf("sm = %s %s\n", sm.kind(), sm.toChars()); - if (sm.hasPointers()) - goto L2; - } - } - } - flags |= 2; // no pointers - L2: - dtdword(&dt, flags); - - - // deallocator - if (aggDelete) - dtxoff(&dt, aggDelete.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // offTi[] - dtdword(&dt, 0); - dtdword(&dt, 0); // null for now, fix later - - // defaultConstructor - if (defaultCtor) - dtxoff(&dt, defaultCtor.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - version (DMDV2) { - FuncDeclaration sgetmembers = findGetMembers(); - if (sgetmembers) - dtxoff(&dt, sgetmembers.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); // module getMembers() function - } - - //dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr); // typeinfo - //dtdword(&dt, 0); - - ////////////////////////////////////////////// - - // Put out vtblInterfaces.data[]. Must immediately follow csym, because - // of the fixup (*) - - offset += vtblInterfaces.dim * (4 * PTRSIZE); - foreach (b; vtblInterfaces) - { - ClassDeclaration id = b.base; - - /* The layout is: - * struct Interface - * { - * ClassInfo *interface; - * void *[] vtbl; - * ptrdiff_t offset; - * } - */ - - // Fill in vtbl[] - b.fillVtbl(this, b.vtbl, 1); - - dtxoff(&dt, id.toSymbol(), 0, TYnptr); // ClassInfo - - // vtbl[] - dtdword(&dt, id.vtbl.dim); - dtxoff(&dt, csym, offset, TYnptr); - - dtdword(&dt, b.offset); // this offset - - offset += id.vtbl.dim * PTRSIZE; - } - - // Put out the vtblInterfaces.data[].vtbl[] - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars()); - foreach (size_t i, BaseClass b; vtblInterfaces) - { - ClassDeclaration id = b.base; - int j; - - //printf(" interface[%d] is '%s'\n", i, id.toChars()); - j = 0; - if (id.vtblOffset()) - { - // First entry is ClassInfo reference - //dtxoff(&dt, id.toSymbol(), 0, TYnptr); - - // First entry is struct Interface reference - dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); - j = 1; - } - - assert(id.vtbl.dim == b.vtbl.dim); - for (; j < id.vtbl.dim; j++) - { - assert(j < b.vtbl.dim); - static if (false) { - Object o = cast(Object)b.vtbl.data[j]; - if (o) - { - printf("o = %p\n", o); - assert(o.dyncast() == DYNCAST_DSYMBOL); - Dsymbol s = cast(Dsymbol)o; - printf("s.kind() = '%s'\n", s.kind()); - } - } - auto fd = cast(FuncDeclaration)b.vtbl.data[j]; - if (fd) - dtxoff(&dt, fd.toThunkSymbol(b.offset), 0, TYnptr); - else - dtdword(&dt, 0); - } - } - - static if (true) { - // Put out the overriding interface vtbl[]s. - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); - ClassDeclaration cd; - scope Array bvtbl = new Array(); - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - foreach (size_t k, BaseClass bs; cd.vtblInterfaces) - { - if (bs.fillVtbl(this, bvtbl, 0)) - { - //printf("\toverriding vtbl[] for %s\n", bs.base.toChars()); - ClassDeclaration id = bs.base; - int j; - - j = 0; - if (id.vtblOffset()) - { - // First entry is ClassInfo reference - //dtxoff(&dt, id.toSymbol(), 0, TYnptr); - - // First entry is struct Interface reference - dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); - j = 1; - } - - for (; j < id.vtbl.dim; j++) - { - assert(j < bvtbl.dim); - FuncDeclaration fd = cast(FuncDeclaration)bvtbl.data[j]; - if (fd) - dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); - else - dtdword(&dt, 0); - } - } - } - } - } - - version (INTERFACE_VIRTUAL) { - // Put out the overriding interface vtbl[]s. - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); - for (size_t i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - ClassDeclaration cd; - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - for (int k = 0; k < cd.vtblInterfaces.dim; k++) - { - BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; - - if (b.base == bs.base) - { - //printf("\toverriding vtbl[] for %s\n", b.base.toChars()); - ClassDeclaration id = b.base; - int j; - - j = 0; - if (id.vtblOffset()) - { - // First entry is ClassInfo reference - //dtxoff(&dt, id.toSymbol(), 0, TYnptr); - - // First entry is struct Interface reference - dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); - j = 1; - } - - for (; j < id.vtbl.dim; j++) - { - assert(j < b.vtbl.dim); - FuncDeclaration fd = cast(FuncDeclaration)b.vtbl.data[j]; - if (fd) - dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); - else - dtdword(&dt, 0); - } - } - } - } - } - } - - - csym.Sdt = dt; - version (ELFOBJ_OR_MACHOBJ) { // Burton - // ClassInfo cannot be const data, because we use the monitor on it - csym.Sseg = Segment.DATA; - } - outdata(csym); - if (isExport()) - obj_export(csym,0); - - ////////////////////////////////////////////// - - // Put out the vtbl[] - //printf("putting out %s.vtbl[]\n", toChars()); - dt = null; - size_t i; - if (0) - i = 0; - else - { - dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference - i = 1; - } - for (; i < vtbl.dim; i++) - { - FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); - - //printf("\tvtbl[%d] = %p\n", i, fd); - if (fd && (fd.fbody || !isAbstract())) - { - Symbol* s = fd.toSymbol(); - - version (DMDV2) { - if (isFuncHidden(fd)) - { - /* fd is hidden from the view of this class. - * If fd overlaps with any function in the vtbl[], then - * issue 'hidden' error. - */ - for (int j = 1; j < vtbl.dim; j++) - { - if (j == i) - continue; - FuncDeclaration fd2 = (cast(Dsymbol)vtbl.data[j]).isFuncDeclaration(); - if (!fd2.ident.equals(fd.ident)) - continue; - if (fd.leastAsSpecialized(fd2) || fd2.leastAsSpecialized(fd)) - { - if (global.params.warnings) - { - TypeFunction tf = cast(TypeFunction)fd.type; - if (tf.ty == Tfunction) - warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Parameter.argsTypesToChars(tf.parameters, tf.varargs), toChars()); - else - warning("%s is hidden by %s\n", fd.toPrettyChars(), toChars()); - } - s = rtlsym[RTLSYM_DHIDDENFUNC]; - break; - } - } - } - } - dtxoff(&dt, s, 0, TYnptr); - } - else - dtdword(&dt, 0); - } - - vtblsym.Sdt = dt; - vtblsym.Sclass = scclass; - vtblsym.Sfl = FLdata; - version (ELFOBJ) { - vtblsym.Sseg = Segment.CDATA; - } - version (MACHOBJ) { - vtblsym.Sseg = Segment.DATA; - } - outdata(vtblsym); - if (isExport()) - obj_export(vtblsym,0); - } - - void toDebug() - { - assert(false); - } - - /****************************************** - * Get offset of base class's vtbl[] initializer from start of csym. - * Returns ~0 if not this csym. - */ - uint baseVtblOffset(BaseClass bc) - { - uint csymoffset; - - //printf("ClassDeclaration.baseVtblOffset('%s', bc = %p)\n", toChars(), bc); - csymoffset = CLASSINFO_SIZE; - csymoffset += vtblInterfaces.dim * (4 * PTRSIZE); - - foreach (b; vtblInterfaces) - { - if (b == bc) - return csymoffset; - csymoffset += b.base.vtbl.dim * PTRSIZE; - } - - static if (true) { - // Put out the overriding interface vtbl[]s. - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); - ClassDeclaration cd; - Array bvtbl; - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - foreach(bs; cd.vtblInterfaces) - { - if (bs.fillVtbl(this, null, 0)) - { - if (bc == bs) - { - //printf("\tcsymoffset = x%x\n", csymoffset); - return csymoffset; - } - csymoffset += bs.base.vtbl.dim * PTRSIZE; - } - } - } - } - version (INTERFACE_VIRTUAL) { - for (size_t i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - ClassDeclaration cd; - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - //printf("\tbase class %s\n", cd.toChars()); - for (int k = 0; k < cd.vtblInterfaces.dim; k++) - { - BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; - - if (bc == bs) - { - //printf("\tcsymoffset = x%x\n", csymoffset); - return csymoffset; - } - if (b.base == bs.base) - csymoffset += bs.base.vtbl.dim * PTRSIZE; - } - } - } - } - - return ~0; - } - - /************************************* - * Create the "ClassInfo" symbol - */ - override Symbol* toSymbol() - { - if (!csym) - { - Symbol* s; - - s = toSymbolX("__Class", SC.SCextern, global.scc.Stype, "Z"); - s.Sfl = FL.FLextern; - s.Sflags |= SFL.SFLnodebug; - csym = s; - slist_add(s); - } - - return csym; - } - - /************************************* - * This is accessible via the ClassData, but since it is frequently - * needed directly (like for rtti comparisons), make it directly accessible. - */ - Symbol* toVtblSymbol() - { - if (!vtblsym) - { - if (!csym) - toSymbol(); - - TYPE* t = type_alloc(TYM.TYnptr | mTY.mTYconst); - t.Tnext = tsvoid; - t.Tnext.Tcount++; - t.Tmangle = mTYman.mTYman_d; - - Symbol* s = toSymbolX("__vtbl", SC.SCextern, t, "Z"); - s.Sflags |= SFL.SFLnodebug; - s.Sfl = FL.FLextern; - vtblsym = s; - slist_add(s); - } - return vtblsym; - } - - // Generate the data for the static initializer. - void toDt(dt_t **pdt) - { - //printf("ClassDeclaration.toDt(this = '%s')\n", toChars()); - - // Put in first two members, the vtbl[] and the monitor - dtxoff(pdt, toVtblSymbol(), 0, TYnptr); - dtdword(pdt, 0); // monitor - - // Put in the rest - toDt2(pdt, this); - - //printf("-ClassDeclaration.toDt(this = '%s')\n", toChars()); - } - - void toDt2(dt_t** pdt, ClassDeclaration cd) - { - uint offset; - - dt_t* dt; - uint csymoffset; - - version (LOG) { - printf("ClassDeclaration.toDt2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); - } - if (baseClass) - { - baseClass.toDt2(pdt, cd); - offset = baseClass.structsize; - } - else - { - offset = 8; - } - - // Note equivalence of this loop to struct's - for (size_t i = 0; i < fields.dim; i++) - { - VarDeclaration v = cast(VarDeclaration)fields[i]; - Initializer init; - - //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset); - dt = null; - init = v.init; - if (init) - { - //printf("\t\t%s has initializer %s\n", v.toChars(), init.toChars()); - ExpInitializer ei = init.isExpInitializer(); - Type tb = v.type.toBasetype(); - if (ei && tb.ty == Tsarray) - (cast(TypeSArray)tb).toDtElem(&dt, ei.exp); - else - dt = init.toDt(); - } - else if (v.offset >= offset) - { //printf("\t\tdefault initializer\n"); - v.type.toDt(&dt); - } - if (dt) - { - if (v.offset < offset) - error("duplicated union initialization for %s", v.toChars()); - else - { - if (offset < v.offset) - dtnzeros(pdt, v.offset - offset); - dtcat(pdt, dt); - offset = v.offset + cast(uint)v.type.size(); - } - } - } - - // Interface vptr initializations - toSymbol(); // define csym - - foreach (b; vtblInterfaces) - { -/// version (1 || INTERFACE_VIRTUAL) { - for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass) - { - assert(cd2); - csymoffset = cd2.baseVtblOffset(b); - if (csymoffset != ~0) - { - if (offset < b.offset) - dtnzeros(pdt, b.offset - offset); - dtxoff(pdt, cd2.toSymbol(), csymoffset, TYnptr); - break; - } - } -/// } else { -/// csymoffset = baseVtblOffset(b); -/// assert(csymoffset != ~0); -/// dtxoff(pdt, csym, csymoffset, TYnptr); -/// } - offset = b.offset + 4; - } - - if (offset < structsize) - dtnzeros(pdt, structsize - offset); - } - - Symbol* vtblsym; - - ///ClassDeclaration isClassDeclaration() { return cast(ClassDeclaration)this; } /// huh? - override ClassDeclaration isClassDeclaration() { return this; } -} +module dmd.ClassDeclaration; + +import dmd.common; +import dmd.AggregateDeclaration; +import dmd.InterfaceDeclaration; +import dmd.ThisDeclaration; +import dmd.CompoundStatement; +import dmd.DeleteDeclaration; +import dmd.NewDeclaration; +import dmd.CtorDeclaration; +import dmd.TypeIdentifier; +import dmd.STC; +import dmd.Parameter; +import dmd.TypeTuple; +import dmd.TY; +import dmd.LINK; +import dmd.DsymbolTable; +import dmd.FuncDeclaration; +import dmd.Array; +import dmd.TypeClass; +import dmd.Module; +import dmd.Id; +import dmd.Type; +import dmd.OverloadSet; +import dmd.ArrayTypes; +import dmd.BaseClass; +import dmd.ClassInfoDeclaration; +import dmd.TypeInfoClassDeclaration; +import dmd.Loc; +import dmd.Identifier; +import dmd.Dsymbol; +import dmd.Scope; +import dmd.TypeFunction; +import dmd.OutBuffer; +import dmd.HdrGenState; +import dmd.VarDeclaration; +import dmd.Initializer; +import dmd.ExpInitializer; +import dmd.TypeSArray; +import dmd.ScopeDsymbol; +import dmd.PROT; +import dmd.Util; +import dmd.Global; + +import dmd.expression.Util; + +import dmd.backend.Symbol; +import dmd.backend.dt_t; +import dmd.backend.TYPE; +import dmd.backend.FL; +import dmd.backend.SFL; +import dmd.backend.mTY; +import dmd.backend.SC; +import dmd.backend.mTYman; +import dmd.backend.Util; +import dmd.backend.TYM; +import dmd.backend.Classsym; +import dmd.backend.glue; +import dmd.backend.RTLSYM; +import dmd.backend.LIST; + +import dmd.codegen.Util; + +import dmd.DDMDExtensions; + +import std.string; + +version (DMDV2) { + enum CLASSINFO_SIZE = (0x3C+12+4); // value of ClassInfo.size +} else { + enum CLASSINFO_SIZE = (0x3C+12+4); // value of ClassInfo.size +} + +enum OFFSET_RUNTIME = 0x76543210; + +struct FuncDeclarationFinder +{ + bool visit(FuncDeclaration fd2) + { + //printf("param = %p, fd = %p %s\n", param, fd, fd.toChars()); + return fd is fd2; + } + + FuncDeclaration fd; +} + +class ClassDeclaration : AggregateDeclaration +{ + mixin insertMemberExtension!(typeof(this)); + + ClassDeclaration baseClass; // null only if this is Object +version(DMDV1) { + CtorDeclaration *ctor; + CtorDeclaration *defaultCtor; // default constructor +} + FuncDeclaration staticCtor; + FuncDeclaration staticDtor; + Array vtbl; // Array of FuncDeclaration's making up the vtbl[] + Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] + + BaseClasses baseclasses; // Array of BaseClass's; first is super, + // rest are Interface's + + int interfaces_dim; + BaseClass* interfaces; // interfaces[interfaces_dim] for this class + // (does not include baseClass) + + BaseClasses vtblInterfaces; // array of base interfaces that have + // their own vtbl[] + + TypeInfoClassDeclaration vclassinfo; // the ClassInfo object for this ClassDeclaration + bool com; // true if this is a COM class (meaning + // it derives from IUnknown) + bool isauto; // true if this is an auto class + bool isabstract; // true if abstract class +version(DMDV1) { + int isnested; // !=0 if is nested +} + int inuse; // to prevent recursive attempts + + this(Loc loc, Identifier id, BaseClasses baseclasses) + { + register(); + + super(loc, id); + + vtbl = new Array(); + vtblFinal = new Array(); + + enum msg = "only object.d can define this reserved class name"; + + if (baseclasses) { + this.baseclasses = baseclasses; + } else { + this.baseclasses = new BaseClasses(); + } + + //printf("ClassDeclaration(%s), dim = %d\n", id.toChars(), this.baseclasses.dim); + + // For forward references + type = new TypeClass(this); + + if (id) + { + // Look for special class names + + if (id is Id.__sizeof || id is Id.alignof_ || id is Id.mangleof_) + error("illegal class name"); + + // BUG: What if this is the wrong TypeInfo, i.e. it is nested? + if (id.toChars()[0] == 'T') + { + if (id is Id.TypeInfo) + { + if (global.typeinfo) { + global.typeinfo.error("%s", msg); + } + + global.typeinfo = this; + } + + if (id is Id.TypeInfo_Class) + { + if (global.typeinfoclass) + global.typeinfoclass.error("%s", msg); + global.typeinfoclass = this; + } + + if (id is Id.TypeInfo_Interface) + { + if (global.typeinfointerface) + global.typeinfointerface.error("%s", msg); + global.typeinfointerface = this; + } + + if (id is Id.TypeInfo_Struct) + { + if (global.typeinfostruct) + global.typeinfostruct.error("%s", msg); + global.typeinfostruct = this; + } + + if (id is Id.TypeInfo_Typedef) + { + if (global.typeinfotypedef) + global.typeinfotypedef.error("%s", msg); + global.typeinfotypedef = this; + } + + if (id is Id.TypeInfo_Pointer) + { + if (global.typeinfopointer) + global.typeinfopointer.error("%s", msg); + global.typeinfopointer = this; + } + + if (id is Id.TypeInfo_Array) + { + if (global.typeinfoarray) + global.typeinfoarray.error("%s", msg); + global.typeinfoarray = this; + } + + if (id is Id.TypeInfo_StaticArray) + { //if (global.typeinfostaticarray) + //global.typeinfostaticarray.error("%s", msg); + global.typeinfostaticarray = this; + } + + if (id is Id.TypeInfo_AssociativeArray) + { + if (global.typeinfoassociativearray) + global.typeinfoassociativearray.error("%s", msg); + global.typeinfoassociativearray = this; + } + + if (id is Id.TypeInfo_Enum) + { + if (global.typeinfoenum) + global.typeinfoenum.error("%s", msg); + global.typeinfoenum = this; + } + + if (id is Id.TypeInfo_Function) + { + if (global.typeinfofunction) + global.typeinfofunction.error("%s", msg); + global.typeinfofunction = this; + } + + if (id is Id.TypeInfo_Delegate) + { + if (global.typeinfodelegate) + global.typeinfodelegate.error("%s", msg); + global.typeinfodelegate = this; + } + + if (id is Id.TypeInfo_Tuple) + { + if (global.typeinfotypelist) + global.typeinfotypelist.error("%s", msg); + global.typeinfotypelist = this; + } + + version (DMDV2) { + if (id is Id.TypeInfo_Const) + { + if (global.typeinfoconst) + global.typeinfoconst.error("%s", msg); + global.typeinfoconst = this; + } + + if (id is Id.TypeInfo_Invariant) + { + if (global.typeinfoinvariant) + global.typeinfoinvariant.error("%s", msg); + global.typeinfoinvariant = this; + } + + if (id is Id.TypeInfo_Shared) + { + if (global.typeinfoshared) + global.typeinfoshared.error("%s", msg); + global.typeinfoshared = this; + } + + if (id == Id.TypeInfo_Wild) + { + if (global.typeinfowild) + global.typeinfowild.error("%s", msg); + global.typeinfowild = this; + } + } + } + + if (id is Id.Object_) + { + if (global.object) + global.object.error("%s", msg); + global.object = this; + } + +// if (id is Id.ClassInfo) + if (id is Id.TypeInfo_Class) + { + if (global.classinfo) + global.classinfo.error("%s", msg); + global.classinfo = this; + } + + if (id is Id.ModuleInfo) + { + if (global.moduleinfo) + global.moduleinfo.error("%s", msg); + global.moduleinfo = this; + } + } + + com = 0; + isauto = false; + isabstract = false; + inuse = 0; + } + + override Dsymbol syntaxCopy(Dsymbol s) + { + ClassDeclaration cd; + + //printf("ClassDeclaration.syntaxCopy('%s')\n", toChars()); + if (s) + cd = cast(ClassDeclaration)s; + else + cd = new ClassDeclaration(loc, ident, null); + + cd.storage_class |= storage_class; + + cd.baseclasses.setDim(this.baseclasses.dim); + for (size_t i = 0; i < cd.baseclasses.dim; i++) + { + auto b = this.baseclasses[i]; + auto b2 = new BaseClass(b.type.syntaxCopy(), b.protection); + cd.baseclasses[i] = b2; + } + + ScopeDsymbol.syntaxCopy(cd); + return cd; + } + + override void semantic(Scope sc) + { + uint offset; + + //printf("ClassDeclaration.semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); + //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : ""); + //printf("sc.stc = %x\n", sc.stc); + + //{ static int n; if (++n == 20) *(char*)0=0; } + + if (!ident) // if anonymous class + { + string id = "__anonclass"; + ident = Identifier.generateId(id); + } + + if (!sc) + sc = scope_; + + if (!parent && sc.parent && !sc.parent.isModule()) + parent = sc.parent; + + type = type.semantic(loc, sc); + handle = type; + + if (!members) // if forward reference + { + //printf("\tclass '%s' is forward referenced\n", toChars()); + return; + } + if (symtab) + { if (sizeok == 1 || !scope_) + { //printf("\tsemantic for '%s' is already completed\n", toChars()); + return; // semantic() already completed + } + } + else + symtab = new DsymbolTable(); + + Scope scx = null; + if (scope_) + { + sc = scope_; + scx = scope_; // save so we don't make redundant copies + scope_ = null; + } + uint dprogress_save = global.dprogress; +version (IN_GCC) { + methods.setDim(0); +} + + if (sc.stc & STC.STCdeprecated) + { + isdeprecated = 1; + } + + if (sc.linkage == LINK.LINKcpp) + error("cannot create C++ classes"); + + // Expand any tuples in baseclasses[] + for (size_t i = 0; i < baseclasses.dim; ) + { + auto b = baseclasses[i]; + //printf("test1 %s %s\n", toChars(), b.type.toChars()); + b.type = b.type.semantic(loc, sc); + //printf("test2\n"); + Type tb = b.type.toBasetype(); + + if (tb.ty == TY.Ttuple) + { + TypeTuple tup = cast(TypeTuple)tb; + enum PROT protection = b.protection; + baseclasses.remove(i); + size_t dim = Parameter.dim(tup.arguments); + for (size_t j = 0; j < dim; j++) + { + auto arg = Parameter.getNth(tup.arguments, j); + b = new BaseClass(arg.type, protection); + baseclasses.insert(i + j, b); + } + } + else + i++; + } + + // See if there's a base class as first in baseclasses[] + if (baseclasses.dim) + { + TypeClass tc; + BaseClass b; + Type tb; + + b = baseclasses[0]; + //b.type = b.type.semantic(loc, sc); + tb = b.type.toBasetype(); + if (tb.ty != TY.Tclass) + { error("base type must be class or interface, not %s", b.type.toChars()); + baseclasses.remove(0); + } + else + { + tc = cast(TypeClass)(tb); + + if (tc.sym.isDeprecated()) + { + if (!isDeprecated()) + { + // Deriving from deprecated class makes this one deprecated too + isdeprecated = 1; + + tc.checkDeprecated(loc, sc); + } + } + + if (tc.sym.isInterfaceDeclaration()) { + ; + } else { + for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass) + { + if (cdb == this) + { + error("circular inheritance"); + baseclasses.remove(0); + goto L7; + } + } + if (!tc.sym.symtab || tc.sym.sizeok == 0) + { // Try to resolve forward reference + if (sc.mustsemantic && tc.sym.scope_) + tc.sym.semantic(null); + } + if (!tc.sym.symtab || tc.sym.scope_ || tc.sym.sizeok == 0) + { + //printf("%s: forward reference of base class %s\n", toChars(), tc.sym.toChars()); + //error("forward reference of base class %s", baseClass.toChars()); + // Forward reference of base class, try again later + //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars()); + scope_ = scx ? scx : sc.clone(); + scope_.setNoFree(); + if (tc.sym.scope_) + tc.sym.scope_.module_.addDeferredSemantic(tc.sym); + scope_.module_.addDeferredSemantic(this); + return; + } + else + { baseClass = tc.sym; + b.base = baseClass; + } + L7: ; + } + } + } + + // Treat the remaining entries in baseclasses as interfaces + // Check for errors, handle forward references + for (int i = (baseClass ? 1 : 0); i < baseclasses.dim; ) + { TypeClass tc; + BaseClass b; + Type tb; + + b = baseclasses[i]; + b.type = b.type.semantic(loc, sc); + tb = b.type.toBasetype(); + if (tb.ty == TY.Tclass) + tc = cast(TypeClass)tb; + else + tc = null; + if (!tc || !tc.sym.isInterfaceDeclaration()) + { + error("base type must be interface, not %s", b.type.toChars()); + baseclasses.remove(i); + continue; + } + else + { + if (tc.sym.isDeprecated()) + { + if (!isDeprecated()) + { + // Deriving from deprecated class makes this one deprecated too + isdeprecated = 1; + + tc.checkDeprecated(loc, sc); + } + } + + // Check for duplicate interfaces + for (size_t j = (baseClass ? 1 : 0); j < i; j++) + { + auto b2 = baseclasses[j]; + if (b2.base == tc.sym) + error("inherits from duplicate interface %s", b2.base.toChars()); + } + + if (!tc.sym.symtab) + { // Try to resolve forward reference + if (sc.mustsemantic && tc.sym.scope_) + tc.sym.semantic(null); + } + + b.base = tc.sym; + if (!b.base.symtab || b.base.scope_) + { + //error("forward reference of base class %s", baseClass.toChars()); + // Forward reference of base, try again later + //printf("\ttry later, forward reference of base %s\n", baseClass.toChars()); + scope_ = scx ? scx : sc.clone(); + scope_.setNoFree(); + if (tc.sym.scope_) + tc.sym.scope_.module_.addDeferredSemantic(tc.sym); + scope_.module_.addDeferredSemantic(this); + return; + } + } + i++; + } + + + // If no base class, and this is not an Object, use Object as base class + if (!baseClass && ident !is Id.Object_) + { + // BUG: what if Object is redefined in an inner scope? + Type tbase = new TypeIdentifier(Loc(0), Id.Object_); + BaseClass b; + TypeClass tc; + Type bt; + + if (!global.object) + { + error("missing or corrupt object.d"); + fatal(); + } + bt = tbase.semantic(loc, sc).toBasetype(); + b = new BaseClass(bt, PROT.PROTpublic); + baseclasses.shift(b); + assert(b.type.ty == TY.Tclass); + tc = cast(TypeClass)(b.type); + baseClass = tc.sym; + assert(!baseClass.isInterfaceDeclaration()); + b.base = baseClass; + } + + interfaces_dim = baseclasses.dim; + interfaces = baseclasses.ptr; + + if (baseClass) + { + if (baseClass.storage_class & STC.STCfinal) + error("cannot inherit from final class %s", baseClass.toChars()); + + interfaces_dim--; + interfaces++; + + // Copy vtbl[] from base class + vtbl.setDim(baseClass.vtbl.dim); + memcpy(vtbl.data, baseClass.vtbl.data, (void*).sizeof * vtbl.dim); + + // Inherit properties from base class + com = baseClass.isCOMclass(); + isauto = baseClass.isauto; + vthis = baseClass.vthis; + storage_class |= baseClass.storage_class & STC.STC_TYPECTOR; + } + else + { + // No base class, so this is the root of the class hierarchy + vtbl.setDim(0); + vtbl.push(cast(void*)this); // leave room for classinfo as first member + } + + protection = sc.protection; + storage_class |= sc.stc; + + if (sizeok == 0) + { + interfaceSemantic(sc); + + foreach (s; members) + s.addMember(sc, this, true); + + /* If this is a nested class, add the hidden 'this' + * member which is a pointer to the enclosing scope. + */ + if (vthis) // if inheriting from nested class + { // Use the base class's 'this' member + isnested = true; + if (storage_class & STC.STCstatic) + error("static class cannot inherit from nested class %s", baseClass.toChars()); + if (toParent2() != baseClass.toParent2()) + { + if (toParent2()) + { + error("is nested within %s, but super class %s is nested within %s", + toParent2().toChars(), + baseClass.toChars(), + baseClass.toParent2().toChars()); + } + else + { + error("is not nested, but super class %s is nested within %s", + baseClass.toChars(), + baseClass.toParent2().toChars()); + } + isnested = false; + } + } + else if (!(storage_class & STC.STCstatic)) + { + Dsymbol s = toParent2(); + if (s) + { + AggregateDeclaration ad = s.isClassDeclaration(); + FuncDeclaration fd = s.isFuncDeclaration(); + + if (ad || fd) + { isnested = true; + Type t; + if (ad) + t = ad.handle; + else if (fd) + { + AggregateDeclaration ad2 = fd.isMember2(); + if (ad2) + t = ad2.handle; + else + { + t = global.tvoidptr; + } + } + else + assert(0); + if (t.ty == TY.Tstruct) // ref to struct + t = global.tvoidptr; + assert(!vthis); + vthis = new ThisDeclaration(loc, t); + members.push(vthis); + } + } + } + } + + if (storage_class & (STC.STCauto | STC.STCscope)) + isauto = true; + if (storage_class & STC.STCabstract) + isabstract = true; + if (storage_class & STC.STCimmutable) + type = type.invariantOf(); + else if (storage_class & STC.STCconst) + type = type.constOf(); + else if (storage_class & STC.STCshared) + type = type.sharedOf(); + + sc = sc.push(this); + sc.stc &= ~(STC.STCfinal | STC.STCauto | STC.STCscope | STC.STCstatic | + STC.STCabstract | STC.STCdeprecated | STC.STC_TYPECTOR | STC.STCtls | STC.STCgshared); + sc.stc |= storage_class & STC.STC_TYPECTOR; + sc.parent = this; + sc.inunion = 0; + + if (isCOMclass()) + { +version (Windows) { + sc.linkage = LINK.LINKwindows; +} else { + /* This enables us to use COM objects under Linux and + * work with things like XPCOM + */ + sc.linkage = LINK.LINKc; +} + } + sc.protection = PROT.PROTpublic; + sc.explicitProtection = 0; + sc.structalign = 8; + structalign = sc.structalign; + if (baseClass) + { sc.offset = baseClass.structsize; + alignsize = baseClass.alignsize; + // if (isnested) + // sc.offset += PTRSIZE; // room for uplevel context pointer + } + else + { sc.offset = PTRSIZE * 2; // allow room for __vptr and __monitor + alignsize = PTRSIZE; + } + structsize = sc.offset; + Scope scsave = sc.clone(); + sizeok = 0; + + /* Set scope so if there are forward references, we still might be able to + * resolve individual members like enums. + */ + foreach (s; members) + { + /* There are problems doing this in the general case because + * Scope keeps track of things like 'offset' + */ + if (s.isEnumDeclaration() || (s.isAggregateDeclaration() && s.ident)) + { + //printf("setScope %s %s\n", s->kind(), s->toChars()); + s.setScope(sc); + } + } + + foreach (Dsymbol s; members) { + s.semantic(sc); + } + + if (sizeok == 2) + { + // semantic() failed because of forward references. + // Unwind what we did, and defer it for later + fields.setDim(0); + structsize = 0; + alignsize = 0; + structalign = 0; + + sc = sc.pop(); + + scope_ = scx ? scx : sc.clone(); + scope_.setNoFree(); + scope_.module_.addDeferredSemantic(this); + + global.dprogress = dprogress_save; + + //printf("\tsemantic('%s') failed due to forward references\n", toChars()); + return; + } + + //printf("\tsemantic('%s') successful\n", toChars()); + + structsize = sc.offset; + //members.print(); + + /* Look for special member functions. + * They must be in this class, not in a base class. + */ + ctor = cast(CtorDeclaration)search(Loc(0), Id.ctor, 0); + if (ctor && (ctor.toParent() != this || !ctor.isCtorDeclaration())) + ctor = null; + + // dtor = (DtorDeclaration *)search(Id.dtor, 0); + // if (dtor && dtor.toParent() != this) + // dtor = null; + + // inv = (InvariantDeclaration *)search(Id.classInvariant, 0); + // if (inv && inv.toParent() != this) + // inv = null; + + // Can be in base class + aggNew = cast(NewDeclaration)search(Loc(0), Id.classNew, 0); + aggDelete = cast(DeleteDeclaration)search(Loc(0), Id.classDelete, 0); + + // If this class has no constructor, but base class does, create + // a constructor: + // this() { } + if (!ctor && baseClass && baseClass.ctor) + { + //printf("Creating default this(){} for class %s\n", toChars()); + CtorDeclaration ctor = new CtorDeclaration(loc, Loc(0), null, 0); + ctor.fbody = new CompoundStatement(Loc(0), new Statements()); + members.push(ctor); + ctor.addMember(sc, this, true); + sc = scsave; // why? What about sc.nofree? /// + sc.offset = structsize; + ctor.semantic(sc); + this.ctor = ctor; + defaultCtor = ctor; + } + +static if (false) { + if (baseClass) + { + if (!aggDelete) + aggDelete = baseClass.aggDelete; + if (!aggNew) + aggNew = baseClass.aggNew; + } +} + + // Allocate instance of each new interface + foreach (b; vtblInterfaces) + { + uint thissize = PTRSIZE; + + alignmember(structalign, thissize, &sc.offset); + assert(b.offset == 0); + b.offset = sc.offset; + + // Take care of single inheritance offsets + while (b.baseInterfaces.length) + { + b = b.baseInterfaces[0]; + b.offset = sc.offset; + } + + sc.offset += thissize; + if (alignsize < thissize) + alignsize = thissize; + } + structsize = sc.offset; + sizeok = 1; + global.dprogress++; + + dtor = buildDtor(sc); + + sc.pop(); + +static if (false) { // Do not call until toObjfile() because of forward references + // Fill in base class vtbl[]s + for (int i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + + //b.fillVtbl(this, &b.vtbl, 1); + } +} + //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + if (!isAnonymous()) + { + buf.printf("%s ", kind()); + buf.writestring(toChars()); + if (baseclasses.dim) + buf.writestring(" : "); + } + foreach (size_t i, BaseClass b; baseclasses) + { + if (i) + buf.writeByte(','); + //buf.writestring(b.base.ident.toChars()); + b.type.toCBuffer(buf, null, hgs); + } + if (members) + { + buf.writenl(); + buf.writeByte('{'); + buf.writenl(); + foreach (s; members) + { + buf.writestring(" "); + s.toCBuffer(buf, hgs); + } + buf.writestring("}"); + } + else + buf.writeByte(';'); + buf.writenl(); + } + + /********************************************* + * Determine if 'this' is a base class of cd. + * This is used to detect circular inheritance only. + */ + int isBaseOf2(ClassDeclaration cd) + { + if (!cd) + return 0; + //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); + foreach (b; cd.baseclasses) + { + if (b.base is this || isBaseOf2(b.base)) + return 1; + } + return 0; + } + + /******************************************* + * Determine if 'this' is a base class of cd. + */ +/// #define OFFSET_RUNTIME 0x76543210 + bool isBaseOf(ClassDeclaration cd, int* poffset) + { + if (!cd) + return 0; + //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); + foreach (b; cd.baseclasses) + { + if (b.base == this || isBaseOf2(b.base)) + return 1; + } + + return 0; + } + + override Dsymbol search(Loc, Identifier ident, int flags) + { + Dsymbol s; + //printf("%s.ClassDeclaration.search('%s')\n", toChars(), ident.toChars()); + + if (scope_) + { + Scope sc = scope_; + sc.mustsemantic++; + semantic(sc); + sc.mustsemantic--; + } + + if (!members || !symtab || scope_) + { + error("is forward referenced when looking for '%s'", ident.toChars()); + //*(char*)0=0; + return null; + } + + s = ScopeDsymbol.search(loc, ident, flags); + if (!s) + { + // Search bases classes in depth-first, left to right order + + int i; + + foreach (b; baseclasses) + { + if (b.base) + { + if (!b.base.symtab) + error("base %s is forward referenced", b.base.ident.toChars()); + else + { + s = b.base.search(loc, ident, flags); + if (s is this) // happens if s is nested in this and derives from this + s = null; + else if (s) + break; + } + } + } + } + return s; + } + +version (DMDV2) { + bool isFuncHidden(FuncDeclaration fd) + { + //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); + Dsymbol s = search(Loc(0), fd.ident, 4|2); + if (!s) + { + //printf("not found\n"); + /* Because, due to a hack, if there are multiple definitions + * of fd.ident, null is returned. + */ + return false; + } + + FuncDeclarationFinder p; p.fd = fd; + + s = s.toAlias(); + OverloadSet os = s.isOverloadSet(); + if (os) + { + foreach (s2; os.a) + { + auto f2 = s2.isFuncDeclaration(); + if (f2 && overloadApply(f2, p)) + return false; + } + return true; + } + else + { + FuncDeclaration fdstart = s.isFuncDeclaration(); + //printf("%s fdstart = %p\n", s.kind(), fdstart); + return !overloadApply(fdstart, p); + } + } +} + FuncDeclaration findFunc(Identifier ident, TypeFunction tf) + { + //printf("ClassDeclaration.findFunc(%s, %s) %s\n", ident.toChars(), tf.toChars(), toChars()); + + ClassDeclaration cd = this; + Array vtbl = cd.vtbl; + while (true) + { + for (size_t i = 0; i < vtbl.dim; i++) + { + FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); + if (!fd) + continue; // the first entry might be a ClassInfo + + //printf("\t[%d] = %s\n", i, fd.toChars()); + if (ident == fd.ident && + //tf.equals(fd.type) + fd.type.covariant(tf) == 1 + ) + { //printf("\t\tfound\n"); + return fd; + } + //else printf("\t\t%d\n", fd.type.covariant(tf)); + } + if (!cd) + break; + + vtbl = cd.vtblFinal; + cd = cd.baseClass; + } + + return null; + } + + void interfaceSemantic(Scope sc) + { + InterfaceDeclaration id = isInterfaceDeclaration(); + + vtblInterfaces = new BaseClasses(); + vtblInterfaces.reserve(interfaces_dim); + + for (size_t i = 0; i < interfaces_dim; i++) + { + BaseClass b = interfaces[i]; + + // If this is an interface, and it derives from a COM interface, + // then this is a COM interface too. + if (b.base.isCOMinterface()) + com = 1; + + if (b.base.isCPPinterface() && id) + id.cpp = 1; + + vtblInterfaces.push(b); + b.copyBaseInterfaces(vtblInterfaces); + } + } + +version(DMDV1) +{ + int isNested() + { + assert(false); + } +} + bool isCOMclass() + { + return com; + } + + bool isCOMinterface() + { + return false; + } + +version (DMDV2) { + bool isCPPinterface() + { + return false; + } +} + bool isAbstract() + { + if (isabstract) + return true; + + for (int i = 1; i < vtbl.dim; i++) + { + FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); + + //printf("\tvtbl[%d] = %p\n", i, fd); + if (!fd || fd.isAbstract()) + { + isabstract = true; + return true; + } + } + + return false; + } + + int vtblOffset() + { + assert(false); + } + + override string kind() + { + return "class"; + } + + override string mangle() + { + Dsymbol parentsave = parent; + + //printf("ClassDeclaration.mangle() %s.%s\n", parent.toChars(), toChars()); + + /* These are reserved to the compiler, so keep simple + * names for them. + */ + if (ident is Id.Exception) + { + if (parent.ident is Id.object) + parent = null; + } + else if (ident is Id.TypeInfo || + // ident is Id.Exception || + ident is Id.TypeInfo_Struct || + ident is Id.TypeInfo_Class || + ident is Id.TypeInfo_Typedef || + ident is Id.TypeInfo_Tuple || + this is global.object || + this is global.classinfo || + this is global.moduleinfo || + ident.toChars().startsWith("TypeInfo_") + ) + { + parent = null; + } + + string id = Dsymbol.mangle(); + parent = parentsave; + return id; + } + + override void toDocBuffer(OutBuffer buf) + { + assert(false); + } + + override PROT getAccess(Dsymbol smember) // determine access to smember + { + PROT access_ret = PROT.PROTnone; + + version (LOG) { + printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n", + toChars(), smember.toChars()); + } + if (smember.toParent() is this) + { + access_ret = smember.prot(); + } + else + { + PROT access; + + if (smember.isDeclaration().isStatic()) + { + access_ret = smember.prot(); + } + + foreach (b; baseclasses) + { + access = b.base.getAccess(smember); + switch (access) + { + case PROT.PROTnone: + break; + + case PROT.PROTprivate: + access = PROT.PROTnone; // private members of base class not accessible + break; + + case PROT.PROTpackage: + case PROT.PROTprotected: + case PROT.PROTpublic: + case PROT.PROTexport: + // If access is to be tightened + if (b.protection < access) + access = b.protection; + + // Pick path with loosest access + if (access > access_ret) + access_ret = access; + break; + + default: + assert(0); + } + } + } + + version (LOG) { + printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n", + toChars(), smember.toChars(), access_ret); + } + + return access_ret; + } + + override void addLocalClass(ClassDeclarations aclasses) + { + aclasses.push(this); + } + + // Back end + override void toObjFile(int multiobj) // compile to .obj file + { + uint offset; + Symbol* sinit; + enum_SC scclass; + + //printf("ClassDeclaration.toObjFile('%s')\n", toChars()); + + if (!members) + return; + + if (multiobj) + { + obj_append(this); + return; + } + + if (global.params.symdebug) + toDebug(); + + assert(!scope_); // semantic() should have been run to completion + + scclass = SCglobal; + if (inTemplateInstance()) + scclass = SCcomdat; + + // Put out the members + foreach (member; members) + member.toObjFile(0); + +static if (false) { + // Build destructor by aggregating dtors[] + Symbol* sdtor; + switch (dtors.dim) + { + case 0: + // No destructors for this class + sdtor = null; + break; + + case 1: + // One destructor, just use it directly + sdtor = (cast(DtorDeclaration)dtors.data[0]).toSymbol(); + break; + + default: + { + /* Build a destructor that calls all the + * other destructors in dtors[]. + */ + + elem* edtor = null; + + // Declare 'this' pointer for our new destructor + Symbol* sthis = symbol_calloc("this"); + sthis.Stype = type_fake(TYnptr); + sthis.Stype.Tcount++; + sthis.Sclass = SCfastpar; + sthis.Spreg = AX; + sthis.Sfl = FLauto; + + // Call each of the destructors in dtors[] + // in reverse order + for (size_t i = 0; i < dtors.dim; i++) + { + DtorDeclaration d = cast(DtorDeclaration)dtors.data[i]; + Symbol* s = d.toSymbol(); + elem* e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); + edtor = el_combine(e, edtor); + } + + // Create type for the function + .type* t = type_alloc(TYjfunc); + t.Tflags |= TFprototype | TFfixed; + t.Tmangle = mTYman_d; + t.Tnext = tsvoid; + tsvoid.Tcount++; + + // Create the function, sdtor, and write it out + localgot = null; + sdtor = toSymbolX("__dtor", SCglobal, t, "FZv"); + block* b = block_calloc(); + b.BC = BCret; + b.Belem = edtor; + sdtor.Sfunc.Fstartblock = b; + cstate.CSpsymtab = &sdtor.Sfunc.Flocsym; + symbol_add(sthis); + writefunc(sdtor); + } + } +} + + // Generate C symbols + toSymbol(); + toVtblSymbol(); + sinit = toInitializer(); + + ////////////////////////////////////////////// + + // Generate static initializer + sinit.Sclass = scclass; + sinit.Sfl = FLdata; + version (ELFOBJ) { // Burton + sinit.Sseg = Segment.CDATA; + } + version (MACHOBJ) { + sinit.Sseg = Segment.DATA; + } + toDt(&sinit.Sdt); + outdata(sinit); + + ////////////////////////////////////////////// + + // Put out the TypeInfo + type.getTypeInfo(null); + //type.vtinfo.toObjFile(multiobj); + + ////////////////////////////////////////////// + + // Put out the ClassInfo + csym.Sclass = scclass; + csym.Sfl = FLdata; + + /* The layout is: + { + void **vptr; + monitor_t monitor; + byte[] initializer; // static initialization data + char[] name; // class name + void *[] vtbl; + Interface[] interfaces; + ClassInfo *base; // base class + void *destructor; + void *invariant; // class invariant + uint flags; + void *deallocator; + OffsetTypeInfo[] offTi; + void *defaultConstructor; + const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function + //TypeInfo typeinfo; + } + */ + dt_t* dt = null; + offset = CLASSINFO_SIZE; // must be ClassInfo.size + if (global.classinfo) + { + if (global.classinfo.structsize != CLASSINFO_SIZE) + error("D compiler and phobos' object.d are mismatched"); + + dtxoff(&dt, global.classinfo.toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo + } + else + { + dtdword(&dt, 0); // BUG: should be an assert() + } + + dtdword(&dt, 0); // monitor + + // initializer[] + assert(structsize >= 8); + dtdword(&dt, structsize); // size + dtxoff(&dt, sinit, 0, TYnptr); // initializer + + // name[] + string name = ident.toChars(); + size_t namelen = name.length; + if (!(namelen > 9 && name[0..9] == "TypeInfo_")) + { + name = toPrettyChars(); + namelen = name.length; + } + dtdword(&dt, namelen); + dtabytes(&dt, TYnptr, 0, namelen + 1, toStringz(name)); + + // vtbl[] + dtdword(&dt, vtbl.dim); + dtxoff(&dt, vtblsym, 0, TYnptr); + + // interfaces[] + dtdword(&dt, vtblInterfaces.dim); + if (vtblInterfaces.dim) + dtxoff(&dt, csym, offset, TYnptr); // (*) + else + dtdword(&dt, 0); + + // base + if (baseClass) + dtxoff(&dt, baseClass.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // destructor + if (dtor) + dtxoff(&dt, dtor.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // invariant + if (inv) + dtxoff(&dt, inv.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // flags + int flags = 4 | isCOMclass(); + version (DMDV2) { + flags |= 16; + } + flags |= 32; + + if (ctor) + flags |= 8; + for (ClassDeclaration cd = this; cd; cd = cd.baseClass) + { + if (cd.members) + { + foreach (sm; cd.members) + { + //printf("sm = %s %s\n", sm.kind(), sm.toChars()); + if (sm.hasPointers()) + goto L2; + } + } + } + flags |= 2; // no pointers + L2: + dtdword(&dt, flags); + + + // deallocator + if (aggDelete) + dtxoff(&dt, aggDelete.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // offTi[] + dtdword(&dt, 0); + dtdword(&dt, 0); // null for now, fix later + + // defaultConstructor + if (defaultCtor) + dtxoff(&dt, defaultCtor.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + version (DMDV2) { + FuncDeclaration sgetmembers = findGetMembers(); + if (sgetmembers) + dtxoff(&dt, sgetmembers.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); // module getMembers() function + } + + //dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr); // typeinfo + //dtdword(&dt, 0); + + ////////////////////////////////////////////// + + // Put out vtblInterfaces.data[]. Must immediately follow csym, because + // of the fixup (*) + + offset += vtblInterfaces.dim * (4 * PTRSIZE); + foreach (b; vtblInterfaces) + { + ClassDeclaration id = b.base; + + /* The layout is: + * struct Interface + * { + * ClassInfo *interface; + * void *[] vtbl; + * ptrdiff_t offset; + * } + */ + + // Fill in vtbl[] + b.fillVtbl(this, b.vtbl, 1); + + dtxoff(&dt, id.toSymbol(), 0, TYnptr); // ClassInfo + + // vtbl[] + dtdword(&dt, id.vtbl.dim); + dtxoff(&dt, csym, offset, TYnptr); + + dtdword(&dt, b.offset); // this offset + + offset += id.vtbl.dim * PTRSIZE; + } + + // Put out the vtblInterfaces.data[].vtbl[] + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars()); + foreach (size_t i, BaseClass b; vtblInterfaces) + { + ClassDeclaration id = b.base; + int j; + + //printf(" interface[%d] is '%s'\n", i, id.toChars()); + j = 0; + if (id.vtblOffset()) + { + // First entry is ClassInfo reference + //dtxoff(&dt, id.toSymbol(), 0, TYnptr); + + // First entry is struct Interface reference + dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); + j = 1; + } + + assert(id.vtbl.dim == b.vtbl.dim); + for (; j < id.vtbl.dim; j++) + { + assert(j < b.vtbl.dim); + static if (false) { + Object o = cast(Object)b.vtbl.data[j]; + if (o) + { + printf("o = %p\n", o); + assert(o.dyncast() == DYNCAST_DSYMBOL); + Dsymbol s = cast(Dsymbol)o; + printf("s.kind() = '%s'\n", s.kind()); + } + } + auto fd = cast(FuncDeclaration)b.vtbl.data[j]; + if (fd) + dtxoff(&dt, fd.toThunkSymbol(b.offset), 0, TYnptr); + else + dtdword(&dt, 0); + } + } + + static if (true) { + // Put out the overriding interface vtbl[]s. + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); + ClassDeclaration cd; + scope Array bvtbl = new Array(); + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + foreach (size_t k, BaseClass bs; cd.vtblInterfaces) + { + if (bs.fillVtbl(this, bvtbl, 0)) + { + //printf("\toverriding vtbl[] for %s\n", bs.base.toChars()); + ClassDeclaration id = bs.base; + int j; + + j = 0; + if (id.vtblOffset()) + { + // First entry is ClassInfo reference + //dtxoff(&dt, id.toSymbol(), 0, TYnptr); + + // First entry is struct Interface reference + dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); + j = 1; + } + + for (; j < id.vtbl.dim; j++) + { + assert(j < bvtbl.dim); + FuncDeclaration fd = cast(FuncDeclaration)bvtbl.data[j]; + if (fd) + dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); + else + dtdword(&dt, 0); + } + } + } + } + } + + version (INTERFACE_VIRTUAL) { + // Put out the overriding interface vtbl[]s. + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); + for (size_t i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + ClassDeclaration cd; + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + for (int k = 0; k < cd.vtblInterfaces.dim; k++) + { + BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; + + if (b.base == bs.base) + { + //printf("\toverriding vtbl[] for %s\n", b.base.toChars()); + ClassDeclaration id = b.base; + int j; + + j = 0; + if (id.vtblOffset()) + { + // First entry is ClassInfo reference + //dtxoff(&dt, id.toSymbol(), 0, TYnptr); + + // First entry is struct Interface reference + dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); + j = 1; + } + + for (; j < id.vtbl.dim; j++) + { + assert(j < b.vtbl.dim); + FuncDeclaration fd = cast(FuncDeclaration)b.vtbl.data[j]; + if (fd) + dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); + else + dtdword(&dt, 0); + } + } + } + } + } + } + + + csym.Sdt = dt; + version (ELFOBJ_OR_MACHOBJ) { // Burton + // ClassInfo cannot be const data, because we use the monitor on it + csym.Sseg = Segment.DATA; + } + outdata(csym); + if (isExport()) + obj_export(csym,0); + + ////////////////////////////////////////////// + + // Put out the vtbl[] + //printf("putting out %s.vtbl[]\n", toChars()); + dt = null; + size_t i; + if (0) + i = 0; + else + { + dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference + i = 1; + } + for (; i < vtbl.dim; i++) + { + FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); + + //printf("\tvtbl[%d] = %p\n", i, fd); + if (fd && (fd.fbody || !isAbstract())) + { + Symbol* s = fd.toSymbol(); + + version (DMDV2) { + if (isFuncHidden(fd)) + { + /* fd is hidden from the view of this class. + * If fd overlaps with any function in the vtbl[], then + * issue 'hidden' error. + */ + for (int j = 1; j < vtbl.dim; j++) + { + if (j == i) + continue; + FuncDeclaration fd2 = (cast(Dsymbol)vtbl.data[j]).isFuncDeclaration(); + if (!fd2.ident.equals(fd.ident)) + continue; + if (fd.leastAsSpecialized(fd2) || fd2.leastAsSpecialized(fd)) + { + if (global.params.warnings) + { + TypeFunction tf = cast(TypeFunction)fd.type; + if (tf.ty == Tfunction) + warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Parameter.argsTypesToChars(tf.parameters, tf.varargs), toChars()); + else + warning("%s is hidden by %s\n", fd.toPrettyChars(), toChars()); + } + s = rtlsym[RTLSYM_DHIDDENFUNC]; + break; + } + } + } + } + dtxoff(&dt, s, 0, TYnptr); + } + else + dtdword(&dt, 0); + } + + vtblsym.Sdt = dt; + vtblsym.Sclass = scclass; + vtblsym.Sfl = FLdata; + version (ELFOBJ) { + vtblsym.Sseg = Segment.CDATA; + } + version (MACHOBJ) { + vtblsym.Sseg = Segment.DATA; + } + outdata(vtblsym); + if (isExport()) + obj_export(vtblsym,0); + } + + void toDebug() + { + assert(false); + } + + /****************************************** + * Get offset of base class's vtbl[] initializer from start of csym. + * Returns ~0 if not this csym. + */ + uint baseVtblOffset(BaseClass bc) + { + uint csymoffset; + + //printf("ClassDeclaration.baseVtblOffset('%s', bc = %p)\n", toChars(), bc); + csymoffset = CLASSINFO_SIZE; + csymoffset += vtblInterfaces.dim * (4 * PTRSIZE); + + foreach (b; vtblInterfaces) + { + if (b == bc) + return csymoffset; + csymoffset += b.base.vtbl.dim * PTRSIZE; + } + + static if (true) { + // Put out the overriding interface vtbl[]s. + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); + ClassDeclaration cd; + Array bvtbl; + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + foreach(bs; cd.vtblInterfaces) + { + if (bs.fillVtbl(this, null, 0)) + { + if (bc == bs) + { + //printf("\tcsymoffset = x%x\n", csymoffset); + return csymoffset; + } + csymoffset += bs.base.vtbl.dim * PTRSIZE; + } + } + } + } + version (INTERFACE_VIRTUAL) { + for (size_t i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + ClassDeclaration cd; + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + //printf("\tbase class %s\n", cd.toChars()); + for (int k = 0; k < cd.vtblInterfaces.dim; k++) + { + BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; + + if (bc == bs) + { + //printf("\tcsymoffset = x%x\n", csymoffset); + return csymoffset; + } + if (b.base == bs.base) + csymoffset += bs.base.vtbl.dim * PTRSIZE; + } + } + } + } + + return ~0; + } + + /************************************* + * Create the "ClassInfo" symbol + */ + override Symbol* toSymbol() + { + if (!csym) + { + Symbol* s; + + s = toSymbolX("__Class", SC.SCextern, global.scc.Stype, "Z"); + s.Sfl = FL.FLextern; + s.Sflags |= SFL.SFLnodebug; + csym = s; + slist_add(s); + } + + return csym; + } + + /************************************* + * This is accessible via the ClassData, but since it is frequently + * needed directly (like for rtti comparisons), make it directly accessible. + */ + Symbol* toVtblSymbol() + { + if (!vtblsym) + { + if (!csym) + toSymbol(); + + TYPE* t = type_alloc(TYM.TYnptr | mTY.mTYconst); + t.Tnext = tsvoid; + t.Tnext.Tcount++; + t.Tmangle = mTYman.mTYman_d; + + Symbol* s = toSymbolX("__vtbl", SC.SCextern, t, "Z"); + s.Sflags |= SFL.SFLnodebug; + s.Sfl = FL.FLextern; + vtblsym = s; + slist_add(s); + } + return vtblsym; + } + + // Generate the data for the static initializer. + void toDt(dt_t **pdt) + { + //printf("ClassDeclaration.toDt(this = '%s')\n", toChars()); + + // Put in first two members, the vtbl[] and the monitor + dtxoff(pdt, toVtblSymbol(), 0, TYnptr); + dtdword(pdt, 0); // monitor + + // Put in the rest + toDt2(pdt, this); + + //printf("-ClassDeclaration.toDt(this = '%s')\n", toChars()); + } + + void toDt2(dt_t** pdt, ClassDeclaration cd) + { + uint offset; + + dt_t* dt; + uint csymoffset; + + version (LOG) { + printf("ClassDeclaration.toDt2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); + } + if (baseClass) + { + baseClass.toDt2(pdt, cd); + offset = baseClass.structsize; + } + else + { + offset = 8; + } + + // Note equivalence of this loop to struct's + for (size_t i = 0; i < fields.dim; i++) + { + VarDeclaration v = cast(VarDeclaration)fields[i]; + Initializer init; + + //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset); + dt = null; + init = v.init; + if (init) + { + //printf("\t\t%s has initializer %s\n", v.toChars(), init.toChars()); + ExpInitializer ei = init.isExpInitializer(); + Type tb = v.type.toBasetype(); + if (ei && tb.ty == Tsarray) + (cast(TypeSArray)tb).toDtElem(&dt, ei.exp); + else + dt = init.toDt(); + } + else if (v.offset >= offset) + { //printf("\t\tdefault initializer\n"); + v.type.toDt(&dt); + } + if (dt) + { + if (v.offset < offset) + error("duplicated union initialization for %s", v.toChars()); + else + { + if (offset < v.offset) + dtnzeros(pdt, v.offset - offset); + dtcat(pdt, dt); + offset = v.offset + cast(uint)v.type.size(); + } + } + } + + // Interface vptr initializations + toSymbol(); // define csym + + foreach (b; vtblInterfaces) + { +/// version (1 || INTERFACE_VIRTUAL) { + for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass) + { + assert(cd2); + csymoffset = cd2.baseVtblOffset(b); + if (csymoffset != ~0) + { + if (offset < b.offset) + dtnzeros(pdt, b.offset - offset); + dtxoff(pdt, cd2.toSymbol(), csymoffset, TYnptr); + break; + } + } +/// } else { +/// csymoffset = baseVtblOffset(b); +/// assert(csymoffset != ~0); +/// dtxoff(pdt, csym, csymoffset, TYnptr); +/// } + offset = b.offset + 4; + } + + if (offset < structsize) + dtnzeros(pdt, structsize - offset); + } + + Symbol* vtblsym; + + ///ClassDeclaration isClassDeclaration() { return cast(ClassDeclaration)this; } /// huh? + override ClassDeclaration isClassDeclaration() { return this; } +} diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ClassInfoDeclaration.d --- a/dmd/ClassInfoDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ClassInfoDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.backend.SC; import dmd.backend.Util; +import dmd.DDMDExtensions; + class ClassInfoDeclaration : VarDeclaration { + mixin insertMemberExtension!(typeof(this)); + ClassDeclaration cd; this(ClassDeclaration cd) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CmpExp.d --- a/dmd/CmpExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CmpExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -29,8 +29,12 @@ import dmd.backend.OPER; import dmd.backend.rel; +import dmd.DDMDExtensions; + class CmpExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(TOK op, Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ComExp.d --- a/dmd/ComExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ComExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.expression.Util; import dmd.expression.Com; +import dmd.DDMDExtensions; + class ComExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CommaExp.d --- a/dmd/CommaExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CommaExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.elem; import dmd.backend.Util; +import dmd.DDMDExtensions; + class CommaExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CompileDeclaration.d --- a/dmd/CompileDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CompileDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,10 +18,14 @@ import dmd.StringExp; import dmd.Parser; +import dmd.DDMDExtensions; + // Mixin declarations class CompileDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + Expression exp; ScopeDsymbol sd; bool compiled; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CompileExp.d --- a/dmd/CompileExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CompileExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.expression.Util; +import dmd.DDMDExtensions; + class CompileExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CompileStatement.d --- a/dmd/CompileStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CompileStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import dmd.CompoundStatement; import dmd.StringExp; +import dmd.DDMDExtensions; + class CompileStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ComplexExp.d --- a/dmd/ComplexExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ComplexExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.TYM; import dmd.backend.mTY; +import dmd.DDMDExtensions; + class ComplexExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Complex!(real) value; this(Loc loc, Complex!(real) value, Type type) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CompoundDeclarationStatement.d --- a/dmd/CompoundDeclarationStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CompoundDeclarationStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.OutBuffer; import dmd.HdrGenState; +import dmd.DDMDExtensions; + class CompoundDeclarationStatement : CompoundStatement { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Statements s) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CompoundStatement.d --- a/dmd/CompoundStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CompoundStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,8 +27,12 @@ import dmd.BE; import dmd.Util; +import dmd.DDMDExtensions; + class CompoundStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statements statements; this(Loc loc, Statements s) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CondExp.d --- a/dmd/CondExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CondExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -31,8 +31,12 @@ import dmd.expression.Util; +import dmd.DDMDExtensions; + class CondExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + Expression econd; this(Loc loc, Expression econd, Expression e1, Expression e2) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Condition.d --- a/dmd/Condition.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Condition.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class Condition : TObject { + mixin insertMemberExtension!(typeof(this)); + Loc loc; int inc = 0;// 0: not computed yet // 1: include diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ConditionalDeclaration.d --- a/dmd/ConditionalDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ConditionalDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.OutBuffer; import dmd.HdrGenState; +import dmd.DDMDExtensions; + class ConditionalDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + Condition condition; Dsymbols elsedecl; // array of Dsymbol's for else block diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ConditionalStatement.d --- a/dmd/ConditionalStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ConditionalStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.ArrayTypes; import dmd.BE; +import dmd.DDMDExtensions; + class ConditionalStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Condition condition; Statement ifbody; Statement elsebody; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ContinueStatement.d --- a/dmd/ContinueStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ContinueStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.backend.block; import dmd.backend.Blockx; +import dmd.DDMDExtensions; + class ContinueStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; this(Loc loc, Identifier ident) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/CtorDeclaration.d --- a/dmd/CtorDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/CtorDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.Parameter; import dmd.Id; +import dmd.DDMDExtensions; + class CtorDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + Parameters arguments; int varargs; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DDMDExtensions.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/DDMDExtensions.d Tue Jun 07 23:37:34 2011 -0400 @@ -0,0 +1,20 @@ +module dmd.DDMDExtensions; + +/++ +If you're making a tool based off of DDMD, +you can uncomment the commented lines below, +and change "DSuperTool" to the name of your tool. +Then, create your own module to handle +"insertMemberDSuperTool". + +That will allow you to insert code into any +module or class in DDMD's AST without actually +having to modify DDMD's actual AST code. ++/ + +//import DSuperTool.DDMDExtension; + +template insertMemberExtension(T) +{ + //mixin insertMemberDSuperTool!T; +} diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DebugCondition.d --- a/dmd/DebugCondition.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DebugCondition.d Tue Jun 07 23:37:34 2011 -0400 @@ -14,8 +14,12 @@ import dmd.condition.util.findCondition; +import dmd.DDMDExtensions; + class DebugCondition : DVCondition { + mixin insertMemberExtension!(typeof(this)); + static void setGlobalLevel(uint level) { assert(false); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DebugSymbol.d --- a/dmd/DebugSymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DebugSymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,12 +13,16 @@ import dmd.condition.util.findCondition; +import dmd.DDMDExtensions; + /* DebugSymbol's happen for statements like: * debug = identifier; * debug = integer; */ class DebugSymbol : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + uint level; this(Loc loc, Identifier ident) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Declaration.d --- a/dmd/Declaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Declaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,6 +21,8 @@ import std.conv : to; } +import dmd.DDMDExtensions; + import std.stdio : writef; import core.stdc.ctype; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DeclarationExp.d --- a/dmd/DeclarationExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DeclarationExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,10 +26,14 @@ import dmd.Type; import dmd.codegen.Util; +import dmd.DDMDExtensions; + // Declaration of a symbol class DeclarationExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Dsymbol declaration; this(Loc loc, Dsymbol declaration) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DeclarationStatement.d --- a/dmd/DeclarationStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DeclarationStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,8 +13,12 @@ import dmd.TOK; import dmd.VarDeclaration; +import dmd.DDMDExtensions; + class DeclarationStatement : ExpStatement { + mixin insertMemberExtension!(typeof(this)); + // Doing declarations as an expression, rather than a statement, // makes inlining functions much easier. diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DefaultInitExp.d --- a/dmd/DefaultInitExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DefaultInitExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.TOK; import dmd.Token; +import dmd.DDMDExtensions; + class DefaultInitExp : Expression { + mixin insertMemberExtension!(typeof(this)); + TOK subop; this(Loc loc, TOK subop, int size) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DefaultStatement.d --- a/dmd/DefaultStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DefaultStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.backend.block; import dmd.backend.BC; +import dmd.DDMDExtensions; + class DefaultStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement statement; version (IN_GCC) { block* cblock = null; // back end: label for the block diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DelegateExp.d --- a/dmd/DelegateExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DelegateExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,8 +27,12 @@ import dmd.backend.TYM; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class DelegateExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + FuncDeclaration func; bool hasOverloads; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DeleteDeclaration.d --- a/dmd/DeleteDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DeleteDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.LINK; import dmd.TY; +import dmd.DDMDExtensions; + class DeleteDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + Parameters arguments; this(Loc loc, Loc endloc, Parameters arguments) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DeleteExp.d --- a/dmd/DeleteExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DeleteExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -41,8 +41,12 @@ import dmd.backend.Symbol; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class DeleteExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DivAssignExp.d --- a/dmd/DivAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DivAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,8 +25,12 @@ import dmd.expression.Div; import dmd.expression.Util; +import dmd.DDMDExtensions; + class DivAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DivExp.d --- a/dmd/DivExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DivExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class DivExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DoStatement.d --- a/dmd/DoStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DoStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.backend.Util; import dmd.backend.BC; +import dmd.DDMDExtensions; + class DoStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement body_; Expression condition; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DocComment.d --- a/dmd/DocComment.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DocComment.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class DocComment : TObject { + mixin insertMemberExtension!(typeof(this)); + Array sections; // Section*[] Section summary; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DollarExp.d --- a/dmd/DollarExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DollarExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -7,8 +7,12 @@ import dmd.TOK; import dmd.Id; +import dmd.DDMDExtensions; + class DollarExp : IdentifierExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DotExp.d --- a/dmd/DotExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DotExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.BinExp; import dmd.TOK; +import dmd.DDMDExtensions; + class DotExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DotIdExp.d --- a/dmd/DotIdExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DotIdExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -44,8 +44,12 @@ import dmd.expression.Util; +import dmd.DDMDExtensions; + class DotIdExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; this(Loc loc, Expression e, Identifier ident) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DotTemplateExp.d --- a/dmd/DotTemplateExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DotTemplateExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -12,8 +12,12 @@ import dmd.expression.Util; +import dmd.DDMDExtensions; + class DotTemplateExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + TemplateDeclaration td; this(Loc loc, Expression e, TemplateDeclaration td) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DotTemplateInstanceExp.d --- a/dmd/DotTemplateInstanceExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DotTemplateInstanceExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -31,11 +31,15 @@ import dmd.expression.Util; +import dmd.DDMDExtensions; + /* Things like: * foo.bar!(args) */ class DotTemplateInstanceExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + TemplateInstance ti; this(Loc loc, Expression e, Identifier name, Objects tiargs) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DotTypeExp.d --- a/dmd/DotTypeExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DotTypeExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.backend.Util; +import dmd.DDMDExtensions; + class DotTypeExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Dsymbol sym; this(Loc loc, Expression e, Dsymbol s) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DotVarExp.d --- a/dmd/DotVarExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DotVarExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -38,8 +38,12 @@ import dmd.backend.OPER; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class DotVarExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Declaration var; bool hasOverloads; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Dsymbol.d --- a/dmd/Dsymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Dsymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -1,940 +1,944 @@ -module dmd.Dsymbol; - -import dmd.common; -import dmd.Loc; -import dmd.STC; -import dmd.Scope; -import dmd.Lexer; -import dmd.Module; -import dmd.Array; -import dmd.ScopeDsymbol; -import dmd.OutBuffer; -import dmd.Id; -import dmd.Identifier; -import dmd.TemplateInstance; -import dmd.SharedStaticCtorDeclaration; -import dmd.SharedStaticDtorDeclaration; -import dmd.HdrGenState; -import dmd.AggregateDeclaration; -import dmd.ClassDeclaration; -import dmd.LabelDsymbol; -import dmd.Type; -import dmd.PROT; -import dmd.ArrayTypes; -import dmd.Package; -import dmd.EnumMember; -import dmd.TemplateDeclaration; -import dmd.TemplateMixin; -import dmd.Declaration; -import dmd.ThisDeclaration; -import dmd.TupleDeclaration; -import dmd.TypedefDeclaration; -import dmd.AliasDeclaration; -import dmd.FuncDeclaration; -import dmd.FuncAliasDeclaration; -import dmd.FuncLiteralDeclaration; -import dmd.CtorDeclaration; -import dmd.PostBlitDeclaration; -import dmd.DtorDeclaration; -import dmd.StaticCtorDeclaration; -import dmd.StaticDtorDeclaration; -import dmd.InvariantDeclaration; -import dmd.UnitTestDeclaration; -import dmd.NewDeclaration; -import dmd.VarDeclaration; -import dmd.StructDeclaration; -import dmd.UnionDeclaration; -import dmd.InterfaceDeclaration; -import dmd.WithScopeSymbol; -import dmd.ArrayScopeSymbol; -import dmd.Import; -import dmd.EnumDeclaration; -import dmd.DeleteDeclaration; -import dmd.SymbolDeclaration; -import dmd.AttribDeclaration; -import dmd.OverloadSet; -import dmd.DYNCAST; -import dmd.Global; -import dmd.Expression; -import dmd.TOK; -import dmd.VarExp; -import dmd.FuncExp; - -import dmd.backend.Symbol; -import dmd.backend.TYPE; -import dmd.backend.Util; -import dmd.backend.mTYman; -import dmd.backend.TYFL; -import dmd.backend.TYM; -import dmd.backend.mTY; -import dmd.backend.SC; -import dmd.backend.FL; -import dmd.backend.LIST; -public import dmd.PASS; - -import core.stdc.string : strcmp, memcpy, strlen; -version (Bug4054) import core.memory; -else import core.stdc.stdlib : alloca; - -import std.stdio; - -// TODO: remove dependencies on these -Expression isExpression(Object o) -{ - return cast(Expression)o; -} - -Dsymbol isDsymbol(Object o) -{ - return cast(Dsymbol)o; -} - -Type isType(Object o) -{ - return cast(Type)o; -} - -/*********************** - * Try to get arg as a type. - */ - -Type getType(Object o) -{ - Type t = isType(o); - if (!t) - { Expression e = isExpression(o); - if (e) - t = e.type; - } - return t; -} - - -Dsymbol getDsymbol(Object oarg) -{ - Dsymbol sa; - Expression ea = isExpression(oarg); - if (ea) - { // Try to convert Expression to symbol - if (ea.op == TOK.TOKvar) - sa = (cast(VarExp)ea).var; - else if (ea.op == TOK.TOKfunction) - sa = (cast(FuncExp)ea).fd; - else - sa = null; - } - else - { // Try to convert Type to symbol - Type ta = isType(oarg); - if (ta) - sa = ta.toDsymbol(null); - else - sa = isDsymbol(oarg); // if already a symbol - } - return sa; -} - -alias Vector!Dsymbol Dsymbols; - -import dmd.TObject; - -class Dsymbol : TObject -{ - Identifier ident; - Identifier c_ident; - Dsymbol parent; - Symbol* csym; // symbol for code generator - Symbol* isym; // import version of csym - string comment; // documentation comment for this Dsymbol - Loc loc; // where defined - Scope scope_; // !=null means context to use for semantic() - - this() - { - register(); - // do nothing - } - - this(Identifier ident) - { - register(); - this.ident = ident; - } - - string toChars() - { - return ident ? ident.toChars() : "__anonymous"; - } - - string locToChars() - { - scope OutBuffer buf = new OutBuffer(); - Module m = getModule(); - - if (m && m.srcfile) - loc.filename = m.srcfile.toChars(); - - return loc.toChars(); - } - - bool equals(Object o) - { - Dsymbol s; - - if (this is o) - return true; - - s = cast(Dsymbol)(o); - if (s && ident.equals(s.ident)) - return true; - - return false; - } - - bool isAnonymous() - { - return ident ? 0 : 1; - } - - void error(T...)(Loc loc, string format, T t) - { - if (!global.gag) - { - string p = loc.toChars(); - if (p.length == 0) - p = locToChars(); - - if (p.length != 0) { - writef("%s: ", p); - } - - write("Error: "); - writef("%s %s ", kind(), toPrettyChars()); - - writefln(format, t); - } - - global.errors++; - - //fatal(); - } - - void error(T...)(string format, T t) - { - //printf("Dsymbol.error()\n"); - if (!global.gag) - { - string p = loc.toChars(); - - if (p.length != 0) { - writef("%s: ", p); - } - - write("Error: "); - if (isAnonymous()) { - writef("%s ", kind()); - } else { - writef("%s %s ", kind(), toPrettyChars()); - } - - writefln(format, t); - } - global.errors++; - - //fatal(); - } - - void checkDeprecated(Loc loc, Scope sc) - { - if (!global.params.useDeprecated && isDeprecated()) - { - // Don't complain if we're inside a deprecated symbol's scope - for (Dsymbol sp = sc.parent; sp; sp = sp.parent) - { - if (sp.isDeprecated()) - goto L1; - } - - for (; sc; sc = sc.enclosing) - { - if (sc.scopesym && sc.scopesym.isDeprecated()) - goto L1; - - // If inside a StorageClassDeclaration that is deprecated - if (sc.stc & STC.STCdeprecated) - goto L1; - } - - error(loc, "is deprecated"); - } - - L1: - Declaration d = isDeclaration(); - if (d && d.storage_class & STCdisable) - { - if (!(sc.func && sc.func.storage_class & STCdisable)) - { - if (d.ident == Id.cpctor && d.toParent()) - d.toParent().error(loc, "is not copyable"); - else - error(loc, "is not callable"); - } - } - } - - Module getModule() - { - //printf("Dsymbol.getModule()\n"); - Dsymbol s = this; - while (s) - { - //printf("\ts = '%s'\n", s.toChars()); - Module m = s.isModule(); - if (m) - return m; - s = s.parent; - } - - return null; - } - - Dsymbol pastMixin() - { - Dsymbol s = this; - //printf("Dsymbol::pastMixin() %s\n", toChars()); - while (s && s.isTemplateMixin()) - s = s.parent; - return s; - } - - Dsymbol toParent() - { - return parent ? parent.pastMixin() : null; - } - - /********************************** - * Use this instead of toParent() when looking for the - * 'this' pointer of the enclosing function/class. - */ - Dsymbol toParent2() - { - Dsymbol s = parent; - while (s && s.isTemplateInstance()) - s = s.parent; - return s; - } - - TemplateInstance inTemplateInstance() - { - for (Dsymbol parent = this.parent; parent; parent = parent.parent) - { - TemplateInstance ti = parent.isTemplateInstance(); - if (ti) - return ti; - } - - return null; - } - - DYNCAST dyncast() { return DYNCAST.DYNCAST_DSYMBOL; } // kludge for template.isSymbol() - - /************************************* - * Do syntax copy of an array of Dsymbol's. - */ - static Vector!Dsymbol arraySyntaxCopy(Vector!Dsymbol a) - { - Vector!Dsymbol b = null; - if (a) - { - b = a.copy(); - for (int i = 0; i < b.dim; i++) - { - auto s = b[i]; - - s = s.syntaxCopy(null); - b[i] = s; - } - } - return b; - } - - string toPrettyChars() - { - //printf("Dsymbol.toPrettyChars() '%s'\n", toChars()); - if (!parent) { - return toChars(); - } - - size_t len = 0; - for (Dsymbol p = this; p; p = p.parent) { - len += p.toChars().length + 1; - } - --len; - -version (Bug4054) - char* s = cast(char*)GC.malloc(len); -else - char* s = cast(char*)alloca(len); - char* q = s + len; - - for (Dsymbol p = this; p; p = p.parent) - { - string t = p.toChars(); - size_t length = t.length; - q -= length; - - memcpy(q, t.ptr, length); - if (q is s) - break; - - q--; - version (TARGET_NET) { - if (AggregateDeclaration ad = p.isAggregateDeclaration()) - { - if (ad.isNested() && p.parent && p.parent.isAggregateDeclaration()) - { - *q = '/'; - continue; - } - } - } - *q = '.'; - } - - return s[0..len].idup; - } - - string kind() - { - assert(false); - } - - /********************************* - * If this symbol is really an alias for another, - * return that other. - */ - Dsymbol toAlias() // resolve real symbol - { - return this; - } - - bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) - { - //printf("Dsymbol.addMember('%s')\n", toChars()); - //printf("Dsymbol.addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd.toChars()); - assert(sd !is null); - parent = sd; - if (!isAnonymous()) // no name, so can't add it to symbol table - { - if (!sd.symtabInsert(this)) // if name is already defined - { - Dsymbol s2 = sd.symtab.lookup(ident); - if (!s2.overloadInsert(this)) - { - sd.multiplyDefined(Loc(0), this, s2); - } - } - if (sd.isAggregateDeclaration() || sd.isEnumDeclaration()) - { - if (ident is Id.__sizeof || ident is Id.alignof_ || ident is Id.mangleof_) - error(".%s property cannot be redefined", ident.toChars()); - } - return true; - } - - return false; - } - - void setScope(Scope sc) - { - //printf("Dsymbol.setScope() %p %s\n", this, toChars()); - if (!sc.nofree) - sc.setNoFree(); // may need it even after semantic() finishes - scope_ = sc; - } - - void importAll(Scope sc) - { - } - - void semantic(Scope sc) - { - error("%p has no semantic routine", this); - } - - /************************************* - * Does semantic analysis on initializers and members of aggregates. - */ - void semantic2(Scope sc) - { - // Most Dsymbols have no further semantic analysis needed - } - - /************************************* - * Does semantic analysis on function bodies. - */ - void semantic3(Scope sc) - { - // Most Dsymbols have no further semantic analysis needed - } - - /************************************* - * Look for function inlining possibilities. - */ - void inlineScan() - { - // Most Dsymbols aren't functions - } - - /********************************************* - * Search for ident as member of s. - * Input: - * flags: 1 don't find private members - * 2 don't give error messages - * 4 return null if ambiguous - * Returns: - * null if not found - */ - Dsymbol search(Loc loc, Identifier ident, int flags) - { - //printf("Dsymbol.search(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars()); - return null; - } - - /*************************************** - * Search for identifier id as a member of 'this'. - * id may be a template instance. - * Returns: - * symbol found, null if not - */ - Dsymbol searchX(Loc loc, Scope sc, Object o) - { - //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars()); - Dsymbol s = toAlias(); - Dsymbol sm; - - if (auto ident = cast(Identifier)o) - { - sm = s.search(loc, ident, 0); - } - else if (auto st = cast(Dsymbol)o) - { - // It's a template instance - //printf("\ttemplate instance id\n"); - TemplateInstance ti = st.isTemplateInstance(); - Identifier id = ti.name; - sm = s.search(loc, cast(Identifier)id, 0); - if (!sm) - { - error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.toChars()); - return null; - } - sm = sm.toAlias(); - TemplateDeclaration td = sm.isTemplateDeclaration(); - if (!td) - { - error("%s is not a template, it is a %s", id.toChars(), sm.kind()); - return null; - } - - ti.tempdecl = td; - if (!ti.semanticRun) - ti.semantic(sc); - - sm = ti.toAlias(); - } - else - { - assert(0); - } - return sm; - } - - bool overloadInsert(Dsymbol s) - { - assert(false); - } - -version (_DH) -{ - char* toHChars() - { - assert(false); - } - - void toHBuffer(OutBuffer buf, HdrGenState* hgs) - { - assert(false); - } -} - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - assert(false); - } - - void toDocBuffer(OutBuffer buf) - { - assert(false); - } - - void toJsonBuffer(OutBuffer buf) - { - } - - uint size(Loc loc) - { - assert(false); - } - - int isforwardRef() - { - assert(false); - } - - void defineRef(Dsymbol s) - { - assert(false); - } - - AggregateDeclaration isThis() // is a 'this' required to access the member - { - return null; - } - - ClassDeclaration isClassMember() // are we a member of a class? - { - Dsymbol parent = toParent(); - if (parent && parent.isClassDeclaration()) - return cast(ClassDeclaration)parent; - return null; - } - - bool isExport() // is Dsymbol exported? - { - return false; - } - - bool isImportedSymbol() // is Dsymbol imported? - { - return false; - } - - bool isDeprecated() // is Dsymbol deprecated? - { - return false; - } - -version (DMDV2) { - bool isOverloadable() - { - return false; - } -} - - LabelDsymbol isLabel() // is this a LabelDsymbol? - { - return null; - } - - AggregateDeclaration isMember() // is this symbol a member of an AggregateDeclaration? - { - //printf("Dsymbol::isMember() %s\n", toChars()); - Dsymbol parent = toParent(); - //printf("parent is %s %s\n", parent.kind(), parent.toChars()); - return parent ? parent.isAggregateDeclaration() : null; - } - - Type getType() // is this a type? - { - return null; - } - - string mangle() - { - OutBuffer buf = new OutBuffer(); - string id; - -static if (false) { - printf("Dsymbol::mangle() '%s'", toChars()); - if (parent) - printf(" parent = %s %s", parent.kind(), parent.toChars()); - printf("\n"); -} - id = ident ? ident.toChars() : toChars(); - if (parent) - { - string p = parent.mangle(); - if (p[0] == '_' && p[1] == 'D') - p = p[2..$]; - buf.writestring(p); - } - ///buf.printf("%zu%s", id.length, id); - buf.printf("%d%s", id.length, id); - id = buf.toChars(); - buf.data = null; - //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); - return id; - } - - bool needThis() // need a 'this' pointer? - { - return false; - } - - PROT prot() - { - assert(false); - } - - Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees - { - assert(false); - } - - /************************************** - * Determine if this symbol is only one. - * Returns: - * false, *ps = null: There are 2 or more symbols - * true, *ps = null: There are zero symbols - * true, *ps = symbol: The one and only one symbol - */ - bool oneMember(Dsymbol* ps) - { - //printf("Dsymbol::oneMember()\n"); - *ps = this; - return true; - } - - /***************************************** - * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. - */ - static bool oneMembers(Dsymbols members, Dsymbol* ps) - { - //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); - Dsymbol s = null; - - if (members) - { - foreach(sx; members) - { - bool x = sx.oneMember(ps); - //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); - if (!x) - { - //printf("\tfalse 1\n"); - assert(*ps is null); - return false; - } - if (*ps) - { - if (s) // more than one symbol - { - *ps = null; - //printf("\tfalse 2\n"); - return false; - } - s = *ps; - } - } - } - - *ps = s; // s is the one symbol, null if none - //printf("\ttrue\n"); - return true; - } - - /***************************************** - * Is Dsymbol a variable that contains pointers? - */ - bool hasPointers() - { - //printf("Dsymbol::hasPointers() %s\n", toChars()); - return 0; - } - - void addLocalClass(ClassDeclarations) { } - void checkCtorConstInit() { } - - // since comment is stored immutable string is correct here - void addComment(string comment) - { - //if (comment) - //writef("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); - - if (this.comment is null) - { - this.comment = comment; - } - else - { -static if (true) -{ - if (comment !is null && comment != this.comment) - { // Concatenate the two - this.comment = Lexer.combineComments(this.comment, comment); - } -} - } - } - - void emitComment(Scope sc) - { - assert(false); - } - - void emitDitto(Scope sc) - { - assert(false); - } - - // Backend - - Symbol* toSymbol() // to backend symbol - { - assert(false); - } - - void toObjFile(int multiobj) // compile to .obj file - { - //printf("Dsymbol::toObjFile('%s')\n", toChars()); - // ignore - } - - int cvMember(ubyte* p) // emit cv debug info for member - { - assert(false); - } - - /********************************* - * Generate import symbol from symbol. - */ - Symbol* toImport() // to backend import symbol - { - if (!isym) - { - if (!csym) - csym = toSymbol(); - isym = toImport(csym); - } - - return isym; - } - - static Symbol* toImport(Symbol* sym) // to backend import symbol - { - char* id; - char* n; - Symbol* s; - type* t; - - //printf("Dsymbol::toImport('%s')\n", sym->Sident); - n = sym.Sident.ptr; -version (Bug4054) - id = cast(char*) GC.malloc(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1); -else - id = cast(char*) alloca(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1); - if (sym.Stype.Tmangle == mTYman_std && tyfunc(sym.Stype.Tty)) - { - sprintf(id, "_imp__%s@%lu", n, type_paramsize_i(sym.Stype)); - } - else if (sym.Stype.Tmangle == mTYman_d) - sprintf(id,"_imp_%s",n); - else - sprintf(id,"_imp__%s",n); - t = type_alloc(TYnptr | mTYconst); - t.Tnext = sym.Stype; - t.Tnext.Tcount++; - t.Tmangle = mTYman_c; - t.Tcount++; - s = symbol_calloc(id); - s.Stype = t; - s.Sclass = SCextern; - s.Sfl = FLextern; - slist_add(s); - - return s; - } - - Symbol* toSymbolX(string prefix, int sclass, TYPE* t, string suffix) // helper - { - Symbol* s; - char* id; - string n; - size_t nlen; - - //writef("Dsymbol::toSymbolX('%s', '%s')\n", prefix, this.classinfo.name); - n = mangle(); - assert(n.length != 0); - - nlen = n.length; -static if (false) { - if (nlen > 2 && n[0] == '_' && n[1] == 'D') - { - nlen -= 2; - n += 2; - } -} - version (Bug4054) - id = cast(char*) GC.malloc(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1); - else - id = cast(char*) alloca(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1); - sprintf(id, "_D%.*s%zu%.*s%.*s", n, prefix.length, prefix, suffix); - - static if (false) { - if (global.params.isWindows && (type_mangle(t) == mTYman.mTYman_c || type_mangle(t) == mTYman.mTYman_std)) - id++; // Windows C mangling will put the '_' back in - } - s = symbol_name(id, sclass, t); - - //printf("-Dsymbol::toSymbolX() %s\n", id); - return s; - } - - // Eliminate need for dynamic_cast - Package isPackage() { return null; } - Module isModule() { return null; } - EnumMember isEnumMember() { return null; } - TemplateDeclaration isTemplateDeclaration() { return null; } - TemplateInstance isTemplateInstance() { return null; } - TemplateMixin isTemplateMixin() { return null; } - Declaration isDeclaration() { return null; } - ThisDeclaration isThisDeclaration() { return null; } - TupleDeclaration isTupleDeclaration() { return null; } - TypedefDeclaration isTypedefDeclaration() { return null; } - AliasDeclaration isAliasDeclaration() { return null; } - AggregateDeclaration isAggregateDeclaration() { return null; } - FuncDeclaration isFuncDeclaration() { return null; } - FuncAliasDeclaration isFuncAliasDeclaration() { return null; } - FuncLiteralDeclaration isFuncLiteralDeclaration() { return null; } - CtorDeclaration isCtorDeclaration() { return null; } - PostBlitDeclaration isPostBlitDeclaration() { return null; } - DtorDeclaration isDtorDeclaration() { return null; } - StaticCtorDeclaration isStaticCtorDeclaration() { return null; } - StaticDtorDeclaration isStaticDtorDeclaration() { return null; } - SharedStaticCtorDeclaration isSharedStaticCtorDeclaration() { return null; } - SharedStaticDtorDeclaration isSharedStaticDtorDeclaration() { return null; } - InvariantDeclaration isInvariantDeclaration() { return null; } - UnitTestDeclaration isUnitTestDeclaration() { return null; } - NewDeclaration isNewDeclaration() { return null; } - VarDeclaration isVarDeclaration() { return null; } - ClassDeclaration isClassDeclaration() { return null; } - StructDeclaration isStructDeclaration() { return null; } - UnionDeclaration isUnionDeclaration() { return null; } - InterfaceDeclaration isInterfaceDeclaration() { return null; } - ScopeDsymbol isScopeDsymbol() { return null; } - WithScopeSymbol isWithScopeSymbol() { return null; } - ArrayScopeSymbol isArrayScopeSymbol() { return null; } - Import isImport() { return null; } - EnumDeclaration isEnumDeclaration() { return null; } -version (_DH) -{ - DeleteDeclaration isDeleteDeclaration() { return null; } -} - SymbolDeclaration isSymbolDeclaration() { return null; } - AttribDeclaration isAttribDeclaration() { return null; } - OverloadSet isOverloadSet() { return null; } -version (TARGET_NET) -{ - PragmaScope isPragmaScope() { return null; } -} +module dmd.Dsymbol; + +import dmd.common; +import dmd.Loc; +import dmd.STC; +import dmd.Scope; +import dmd.Lexer; +import dmd.Module; +import dmd.Array; +import dmd.ScopeDsymbol; +import dmd.OutBuffer; +import dmd.Id; +import dmd.Identifier; +import dmd.TemplateInstance; +import dmd.SharedStaticCtorDeclaration; +import dmd.SharedStaticDtorDeclaration; +import dmd.HdrGenState; +import dmd.AggregateDeclaration; +import dmd.ClassDeclaration; +import dmd.LabelDsymbol; +import dmd.Type; +import dmd.PROT; +import dmd.ArrayTypes; +import dmd.Package; +import dmd.EnumMember; +import dmd.TemplateDeclaration; +import dmd.TemplateMixin; +import dmd.Declaration; +import dmd.ThisDeclaration; +import dmd.TupleDeclaration; +import dmd.TypedefDeclaration; +import dmd.AliasDeclaration; +import dmd.FuncDeclaration; +import dmd.FuncAliasDeclaration; +import dmd.FuncLiteralDeclaration; +import dmd.CtorDeclaration; +import dmd.PostBlitDeclaration; +import dmd.DtorDeclaration; +import dmd.StaticCtorDeclaration; +import dmd.StaticDtorDeclaration; +import dmd.InvariantDeclaration; +import dmd.UnitTestDeclaration; +import dmd.NewDeclaration; +import dmd.VarDeclaration; +import dmd.StructDeclaration; +import dmd.UnionDeclaration; +import dmd.InterfaceDeclaration; +import dmd.WithScopeSymbol; +import dmd.ArrayScopeSymbol; +import dmd.Import; +import dmd.EnumDeclaration; +import dmd.DeleteDeclaration; +import dmd.SymbolDeclaration; +import dmd.AttribDeclaration; +import dmd.OverloadSet; +import dmd.DYNCAST; +import dmd.Global; +import dmd.Expression; +import dmd.TOK; +import dmd.VarExp; +import dmd.FuncExp; + +import dmd.backend.Symbol; +import dmd.backend.TYPE; +import dmd.backend.Util; +import dmd.backend.mTYman; +import dmd.backend.TYFL; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.SC; +import dmd.backend.FL; +import dmd.backend.LIST; +public import dmd.PASS; + +import dmd.DDMDExtensions; + +import core.stdc.string : strcmp, memcpy, strlen; +version (Bug4054) import core.memory; +else import core.stdc.stdlib : alloca; + +import std.stdio; + +// TODO: remove dependencies on these +Expression isExpression(Object o) +{ + return cast(Expression)o; +} + +Dsymbol isDsymbol(Object o) +{ + return cast(Dsymbol)o; +} + +Type isType(Object o) +{ + return cast(Type)o; +} + +/*********************** + * Try to get arg as a type. + */ + +Type getType(Object o) +{ + Type t = isType(o); + if (!t) + { Expression e = isExpression(o); + if (e) + t = e.type; + } + return t; +} + + +Dsymbol getDsymbol(Object oarg) +{ + Dsymbol sa; + Expression ea = isExpression(oarg); + if (ea) + { // Try to convert Expression to symbol + if (ea.op == TOK.TOKvar) + sa = (cast(VarExp)ea).var; + else if (ea.op == TOK.TOKfunction) + sa = (cast(FuncExp)ea).fd; + else + sa = null; + } + else + { // Try to convert Type to symbol + Type ta = isType(oarg); + if (ta) + sa = ta.toDsymbol(null); + else + sa = isDsymbol(oarg); // if already a symbol + } + return sa; +} + +alias Vector!Dsymbol Dsymbols; + +import dmd.TObject; + +class Dsymbol : TObject +{ + mixin insertMemberExtension!(typeof(this)); + + Identifier ident; + Identifier c_ident; + Dsymbol parent; + Symbol* csym; // symbol for code generator + Symbol* isym; // import version of csym + string comment; // documentation comment for this Dsymbol + Loc loc; // where defined + Scope scope_; // !=null means context to use for semantic() + + this() + { + register(); + // do nothing + } + + this(Identifier ident) + { + register(); + this.ident = ident; + } + + string toChars() + { + return ident ? ident.toChars() : "__anonymous"; + } + + string locToChars() + { + scope OutBuffer buf = new OutBuffer(); + Module m = getModule(); + + if (m && m.srcfile) + loc.filename = m.srcfile.toChars(); + + return loc.toChars(); + } + + bool equals(Object o) + { + Dsymbol s; + + if (this is o) + return true; + + s = cast(Dsymbol)(o); + if (s && ident.equals(s.ident)) + return true; + + return false; + } + + bool isAnonymous() + { + return ident ? 0 : 1; + } + + void error(T...)(Loc loc, string format, T t) + { + if (!global.gag) + { + string p = loc.toChars(); + if (p.length == 0) + p = locToChars(); + + if (p.length != 0) { + writef("%s: ", p); + } + + write("Error: "); + writef("%s %s ", kind(), toPrettyChars()); + + writefln(format, t); + } + + global.errors++; + + //fatal(); + } + + void error(T...)(string format, T t) + { + //printf("Dsymbol.error()\n"); + if (!global.gag) + { + string p = loc.toChars(); + + if (p.length != 0) { + writef("%s: ", p); + } + + write("Error: "); + if (isAnonymous()) { + writef("%s ", kind()); + } else { + writef("%s %s ", kind(), toPrettyChars()); + } + + writefln(format, t); + } + global.errors++; + + //fatal(); + } + + void checkDeprecated(Loc loc, Scope sc) + { + if (!global.params.useDeprecated && isDeprecated()) + { + // Don't complain if we're inside a deprecated symbol's scope + for (Dsymbol sp = sc.parent; sp; sp = sp.parent) + { + if (sp.isDeprecated()) + goto L1; + } + + for (; sc; sc = sc.enclosing) + { + if (sc.scopesym && sc.scopesym.isDeprecated()) + goto L1; + + // If inside a StorageClassDeclaration that is deprecated + if (sc.stc & STC.STCdeprecated) + goto L1; + } + + error(loc, "is deprecated"); + } + + L1: + Declaration d = isDeclaration(); + if (d && d.storage_class & STCdisable) + { + if (!(sc.func && sc.func.storage_class & STCdisable)) + { + if (d.ident == Id.cpctor && d.toParent()) + d.toParent().error(loc, "is not copyable"); + else + error(loc, "is not callable"); + } + } + } + + Module getModule() + { + //printf("Dsymbol.getModule()\n"); + Dsymbol s = this; + while (s) + { + //printf("\ts = '%s'\n", s.toChars()); + Module m = s.isModule(); + if (m) + return m; + s = s.parent; + } + + return null; + } + + Dsymbol pastMixin() + { + Dsymbol s = this; + //printf("Dsymbol::pastMixin() %s\n", toChars()); + while (s && s.isTemplateMixin()) + s = s.parent; + return s; + } + + Dsymbol toParent() + { + return parent ? parent.pastMixin() : null; + } + + /********************************** + * Use this instead of toParent() when looking for the + * 'this' pointer of the enclosing function/class. + */ + Dsymbol toParent2() + { + Dsymbol s = parent; + while (s && s.isTemplateInstance()) + s = s.parent; + return s; + } + + TemplateInstance inTemplateInstance() + { + for (Dsymbol parent = this.parent; parent; parent = parent.parent) + { + TemplateInstance ti = parent.isTemplateInstance(); + if (ti) + return ti; + } + + return null; + } + + DYNCAST dyncast() { return DYNCAST.DYNCAST_DSYMBOL; } // kludge for template.isSymbol() + + /************************************* + * Do syntax copy of an array of Dsymbol's. + */ + static Vector!Dsymbol arraySyntaxCopy(Vector!Dsymbol a) + { + Vector!Dsymbol b = null; + if (a) + { + b = a.copy(); + for (int i = 0; i < b.dim; i++) + { + auto s = b[i]; + + s = s.syntaxCopy(null); + b[i] = s; + } + } + return b; + } + + string toPrettyChars() + { + //printf("Dsymbol.toPrettyChars() '%s'\n", toChars()); + if (!parent) { + return toChars(); + } + + size_t len = 0; + for (Dsymbol p = this; p; p = p.parent) { + len += p.toChars().length + 1; + } + --len; + +version (Bug4054) + char* s = cast(char*)GC.malloc(len); +else + char* s = cast(char*)alloca(len); + char* q = s + len; + + for (Dsymbol p = this; p; p = p.parent) + { + string t = p.toChars(); + size_t length = t.length; + q -= length; + + memcpy(q, t.ptr, length); + if (q is s) + break; + + q--; + version (TARGET_NET) { + if (AggregateDeclaration ad = p.isAggregateDeclaration()) + { + if (ad.isNested() && p.parent && p.parent.isAggregateDeclaration()) + { + *q = '/'; + continue; + } + } + } + *q = '.'; + } + + return s[0..len].idup; + } + + string kind() + { + assert(false); + } + + /********************************* + * If this symbol is really an alias for another, + * return that other. + */ + Dsymbol toAlias() // resolve real symbol + { + return this; + } + + bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + { + //printf("Dsymbol.addMember('%s')\n", toChars()); + //printf("Dsymbol.addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd.toChars()); + assert(sd !is null); + parent = sd; + if (!isAnonymous()) // no name, so can't add it to symbol table + { + if (!sd.symtabInsert(this)) // if name is already defined + { + Dsymbol s2 = sd.symtab.lookup(ident); + if (!s2.overloadInsert(this)) + { + sd.multiplyDefined(Loc(0), this, s2); + } + } + if (sd.isAggregateDeclaration() || sd.isEnumDeclaration()) + { + if (ident is Id.__sizeof || ident is Id.alignof_ || ident is Id.mangleof_) + error(".%s property cannot be redefined", ident.toChars()); + } + return true; + } + + return false; + } + + void setScope(Scope sc) + { + //printf("Dsymbol.setScope() %p %s\n", this, toChars()); + if (!sc.nofree) + sc.setNoFree(); // may need it even after semantic() finishes + scope_ = sc; + } + + void importAll(Scope sc) + { + } + + void semantic(Scope sc) + { + error("%p has no semantic routine", this); + } + + /************************************* + * Does semantic analysis on initializers and members of aggregates. + */ + void semantic2(Scope sc) + { + // Most Dsymbols have no further semantic analysis needed + } + + /************************************* + * Does semantic analysis on function bodies. + */ + void semantic3(Scope sc) + { + // Most Dsymbols have no further semantic analysis needed + } + + /************************************* + * Look for function inlining possibilities. + */ + void inlineScan() + { + // Most Dsymbols aren't functions + } + + /********************************************* + * Search for ident as member of s. + * Input: + * flags: 1 don't find private members + * 2 don't give error messages + * 4 return null if ambiguous + * Returns: + * null if not found + */ + Dsymbol search(Loc loc, Identifier ident, int flags) + { + //printf("Dsymbol.search(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars()); + return null; + } + + /*************************************** + * Search for identifier id as a member of 'this'. + * id may be a template instance. + * Returns: + * symbol found, null if not + */ + Dsymbol searchX(Loc loc, Scope sc, Object o) + { + //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars()); + Dsymbol s = toAlias(); + Dsymbol sm; + + if (auto ident = cast(Identifier)o) + { + sm = s.search(loc, ident, 0); + } + else if (auto st = cast(Dsymbol)o) + { + // It's a template instance + //printf("\ttemplate instance id\n"); + TemplateInstance ti = st.isTemplateInstance(); + Identifier id = ti.name; + sm = s.search(loc, cast(Identifier)id, 0); + if (!sm) + { + error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.toChars()); + return null; + } + sm = sm.toAlias(); + TemplateDeclaration td = sm.isTemplateDeclaration(); + if (!td) + { + error("%s is not a template, it is a %s", id.toChars(), sm.kind()); + return null; + } + + ti.tempdecl = td; + if (!ti.semanticRun) + ti.semantic(sc); + + sm = ti.toAlias(); + } + else + { + assert(0); + } + return sm; + } + + bool overloadInsert(Dsymbol s) + { + assert(false); + } + +version (_DH) +{ + char* toHChars() + { + assert(false); + } + + void toHBuffer(OutBuffer buf, HdrGenState* hgs) + { + assert(false); + } +} + void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + assert(false); + } + + void toDocBuffer(OutBuffer buf) + { + assert(false); + } + + void toJsonBuffer(OutBuffer buf) + { + } + + uint size(Loc loc) + { + assert(false); + } + + int isforwardRef() + { + assert(false); + } + + void defineRef(Dsymbol s) + { + assert(false); + } + + AggregateDeclaration isThis() // is a 'this' required to access the member + { + return null; + } + + ClassDeclaration isClassMember() // are we a member of a class? + { + Dsymbol parent = toParent(); + if (parent && parent.isClassDeclaration()) + return cast(ClassDeclaration)parent; + return null; + } + + bool isExport() // is Dsymbol exported? + { + return false; + } + + bool isImportedSymbol() // is Dsymbol imported? + { + return false; + } + + bool isDeprecated() // is Dsymbol deprecated? + { + return false; + } + +version (DMDV2) { + bool isOverloadable() + { + return false; + } +} + + LabelDsymbol isLabel() // is this a LabelDsymbol? + { + return null; + } + + AggregateDeclaration isMember() // is this symbol a member of an AggregateDeclaration? + { + //printf("Dsymbol::isMember() %s\n", toChars()); + Dsymbol parent = toParent(); + //printf("parent is %s %s\n", parent.kind(), parent.toChars()); + return parent ? parent.isAggregateDeclaration() : null; + } + + Type getType() // is this a type? + { + return null; + } + + string mangle() + { + OutBuffer buf = new OutBuffer(); + string id; + +static if (false) { + printf("Dsymbol::mangle() '%s'", toChars()); + if (parent) + printf(" parent = %s %s", parent.kind(), parent.toChars()); + printf("\n"); +} + id = ident ? ident.toChars() : toChars(); + if (parent) + { + string p = parent.mangle(); + if (p[0] == '_' && p[1] == 'D') + p = p[2..$]; + buf.writestring(p); + } + ///buf.printf("%zu%s", id.length, id); + buf.printf("%d%s", id.length, id); + id = buf.toChars(); + buf.data = null; + //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); + return id; + } + + bool needThis() // need a 'this' pointer? + { + return false; + } + + PROT prot() + { + assert(false); + } + + Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees + { + assert(false); + } + + /************************************** + * Determine if this symbol is only one. + * Returns: + * false, *ps = null: There are 2 or more symbols + * true, *ps = null: There are zero symbols + * true, *ps = symbol: The one and only one symbol + */ + bool oneMember(Dsymbol* ps) + { + //printf("Dsymbol::oneMember()\n"); + *ps = this; + return true; + } + + /***************************************** + * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. + */ + static bool oneMembers(Dsymbols members, Dsymbol* ps) + { + //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); + Dsymbol s = null; + + if (members) + { + foreach(sx; members) + { + bool x = sx.oneMember(ps); + //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); + if (!x) + { + //printf("\tfalse 1\n"); + assert(*ps is null); + return false; + } + if (*ps) + { + if (s) // more than one symbol + { + *ps = null; + //printf("\tfalse 2\n"); + return false; + } + s = *ps; + } + } + } + + *ps = s; // s is the one symbol, null if none + //printf("\ttrue\n"); + return true; + } + + /***************************************** + * Is Dsymbol a variable that contains pointers? + */ + bool hasPointers() + { + //printf("Dsymbol::hasPointers() %s\n", toChars()); + return 0; + } + + void addLocalClass(ClassDeclarations) { } + void checkCtorConstInit() { } + + // since comment is stored immutable string is correct here + void addComment(string comment) + { + //if (comment) + //writef("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); + + if (this.comment is null) + { + this.comment = comment; + } + else + { +static if (true) +{ + if (comment !is null && comment != this.comment) + { // Concatenate the two + this.comment = Lexer.combineComments(this.comment, comment); + } +} + } + } + + void emitComment(Scope sc) + { + assert(false); + } + + void emitDitto(Scope sc) + { + assert(false); + } + + // Backend + + Symbol* toSymbol() // to backend symbol + { + assert(false); + } + + void toObjFile(int multiobj) // compile to .obj file + { + //printf("Dsymbol::toObjFile('%s')\n", toChars()); + // ignore + } + + int cvMember(ubyte* p) // emit cv debug info for member + { + assert(false); + } + + /********************************* + * Generate import symbol from symbol. + */ + Symbol* toImport() // to backend import symbol + { + if (!isym) + { + if (!csym) + csym = toSymbol(); + isym = toImport(csym); + } + + return isym; + } + + static Symbol* toImport(Symbol* sym) // to backend import symbol + { + char* id; + char* n; + Symbol* s; + type* t; + + //printf("Dsymbol::toImport('%s')\n", sym->Sident); + n = sym.Sident.ptr; +version (Bug4054) + id = cast(char*) GC.malloc(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1); +else + id = cast(char*) alloca(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1); + if (sym.Stype.Tmangle == mTYman_std && tyfunc(sym.Stype.Tty)) + { + sprintf(id, "_imp__%s@%lu", n, type_paramsize_i(sym.Stype)); + } + else if (sym.Stype.Tmangle == mTYman_d) + sprintf(id,"_imp_%s",n); + else + sprintf(id,"_imp__%s",n); + t = type_alloc(TYnptr | mTYconst); + t.Tnext = sym.Stype; + t.Tnext.Tcount++; + t.Tmangle = mTYman_c; + t.Tcount++; + s = symbol_calloc(id); + s.Stype = t; + s.Sclass = SCextern; + s.Sfl = FLextern; + slist_add(s); + + return s; + } + + Symbol* toSymbolX(string prefix, int sclass, TYPE* t, string suffix) // helper + { + Symbol* s; + char* id; + string n; + size_t nlen; + + //writef("Dsymbol::toSymbolX('%s', '%s')\n", prefix, this.classinfo.name); + n = mangle(); + assert(n.length != 0); + + nlen = n.length; +static if (false) { + if (nlen > 2 && n[0] == '_' && n[1] == 'D') + { + nlen -= 2; + n += 2; + } +} + version (Bug4054) + id = cast(char*) GC.malloc(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1); + else + id = cast(char*) alloca(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1); + sprintf(id, "_D%.*s%zu%.*s%.*s", n, prefix.length, prefix, suffix); + + static if (false) { + if (global.params.isWindows && (type_mangle(t) == mTYman.mTYman_c || type_mangle(t) == mTYman.mTYman_std)) + id++; // Windows C mangling will put the '_' back in + } + s = symbol_name(id, sclass, t); + + //printf("-Dsymbol::toSymbolX() %s\n", id); + return s; + } + + // Eliminate need for dynamic_cast + Package isPackage() { return null; } + Module isModule() { return null; } + EnumMember isEnumMember() { return null; } + TemplateDeclaration isTemplateDeclaration() { return null; } + TemplateInstance isTemplateInstance() { return null; } + TemplateMixin isTemplateMixin() { return null; } + Declaration isDeclaration() { return null; } + ThisDeclaration isThisDeclaration() { return null; } + TupleDeclaration isTupleDeclaration() { return null; } + TypedefDeclaration isTypedefDeclaration() { return null; } + AliasDeclaration isAliasDeclaration() { return null; } + AggregateDeclaration isAggregateDeclaration() { return null; } + FuncDeclaration isFuncDeclaration() { return null; } + FuncAliasDeclaration isFuncAliasDeclaration() { return null; } + FuncLiteralDeclaration isFuncLiteralDeclaration() { return null; } + CtorDeclaration isCtorDeclaration() { return null; } + PostBlitDeclaration isPostBlitDeclaration() { return null; } + DtorDeclaration isDtorDeclaration() { return null; } + StaticCtorDeclaration isStaticCtorDeclaration() { return null; } + StaticDtorDeclaration isStaticDtorDeclaration() { return null; } + SharedStaticCtorDeclaration isSharedStaticCtorDeclaration() { return null; } + SharedStaticDtorDeclaration isSharedStaticDtorDeclaration() { return null; } + InvariantDeclaration isInvariantDeclaration() { return null; } + UnitTestDeclaration isUnitTestDeclaration() { return null; } + NewDeclaration isNewDeclaration() { return null; } + VarDeclaration isVarDeclaration() { return null; } + ClassDeclaration isClassDeclaration() { return null; } + StructDeclaration isStructDeclaration() { return null; } + UnionDeclaration isUnionDeclaration() { return null; } + InterfaceDeclaration isInterfaceDeclaration() { return null; } + ScopeDsymbol isScopeDsymbol() { return null; } + WithScopeSymbol isWithScopeSymbol() { return null; } + ArrayScopeSymbol isArrayScopeSymbol() { return null; } + Import isImport() { return null; } + EnumDeclaration isEnumDeclaration() { return null; } +version (_DH) +{ + DeleteDeclaration isDeleteDeclaration() { return null; } +} + SymbolDeclaration isSymbolDeclaration() { return null; } + AttribDeclaration isAttribDeclaration() { return null; } + OverloadSet isOverloadSet() { return null; } +version (TARGET_NET) +{ + PragmaScope isPragmaScope() { return null; } +} } \ No newline at end of file diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DsymbolExp.d --- a/dmd/DsymbolExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DsymbolExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -36,8 +36,12 @@ import dmd.TOK; import dmd.ErrorExp; +import dmd.DDMDExtensions; + class DsymbolExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Dsymbol s; bool hasOverloads; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DsymbolTable.d --- a/dmd/DsymbolTable.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DsymbolTable.d Tue Jun 07 23:37:34 2011 -0400 @@ -1,59 +1,63 @@ -module dmd.DsymbolTable; - -import dmd.common; -import dmd.StringTable; -import dmd.Dsymbol; -import dmd.Identifier; -import dmd.StringValue; - -import std.stdio; - -import dmd.TObject; - -class DsymbolTable : TObject -{ - StringTable tab; - - this() - { - register(); - } - - // Look up Identifier. Return Dsymbol if found, NULL if not. - Dsymbol lookup(Identifier ident) - { -debug { - assert(ident); -} - Object* sv = tab.lookup(ident.string_); - return (sv ? cast(Dsymbol)*sv : null); - } - - // Insert Dsymbol in table. Return NULL if already there. - Dsymbol insert(Dsymbol s) - { - Identifier ident = s.ident; -debug { - assert(ident); -} - - return insert(ident, s); - } - - // Look for Dsymbol in table. If there, return it. If not, insert s and return that. - Dsymbol update(Dsymbol s) - { - assert(false); - } - - Dsymbol insert(Identifier ident, Dsymbol s) // when ident and s are not the same - { - Object* sv = tab.insert(ident.toChars()); - if (sv is null) { - return null; // already in table - } - - *sv = s; - return s; - } +module dmd.DsymbolTable; + +import dmd.common; +import dmd.StringTable; +import dmd.Dsymbol; +import dmd.Identifier; +import dmd.StringValue; + +import std.stdio; + +import dmd.TObject; + +import dmd.DDMDExtensions; + +class DsymbolTable : TObject +{ + mixin insertMemberExtension!(typeof(this)); + + StringTable tab; + + this() + { + register(); + } + + // Look up Identifier. Return Dsymbol if found, NULL if not. + Dsymbol lookup(Identifier ident) + { +debug { + assert(ident); } + Object* sv = tab.lookup(ident.string_); + return (sv ? cast(Dsymbol)*sv : null); + } + + // Insert Dsymbol in table. Return NULL if already there. + Dsymbol insert(Dsymbol s) + { + Identifier ident = s.ident; +debug { + assert(ident); +} + + return insert(ident, s); + } + + // Look for Dsymbol in table. If there, return it. If not, insert s and return that. + Dsymbol update(Dsymbol s) + { + assert(false); + } + + Dsymbol insert(Identifier ident, Dsymbol s) // when ident and s are not the same + { + Object* sv = tab.insert(ident.toChars()); + if (sv is null) { + return null; // already in table + } + + *sv = s; + return s; + } +} diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/DtorDeclaration.d --- a/dmd/DtorDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/DtorDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.STC; import dmd.Id; +import dmd.DDMDExtensions; + class DtorDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/EnumDeclaration.d --- a/dmd/EnumDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/EnumDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -40,8 +40,13 @@ import std.stdio : writef; +import dmd.DDMDExtensions; + class EnumDeclaration : ScopeDsymbol -{ /* enum ident : memtype { ... } +{ + mixin insertMemberExtension!(typeof(this)); + + /* enum ident : memtype { ... } */ Type type; // the TypeEnum Type memtype; // type of the members diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/EnumMember.d --- a/dmd/EnumMember.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/EnumMember.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.OutBuffer; import dmd.HdrGenState; +import dmd.DDMDExtensions; + class EnumMember : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + Expression value; Type type; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/EqualExp.d --- a/dmd/EqualExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/EqualExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -33,8 +33,12 @@ import dmd.expression.Util; import dmd.expression.Equal; +import dmd.DDMDExtensions; + class EqualExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(TOK op, Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ErrorExp.d --- a/dmd/ErrorExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ErrorExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,12 +8,16 @@ import dmd.HdrGenState; import dmd.Type; +import dmd.DDMDExtensions; + /* Use this expression for error recovery. * It should behave as a 'sink' to prevent further cascaded error messages. */ class ErrorExp : IntegerExp { + mixin insertMemberExtension!(typeof(this)); + this() { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ExpInitializer.d --- a/dmd/ExpInitializer.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ExpInitializer.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.backend.dt_t; +import dmd.DDMDExtensions; + class ExpInitializer : Initializer { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ExpStatement.d --- a/dmd/ExpStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ExpStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.Blockx; import dmd.backend.Util; +import dmd.DDMDExtensions; + class ExpStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Expression.d --- a/dmd/Expression.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Expression.d Tue Jun 07 23:37:34 2011 -0400 @@ -56,6 +56,8 @@ import dmd.backend.Util; import dmd.backend.dt_t; +import dmd.DDMDExtensions; + import core.memory; import std.stdio : writef; @@ -187,6 +189,8 @@ class Expression : TObject { + mixin insertMemberExtension!(typeof(this)); + Loc loc; // file location TOK op; // handy to minimize use of dynamic_cast Type type; // !=null means that semantic() has been run diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/FileExp.d --- a/dmd/FileExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/FileExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import core.stdc.stdio; +import dmd.DDMDExtensions; + class FileExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/FileInitExp.d --- a/dmd/FileInitExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/FileInitExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.Util; import dmd.Type; +import dmd.DDMDExtensions; + class FileInitExp : DefaultInitExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ForStatement.d --- a/dmd/ForStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ForStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.Util; import dmd.backend.BC; +import dmd.DDMDExtensions; + class ForStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement init; Expression condition; Expression increment; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ForeachRangeStatement.d --- a/dmd/ForeachRangeStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ForeachRangeStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -33,9 +33,13 @@ import dmd.Loc; import dmd.BE; +import dmd.DDMDExtensions; + version(DMDV2) class ForeachRangeStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + TOK op; // TOK.TOKforeach or TOK.TOKforeach_reverse Parameter arg; // loop index variable Expression lwr; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ForeachStatement.d --- a/dmd/ForeachStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ForeachStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -71,8 +71,12 @@ import core.stdc.stdio; +import dmd.DDMDExtensions; + class ForeachStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + TOK op; // TOKforeach or TOKforeach_reverse Parameters arguments; // array of Argument*'s Expression aggr; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/FuncAliasDeclaration.d --- a/dmd/FuncAliasDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/FuncAliasDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.Loc; import dmd.STC; +import dmd.DDMDExtensions; + class FuncAliasDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + FuncDeclaration funcalias; this(FuncDeclaration funcalias) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/FuncDeclaration.d --- a/dmd/FuncDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/FuncDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -120,6 +120,8 @@ import dmd.backend.RTLSYM; import dmd.backend.LIST; +import dmd.DDMDExtensions; + import core.stdc.stdio; import core.stdc.string; version (Bug4054) import core.memory; @@ -130,6 +132,8 @@ class FuncDeclaration : Declaration { + mixin insertMemberExtension!(typeof(this)); + Array fthrows; // Array of Type's of exceptions (not used) Statement frequire; Statement fensure; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/FuncExp.d --- a/dmd/FuncExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/FuncExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.backend.TYM; import dmd.backend.Symbol; +import dmd.DDMDExtensions; + class FuncExp : Expression { + mixin insertMemberExtension!(typeof(this)); + FuncLiteralDeclaration fd; this(Loc loc, FuncLiteralDeclaration fd) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/FuncLiteralDeclaration.d --- a/dmd/FuncLiteralDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/FuncLiteralDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -12,8 +12,12 @@ import dmd.STC; import dmd.Lexer; +import dmd.DDMDExtensions; + class FuncLiteralDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + TOK tok; // TOKfunction or TOKdelegate this(Loc loc, Loc endloc, Type type, TOK tok, ForeachStatement fes) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/GotoCaseStatement.d --- a/dmd/GotoCaseStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/GotoCaseStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.backend.BC; import dmd.backend.Blockx; +import dmd.DDMDExtensions; + class GotoCaseStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; // NULL, or which case to goto CaseStatement cs; // case statement it resolves to diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/GotoDefaultStatement.d --- a/dmd/GotoDefaultStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/GotoDefaultStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.backend.Util; import dmd.backend.BC; +import dmd.DDMDExtensions; + class GotoDefaultStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + SwitchStatement sw; this(Loc loc) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/GotoStatement.d --- a/dmd/GotoStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/GotoStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.backend.Blockx; import dmd.backend.BC; +import dmd.DDMDExtensions; + class GotoStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; LabelDsymbol label = null; TryFinallyStatement tf = null; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/HaltExp.d --- a/dmd/HaltExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/HaltExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.backend.OPER; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class HaltExp : Expression { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/IdentifierExp.d --- a/dmd/IdentifierExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/IdentifierExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -24,8 +24,12 @@ import dmd.HdrGenState; import dmd.TOK; +import dmd.DDMDExtensions; + class IdentifierExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; Declaration var; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/IdentityExp.d --- a/dmd/IdentityExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/IdentityExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.Util; import dmd.codegen.Util; +import dmd.DDMDExtensions; + class IdentityExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(TOK op, Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/IfStatement.d --- a/dmd/IfStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/IfStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -31,8 +31,12 @@ import dmd.backend.Blockx; import dmd.backend.BC; +import dmd.DDMDExtensions; + class IfStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Parameter arg; Expression condition; Statement ifbody; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Import.d --- a/dmd/Import.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Import.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,6 +21,8 @@ import dmd.ProtDeclaration; import dmd.Global; +import dmd.DDMDExtensions; + import std.stdio; void escapePath(OutBuffer buf, string fname) @@ -42,6 +44,8 @@ class Import : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + Identifiers packages; // array of Identifier's representing packages Identifier id; // module Identifier Identifier aliasId; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/InExp.d --- a/dmd/InExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/InExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.Symbol; import dmd.backend.Util; +import dmd.DDMDExtensions; + class InExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/IndexExp.d --- a/dmd/IndexExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/IndexExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -49,8 +49,12 @@ import core.stdc.string; import core.stdc.stdio; +import dmd.DDMDExtensions; + class IndexExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + VarDeclaration lengthVar; int modifiable = 0; // assume it is an rvalue diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Initializer.d --- a/dmd/Initializer.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Initializer.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class Initializer : TObject { + mixin insertMemberExtension!(typeof(this)); + Loc loc; this(Loc loc) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/IntegerExp.d --- a/dmd/IntegerExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/IntegerExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,8 +25,12 @@ import core.stdc.ctype : isprint; import std.stdio; +import dmd.DDMDExtensions; + class IntegerExp : Expression { + mixin insertMemberExtension!(typeof(this)); + ulong value; this(Loc loc, ulong value, Type type) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/InterfaceDeclaration.d --- a/dmd/InterfaceDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/InterfaceDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -32,8 +32,12 @@ import dmd.backend.LIST; import dmd.backend.SFL; +import dmd.DDMDExtensions; + class InterfaceDeclaration : ClassDeclaration { + mixin insertMemberExtension!(typeof(this)); + version (DMDV2) { bool cpp; // true if this is a C++ interface } diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/InvariantDeclaration.d --- a/dmd/InvariantDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/InvariantDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -14,8 +14,12 @@ import dmd.Type; import dmd.AggregateDeclaration; +import dmd.DDMDExtensions; + class InvariantDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/IsExp.d --- a/dmd/IsExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/IsExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -31,8 +31,12 @@ import dmd.Parameter; import dmd.Token; +import dmd.DDMDExtensions; + class IsExp : Expression { + mixin insertMemberExtension!(typeof(this)); + /* is(targ id tok tspec) * is(targ id == tok2) */ diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/LabelDsymbol.d --- a/dmd/LabelDsymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/LabelDsymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -5,8 +5,12 @@ import dmd.LabelStatement; import dmd.Identifier; +import dmd.DDMDExtensions; + class LabelDsymbol : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + LabelStatement statement; version (IN_GCC) { diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/LabelStatement.d --- a/dmd/LabelStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/LabelStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -24,8 +24,12 @@ import dmd.backend.Util; import dmd.backend.BC; +import dmd.DDMDExtensions; + class LabelStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; Statement statement; TryFinallyStatement tf = null; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/LineInitExp.d --- a/dmd/LineInitExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/LineInitExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.TOK; import dmd.Type; +import dmd.DDMDExtensions; + class LineInitExp : DefaultInitExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/LinkDeclaration.d --- a/dmd/LinkDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/LinkDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.Dsymbol; import dmd.Array; +import dmd.DDMDExtensions; + class LinkDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + LINK linkage; this(LINK p, Dsymbols decl) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/MinAssignExp.d --- a/dmd/MinAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/MinAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class MinAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/MinExp.d --- a/dmd/MinExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/MinExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class MinExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ModAssignExp.d --- a/dmd/ModAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ModAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.backend.elem; +import dmd.DDMDExtensions; + class ModAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ModExp.d --- a/dmd/ModExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ModExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class ModExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Module.d --- a/dmd/Module.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Module.d Tue Jun 07 23:37:34 2011 -0400 @@ -57,6 +57,8 @@ import dmd.backend.LIST; import dmd.codegen.Util; +import dmd.DDMDExtensions; + import core.stdc.string; import core.stdc.stdlib; @@ -166,6 +168,8 @@ class Module : Package { + mixin insertMemberExtension!(typeof(this)); + string arg; // original argument name ModuleDeclaration md; // if !null, the contents of the ModuleDeclaration declaration File srcfile; // input source file diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ModuleDeclaration.d --- a/dmd/ModuleDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ModuleDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -7,8 +7,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class ModuleDeclaration : TObject { + mixin insertMemberExtension!(typeof(this)); + Identifier id; Identifiers packages; // array of Identifier's representing packages bool safe; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ModuleInfoDeclaration.d --- a/dmd/ModuleInfoDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ModuleInfoDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.backend.Symbol; +import dmd.DDMDExtensions; + class ModuleInfoDeclaration : VarDeclaration { + mixin insertMemberExtension!(typeof(this)); + Module mod; this(Module mod) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/MulAssignExp.d --- a/dmd/MulAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/MulAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.expression.Mul; import dmd.expression.Util; +import dmd.DDMDExtensions; + class MulAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/MulExp.d --- a/dmd/MulExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/MulExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class MulExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/NegExp.d --- a/dmd/NegExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/NegExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class NegExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/NewAnonClassExp.d --- a/dmd/NewAnonClassExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/NewAnonClassExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import dmd.TOK; import dmd.expression.Util; +import dmd.DDMDExtensions; + class NewAnonClassExp : Expression { + mixin insertMemberExtension!(typeof(this)); + /* thisexp.new(newargs) class baseclasses { } (arguments) */ Expression thisexp; // if !NULL, 'this' for class being allocated diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/NewDeclaration.d --- a/dmd/NewDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/NewDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.STC; import dmd.Id; +import dmd.DDMDExtensions; + class NewDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + Parameters arguments; int varargs; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/NewExp.d --- a/dmd/NewExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/NewExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -50,8 +50,12 @@ import std.string : toStringz; +import dmd.DDMDExtensions; + class NewExp : Expression { + mixin insertMemberExtension!(typeof(this)); + /* thisexp.new(newargs) newtype(arguments) */ Expression thisexp; // if !null, 'this' for class being allocated diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/NotExp.d --- a/dmd/NotExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/NotExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class NotExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/NullExp.d --- a/dmd/NullExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/NullExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.backend.dt_t; import dmd.backend.Util; +import dmd.DDMDExtensions; + class NullExp : Expression { + mixin insertMemberExtension!(typeof(this)); + ubyte committed; this(Loc loc, Type type = null) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/OnScopeStatement.d --- a/dmd/OnScopeStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/OnScopeStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -24,8 +24,12 @@ import dmd.Expression; import dmd.Lexer; +import dmd.DDMDExtensions; + class OnScopeStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + TOK tok; Statement statement; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/OrAssignExp.d --- a/dmd/OrAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/OrAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.backend.elem; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class OrAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/OrExp.d --- a/dmd/OrExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/OrExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.expression.Or; +import dmd.DDMDExtensions; + class OrExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/OrOrExp.d --- a/dmd/OrOrExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/OrOrExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.OPER; import dmd.backend.Util; +import dmd.DDMDExtensions; + class OrOrExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/OverExp.d --- a/dmd/OverExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/OverExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,10 +8,14 @@ import dmd.TOK; import dmd.Type; +import dmd.DDMDExtensions; + //! overload set version(DMDV2) class OverExp : Expression { + mixin insertMemberExtension!(typeof(this)); + OverloadSet vars; this(OverloadSet s) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/OverloadSet.d --- a/dmd/OverloadSet.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/OverloadSet.d Tue Jun 07 23:37:34 2011 -0400 @@ -4,8 +4,12 @@ import dmd.Dsymbol; import dmd.ArrayTypes; +import dmd.DDMDExtensions; + class OverloadSet : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + Dsymbols a; // array of Dsymbols this() diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Package.d --- a/dmd/Package.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Package.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.Global; import dmd.Util; +import dmd.DDMDExtensions; + class Package : ScopeDsymbol { + mixin insertMemberExtension!(typeof(this)); + this(Identifier ident) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Parameter.d --- a/dmd/Parameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Parameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class Parameter : TObject { + mixin insertMemberExtension!(typeof(this)); + //enum InOut inout; StorageClass storageClass; Type type; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PeelStatement.d --- a/dmd/PeelStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PeelStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -5,8 +5,12 @@ import dmd.Scope; import dmd.Loc; +import dmd.DDMDExtensions; + class PeelStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement s; this(Statement s) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PostBlitDeclaration.d --- a/dmd/PostBlitDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PostBlitDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,9 +17,13 @@ import dmd.TypeFunction; import dmd.Id; +import dmd.DDMDExtensions; + version(DMDV2) class PostBlitDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PostExp.d --- a/dmd/PostExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PostExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class PostExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(TOK op, Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PowAssignExp.d --- a/dmd/PowAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PowAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,9 +18,13 @@ import dmd.ErrorExp; import dmd.Id; +import dmd.DDMDExtensions; + // Only a reduced subset of operations for now. class PowAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PowExp.d --- a/dmd/PowExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PowExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -1,183 +1,187 @@ -module dmd.PowExp; - -import dmd.BinExp; -import dmd.Scope; -import dmd.Loc; -import dmd.Identifier; -import dmd.Expression; -import dmd.TOK; -import dmd.Module; -import dmd.Id; -import dmd.IdentifierExp; -import dmd.DotIdExp; -import dmd.CallExp; -import dmd.ErrorExp; -import dmd.CommaExp; -import dmd.AndExp; -import dmd.CondExp; -import dmd.Global; -import dmd.IntegerExp; -import dmd.Type; -import dmd.STC; -import dmd.Lexer; -import dmd.VarDeclaration; -import dmd.ExpInitializer; -import dmd.VarExp; -import dmd.DeclarationExp; -import dmd.MulExp; -import dmd.WANT; - -version(DMDV2) { - -class PowExp : BinExp -{ - this(Loc loc, Expression e1, Expression e2) - { - register(); - super(loc, TOK.TOKpow, PowExp.sizeof, e1, e2); - } - - override Expression semantic(Scope sc) - { - Expression e; - - if (type) - return this; - - //printf("PowExp::semantic() %s\n", toChars()); - BinExp.semanticp(sc); - e = op_overload(sc); - if (e) - return e; - - assert(e1.type && e2.type); - if ( (e1.type.isintegral() || e1.type.isfloating()) && - (e2.type.isintegral() || e2.type.isfloating())) - { - // For built-in numeric types, there are several cases. - // TODO: backend support, especially for e1 ^^ 2. - - bool wantSqrt = false; - e1 = e1.optimize(0); - e2 = e2.optimize(0); - - // Replace 1 ^^ x or 1.0^^x by (x, 1) - if ((e1.op == TOK.TOKint64 && e1.toInteger() == 1) || - (e1.op == TOK.TOKfloat64 && e1.toReal() == 1.0)) - { - typeCombine(sc); - e = new CommaExp(loc, e2, e1); - e = e.semantic(sc); - return e; - } - // Replace -1 ^^ x by (x&1) ? -1 : 1, where x is integral - if (e2.type.isintegral() && e1.op == TOKint64 && cast(long)e1.toInteger() == -1) - { - typeCombine(sc); - Type resultType = type; - e = new AndExp(loc, e2, new IntegerExp(loc, 1, e2.type)); - e = new CondExp(loc, e, new IntegerExp(loc, -1, resultType), new IntegerExp(loc, 1, resultType)); - e = e.semantic(sc); - return e; - } - // All other negative integral powers are illegal - if ((e1.type.isintegral()) && (e2.op == TOK.TOKint64) && cast(long)e2.toInteger() < 0) - { - error("cannot raise %s to a negative integer power. Did you mean (cast(real)%s)^^%s ?", - e1.type.toBasetype().toChars(), e1.toChars(), e2.toChars()); - return new ErrorExp(); - } - - // Determine if we're raising to an integer power. - long intpow = 0; - if (e2.op == TOKint64 && (cast(long)e2.toInteger() == 2 || cast(long)e2.toInteger() == 3)) - intpow = e2.toInteger(); - else if (e2.op == TOKfloat64 && (e2.toReal() == cast(long)(e2.toReal()))) - intpow = cast(long)(e2.toReal()); - - // Deal with x^^2, x^^3 immediately, since they are of practical importance. - if (intpow == 2 || intpow == 3) - { - typeCombine(sc); - // Replace x^^2 with (tmp = x, tmp*tmp) - // Replace x^^3 with (tmp = x, tmp*tmp*tmp) - Identifier idtmp = Lexer.uniqueId("__tmp"); - VarDeclaration tmp = new VarDeclaration(loc, e1.type.toBasetype(), idtmp, new ExpInitializer(Loc(0), e1)); - tmp.storage_class = STC.STCctfe; - Expression ve = new VarExp(loc, tmp); - Expression ae = new DeclarationExp(loc, tmp); - /* Note that we're reusing ve. This should be ok. - */ - Expression me = new MulExp(loc, ve, ve); - if (intpow == 3) - me = new MulExp(loc, me, ve); - e = new CommaExp(loc, ae, me); - e = e.semantic(sc); - return e; - } - - if (!global.importMathChecked) - { - global.importMathChecked = true; - auto amodules = global.amodules; - for (int i = 0; i < amodules.dim; i++) - { - auto mi = cast(Module)amodules.data[i]; - //printf("\t[%d] %s\n", i, mi->toChars()); - if (mi.ident == Id.math && - mi.parent.ident == Id.std && - !mi.parent.parent) - goto L1; - } - error("must import std.math to use ^^ operator"); - - L1: ; - } - - e = new IdentifierExp(loc, Id.empty); - e = new DotIdExp(loc, e, Id.std); - e = new DotIdExp(loc, e, Id.math); - if (e2.op == TOK.TOKfloat64 && e2.toReal() == 0.5) - { // Replace e1 ^^ 0.5 with .std.math.sqrt(x) - typeCombine(sc); - e = new CallExp(loc, new DotIdExp(loc, e, Id._sqrt), e1); - } - else - { - // Replace e1 ^^ e2 with .std.math.pow(e1, e2) - // We don't combine the types if raising to an integer power (because - // integer powers are treated specially by std.math.pow). - if (!e2.type.isintegral()) - typeCombine(sc); - // In fact, if it *could* have been an integer, make it one. - if (e2.op == TOKfloat64 && intpow != 0) - e2 = new IntegerExp(loc, intpow, Type.tint64); - - e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2); - } - e = e.semantic(sc); - // Always constant fold integer powers of literals. This will run the interpreter - // on .std.math.pow - if ((e1.op == TOK.TOKfloat64 || e1.op == TOK.TOKint64) && (e2.op == TOK.TOKint64)) - e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret); - - return e; - } - error("%s ^^ %s is not supported", e1.type.toChars(), e2.type.toChars() ); - return new ErrorExp(); - } - - - // For operator overloading - override Identifier opId() - { - return Id.pow; - } - - override Identifier opId_r() - { - return Id.pow_r; - } -} - +module dmd.PowExp; + +import dmd.BinExp; +import dmd.Scope; +import dmd.Loc; +import dmd.Identifier; +import dmd.Expression; +import dmd.TOK; +import dmd.Module; +import dmd.Id; +import dmd.IdentifierExp; +import dmd.DotIdExp; +import dmd.CallExp; +import dmd.ErrorExp; +import dmd.CommaExp; +import dmd.AndExp; +import dmd.CondExp; +import dmd.Global; +import dmd.IntegerExp; +import dmd.Type; +import dmd.STC; +import dmd.Lexer; +import dmd.VarDeclaration; +import dmd.ExpInitializer; +import dmd.VarExp; +import dmd.DeclarationExp; +import dmd.MulExp; +import dmd.WANT; + +import dmd.DDMDExtensions; + +version(DMDV2) { + +class PowExp : BinExp +{ + mixin insertMemberExtension!(typeof(this)); + + this(Loc loc, Expression e1, Expression e2) + { + register(); + super(loc, TOK.TOKpow, PowExp.sizeof, e1, e2); + } + + override Expression semantic(Scope sc) + { + Expression e; + + if (type) + return this; + + //printf("PowExp::semantic() %s\n", toChars()); + BinExp.semanticp(sc); + e = op_overload(sc); + if (e) + return e; + + assert(e1.type && e2.type); + if ( (e1.type.isintegral() || e1.type.isfloating()) && + (e2.type.isintegral() || e2.type.isfloating())) + { + // For built-in numeric types, there are several cases. + // TODO: backend support, especially for e1 ^^ 2. + + bool wantSqrt = false; + e1 = e1.optimize(0); + e2 = e2.optimize(0); + + // Replace 1 ^^ x or 1.0^^x by (x, 1) + if ((e1.op == TOK.TOKint64 && e1.toInteger() == 1) || + (e1.op == TOK.TOKfloat64 && e1.toReal() == 1.0)) + { + typeCombine(sc); + e = new CommaExp(loc, e2, e1); + e = e.semantic(sc); + return e; + } + // Replace -1 ^^ x by (x&1) ? -1 : 1, where x is integral + if (e2.type.isintegral() && e1.op == TOKint64 && cast(long)e1.toInteger() == -1) + { + typeCombine(sc); + Type resultType = type; + e = new AndExp(loc, e2, new IntegerExp(loc, 1, e2.type)); + e = new CondExp(loc, e, new IntegerExp(loc, -1, resultType), new IntegerExp(loc, 1, resultType)); + e = e.semantic(sc); + return e; + } + // All other negative integral powers are illegal + if ((e1.type.isintegral()) && (e2.op == TOK.TOKint64) && cast(long)e2.toInteger() < 0) + { + error("cannot raise %s to a negative integer power. Did you mean (cast(real)%s)^^%s ?", + e1.type.toBasetype().toChars(), e1.toChars(), e2.toChars()); + return new ErrorExp(); + } + + // Determine if we're raising to an integer power. + long intpow = 0; + if (e2.op == TOKint64 && (cast(long)e2.toInteger() == 2 || cast(long)e2.toInteger() == 3)) + intpow = e2.toInteger(); + else if (e2.op == TOKfloat64 && (e2.toReal() == cast(long)(e2.toReal()))) + intpow = cast(long)(e2.toReal()); + + // Deal with x^^2, x^^3 immediately, since they are of practical importance. + if (intpow == 2 || intpow == 3) + { + typeCombine(sc); + // Replace x^^2 with (tmp = x, tmp*tmp) + // Replace x^^3 with (tmp = x, tmp*tmp*tmp) + Identifier idtmp = Lexer.uniqueId("__tmp"); + VarDeclaration tmp = new VarDeclaration(loc, e1.type.toBasetype(), idtmp, new ExpInitializer(Loc(0), e1)); + tmp.storage_class = STC.STCctfe; + Expression ve = new VarExp(loc, tmp); + Expression ae = new DeclarationExp(loc, tmp); + /* Note that we're reusing ve. This should be ok. + */ + Expression me = new MulExp(loc, ve, ve); + if (intpow == 3) + me = new MulExp(loc, me, ve); + e = new CommaExp(loc, ae, me); + e = e.semantic(sc); + return e; + } + + if (!global.importMathChecked) + { + global.importMathChecked = true; + auto amodules = global.amodules; + for (int i = 0; i < amodules.dim; i++) + { + auto mi = cast(Module)amodules.data[i]; + //printf("\t[%d] %s\n", i, mi->toChars()); + if (mi.ident == Id.math && + mi.parent.ident == Id.std && + !mi.parent.parent) + goto L1; + } + error("must import std.math to use ^^ operator"); + + L1: ; + } + + e = new IdentifierExp(loc, Id.empty); + e = new DotIdExp(loc, e, Id.std); + e = new DotIdExp(loc, e, Id.math); + if (e2.op == TOK.TOKfloat64 && e2.toReal() == 0.5) + { // Replace e1 ^^ 0.5 with .std.math.sqrt(x) + typeCombine(sc); + e = new CallExp(loc, new DotIdExp(loc, e, Id._sqrt), e1); + } + else + { + // Replace e1 ^^ e2 with .std.math.pow(e1, e2) + // We don't combine the types if raising to an integer power (because + // integer powers are treated specially by std.math.pow). + if (!e2.type.isintegral()) + typeCombine(sc); + // In fact, if it *could* have been an integer, make it one. + if (e2.op == TOKfloat64 && intpow != 0) + e2 = new IntegerExp(loc, intpow, Type.tint64); + + e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2); + } + e = e.semantic(sc); + // Always constant fold integer powers of literals. This will run the interpreter + // on .std.math.pow + if ((e1.op == TOK.TOKfloat64 || e1.op == TOK.TOKint64) && (e2.op == TOK.TOKint64)) + e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret); + + return e; + } + error("%s ^^ %s is not supported", e1.type.toChars(), e2.type.toChars() ); + return new ErrorExp(); + } + + + // For operator overloading + override Identifier opId() + { + return Id.pow; + } + + override Identifier opId_r() + { + return Id.pow_r; + } +} + } \ No newline at end of file diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PragmaDeclaration.d --- a/dmd/PragmaDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PragmaDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import core.stdc.stdlib : malloc; +import dmd.DDMDExtensions; + class PragmaDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + Expressions args; // array of Expression's this(Loc loc, Identifier ident, Expressions args, Dsymbols decl) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PragmaStatement.d --- a/dmd/PragmaStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PragmaStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.TOK; import dmd.WANT; +import dmd.DDMDExtensions; + class PragmaStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; Expressions args; // array of Expression's Statement body_; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ProtDeclaration.d --- a/dmd/ProtDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ProtDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.Dsymbol; import dmd.Array; +import dmd.DDMDExtensions; + class ProtDeclaration : AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + PROT protection; this(PROT p, Dsymbols decl) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/PtrExp.d --- a/dmd/PtrExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/PtrExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -31,8 +31,12 @@ import dmd.backend.mTY; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class PtrExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/RealExp.d --- a/dmd/RealExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/RealExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,8 +26,12 @@ import std.stdio; import std.string; +import dmd.DDMDExtensions; + class RealExp : Expression { + mixin insertMemberExtension!(typeof(this)); + real value; this(Loc loc, real value, Type type) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/RemoveExp.d --- a/dmd/RemoveExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/RemoveExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,11 +17,15 @@ import dmd.backend.TYM; import dmd.backend.mTY; +import dmd.DDMDExtensions; + /* This deletes the key e1 from the associative array e2 */ class RemoveExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ReturnStatement.d --- a/dmd/ReturnStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ReturnStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -49,8 +49,12 @@ import core.stdc.string; +import dmd.DDMDExtensions; + class ReturnStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Scope.d --- a/dmd/Scope.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Scope.d Tue Jun 07 23:37:34 2011 -0400 @@ -29,6 +29,8 @@ import core.memory; +import dmd.DDMDExtensions; + enum SCOPE { SCOPEctor = 1, // constructor type @@ -40,6 +42,8 @@ class Scope : TObject { + mixin insertMemberExtension!(typeof(this)); + Scope enclosing; // enclosing Scope Module module_; // Root module diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ScopeDsymbol.d --- a/dmd/ScopeDsymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ScopeDsymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,12 +16,16 @@ import dmd.Id; import dmd.expression.Util; +import dmd.DDMDExtensions; + import std.stdio : writef; //core.stdc.stdlib; import core.memory; class ScopeDsymbol : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + Dsymbols members; // all Dsymbol's in this scope DsymbolTable symtab; // members[] sorted into table diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ScopeExp.d --- a/dmd/ScopeExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ScopeExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.DsymbolExp; import dmd.Type; +import dmd.DDMDExtensions; + class ScopeExp : Expression { + mixin insertMemberExtension!(typeof(this)); + ScopeDsymbol sds; this(Loc loc, ScopeDsymbol pkg) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ScopeStatement.d --- a/dmd/ScopeStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ScopeStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.backend.BC; import dmd.backend.Util; +import dmd.DDMDExtensions; + class ScopeStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement statement; this(Loc loc, Statement s) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SharedStaticCtorDeclaration.d --- a/dmd/SharedStaticCtorDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SharedStaticCtorDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -7,8 +7,12 @@ import dmd.HdrGenState; import dmd.FuncDeclaration; +import dmd.DDMDExtensions; + class SharedStaticCtorDeclaration : StaticCtorDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc) { super(loc, endloc, "_sharedStaticCtor"); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SharedStaticDtorDeclaration.d --- a/dmd/SharedStaticDtorDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SharedStaticDtorDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -7,8 +7,12 @@ import dmd.HdrGenState; import dmd.FuncDeclaration; +import dmd.DDMDExtensions; + class SharedStaticDtorDeclaration : StaticDtorDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc) { super(loc, endloc, "_sharedStaticDtor"); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ShlAssignExp.d --- a/dmd/ShlAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ShlAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,8 +17,12 @@ import dmd.expression.Shl; import dmd.expression.Util; +import dmd.DDMDExtensions; + class ShlAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ShlExp.d --- a/dmd/ShlExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ShlExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.OPER; +import dmd.DDMDExtensions; + class ShlExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ShrAssignExp.d --- a/dmd/ShrAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ShrAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.expression.Shr; import dmd.expression.Util; +import dmd.DDMDExtensions; + class ShrAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ShrExp.d --- a/dmd/ShrExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ShrExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.expression.shift_optimize; import dmd.expression.Shr; +import dmd.DDMDExtensions; + class ShrExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SliceExp.d --- a/dmd/SliceExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SliceExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -56,8 +56,12 @@ import core.stdc.string; +import dmd.DDMDExtensions; + class SliceExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + Expression upr; // null if implicit 0 Expression lwr; // null if implicit [length - 1] diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Statement.d --- a/dmd/Statement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Statement.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,6 +27,8 @@ import std.stdio; +import dmd.DDMDExtensions; + //! startup code used in *Statement.interpret() functions enum START = ` if (istate.start) @@ -41,6 +43,8 @@ class Statement : TObject { + mixin insertMemberExtension!(typeof(this)); + Loc loc; this(Loc loc) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StaticAssert.d --- a/dmd/StaticAssert.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StaticAssert.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,8 +13,12 @@ import dmd.Global; import dmd.Util; +import dmd.DDMDExtensions; + class StaticAssert : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + Expression exp; Expression msg; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StaticAssertStatement.d --- a/dmd/StaticAssertStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StaticAssertStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.Scope; import dmd.Loc; +import dmd.DDMDExtensions; + class StaticAssertStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + StaticAssert sa; this(StaticAssert sa) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StaticCtorDeclaration.d --- a/dmd/StaticCtorDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StaticCtorDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -29,8 +29,12 @@ import dmd.ReturnStatement; import dmd.IdentifierExp; +import dmd.DDMDExtensions; + class StaticCtorDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc, string name = "_staticCtor") { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StaticDtorDeclaration.d --- a/dmd/StaticDtorDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StaticDtorDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -30,8 +30,12 @@ import dmd.CompoundStatement; import dmd.Module; +import dmd.DDMDExtensions; + class StaticDtorDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + VarDeclaration vgate; // 'gate' variable this(Loc loc, Loc endloc, string name = "_staticDtor") diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StaticIfCondition.d --- a/dmd/StaticIfCondition.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StaticIfCondition.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.WANT; import dmd.Util; +import dmd.DDMDExtensions; + class StaticIfCondition : Condition { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StaticIfDeclaration.d --- a/dmd/StaticIfDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StaticIfDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.Array; import dmd.Dsymbol; +import dmd.DDMDExtensions; + class StaticIfDeclaration : ConditionalDeclaration { + mixin insertMemberExtension!(typeof(this)); + ScopeDsymbol sd; int addisdone; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StorageClassDeclaration.d --- a/dmd/StorageClassDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StorageClassDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,8 +13,12 @@ import dmd.Id; import dmd.Identifier; +import dmd.DDMDExtensions; + class StorageClassDeclaration: AttribDeclaration { + mixin insertMemberExtension!(typeof(this)); + StorageClass stc; this(StorageClass stc, Dsymbols decl) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StringExp.d --- a/dmd/StringExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StringExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -40,8 +40,12 @@ import core.stdc.stdlib; import core.stdc.ctype; +import dmd.DDMDExtensions; + class StringExp : Expression { + mixin insertMemberExtension!(typeof(this)); + void* string_; // char, wchar, or dchar data size_t len; // number of chars, wchars, or dchars ubyte sz; // 1: char, 2: wchar, 4: dchar diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StructDeclaration.d --- a/dmd/StructDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StructDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -67,8 +67,12 @@ import std.stdio; +import dmd.DDMDExtensions; + class StructDeclaration : AggregateDeclaration { + mixin insertMemberExtension!(typeof(this)); + bool zeroInit; // true if initialize with 0 fill version (DMDV2) { diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StructInitializer.d --- a/dmd/StructInitializer.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StructInitializer.d Tue Jun 07 23:37:34 2011 -0400 @@ -31,8 +31,12 @@ import dmd.backend.dt_t; import dmd.backend.Util; +import dmd.DDMDExtensions; + class StructInitializer : Initializer { + mixin insertMemberExtension!(typeof(this)); + Identifiers field; // of Identifier *'s Initializers value; // parallel array of Initializer *'s diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/StructLiteralExp.d --- a/dmd/StructLiteralExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/StructLiteralExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -42,9 +42,12 @@ import dmd.backend.mTY; import dmd.backend.OPER; +import dmd.DDMDExtensions; class StructLiteralExp : Expression { + mixin insertMemberExtension!(typeof(this)); + StructDeclaration sd; // which aggregate this is for Expressions elements; // parallels sd.fields[] with // NULL entries for fields to skip diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SuperExp.d --- a/dmd/SuperExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SuperExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.CSX; import dmd.Type; +import dmd.DDMDExtensions; + class SuperExp : ThisExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SwitchErrorStatement.d --- a/dmd/SwitchErrorStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SwitchErrorStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import dmd.backend.OPER; import dmd.backend.RTLSYM; +import dmd.DDMDExtensions; + class SwitchErrorStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SwitchStatement.d --- a/dmd/SwitchStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SwitchStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -57,8 +57,12 @@ import core.stdc.stdlib; +import dmd.DDMDExtensions; + class SwitchStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression condition; Statement body_; bool isFinal; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SymOffExp.d --- a/dmd/SymOffExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SymOffExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -28,8 +28,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class SymOffExp : SymbolExp { + mixin insertMemberExtension!(typeof(this)); + uint offset; this(Loc loc, Declaration var, uint offset, bool hasOverloads = false) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SymbolDeclaration.d --- a/dmd/SymbolDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SymbolDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,10 +13,14 @@ import core.stdc.string; import std.stdio; +import dmd.DDMDExtensions; + // This is a shell around a back end symbol class SymbolDeclaration : Declaration { + mixin insertMemberExtension!(typeof(this)); + Symbol* sym; StructDeclaration dsym; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SymbolExp.d --- a/dmd/SymbolExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SymbolExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,9 +21,13 @@ import dmd.backend.Util; import dmd.codegen.Util; +import dmd.DDMDExtensions; + version(DMDV2) class SymbolExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Declaration var; bool hasOverloads; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/SynchronizedStatement.d --- a/dmd/SynchronizedStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/SynchronizedStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -37,8 +37,12 @@ import dmd.backend.elem; import dmd.backend.Util; +import dmd.DDMDExtensions; + class SynchronizedStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; Statement body_; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateAliasParameter.d --- a/dmd/TemplateAliasParameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateAliasParameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,6 +26,8 @@ import dmd.templates.Util; +import dmd.DDMDExtensions; + Object aliasParameterSemantic(Loc loc, Scope sc, Object o) { if (o) @@ -50,6 +52,8 @@ class TemplateAliasParameter : TemplateParameter { + mixin insertMemberExtension!(typeof(this)); + /* Syntax: * specType ident : specAlias = defaultAlias */ diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateDeclaration.d --- a/dmd/TemplateDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -48,6 +48,8 @@ import std.stdio; +import dmd.DDMDExtensions; + /************************************** * Determine if TemplateDeclaration is variadic. */ @@ -106,6 +108,8 @@ class TemplateDeclaration : ScopeDsymbol { + mixin insertMemberExtension!(typeof(this)); + TemplateParameters parameters; // array of TemplateParameter's TemplateParameters origParameters; // originals for Ddoc diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateExp.d --- a/dmd/TemplateExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,8 +8,12 @@ import dmd.TemplateDeclaration; import dmd.TOK; +import dmd.DDMDExtensions; + class TemplateExp : Expression { + mixin insertMemberExtension!(typeof(this)); + TemplateDeclaration td; this(Loc loc, TemplateDeclaration td) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateInstance.d --- a/dmd/TemplateInstance.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateInstance.d Tue Jun 07 23:37:34 2011 -0400 @@ -45,6 +45,8 @@ import dmd.backend.glue; +import dmd.DDMDExtensions; + Tuple isTuple(Object o) { //return dynamic_cast(o); @@ -163,6 +165,8 @@ class TemplateInstance : ScopeDsymbol { + mixin insertMemberExtension!(typeof(this)); + /* Given: * foo!(args) => * name = foo diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateMixin.d --- a/dmd/TemplateMixin.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateMixin.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,10 +21,14 @@ import dmd.Global; import dmd.Util; +import dmd.DDMDExtensions; + extern(C++) void util_progress(); class TemplateMixin : TemplateInstance { + mixin insertMemberExtension!(typeof(this)); + Array idents; Type tqual; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateParameter.d --- a/dmd/TemplateParameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateParameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.TObject; +import dmd.DDMDExtensions; + class TemplateParameter : TObject { + mixin insertMemberExtension!(typeof(this)); + /* For type-parameter: * template Foo(ident) // specType is set to NULL * template Foo(ident : specType) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateThisParameter.d --- a/dmd/TemplateThisParameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateThisParameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.OutBuffer; import dmd.HdrGenState; +import dmd.DDMDExtensions; + class TemplateThisParameter : TemplateTypeParameter { + mixin insertMemberExtension!(typeof(this)); + /* Syntax: * this ident : specType = defaultType */ diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateTupleParameter.d --- a/dmd/TemplateTupleParameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateTupleParameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.Expression; import dmd.TupleDeclaration; +import dmd.DDMDExtensions; + class TemplateTupleParameter : TemplateParameter { + mixin insertMemberExtension!(typeof(this)); + /* Syntax: * ident ... */ diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateTypeParameter.d --- a/dmd/TemplateTypeParameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateTypeParameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.MATCH; import dmd.Dsymbol; +import dmd.DDMDExtensions; + class TemplateTypeParameter : TemplateParameter { + mixin insertMemberExtension!(typeof(this)); + /* Syntax: * ident : specType = defaultType */ diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TemplateValueParameter.d --- a/dmd/TemplateValueParameter.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TemplateValueParameter.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,8 +25,12 @@ import dmd.Dsymbol : isExpression; +import dmd.DDMDExtensions; + class TemplateValueParameter : TemplateParameter { + mixin insertMemberExtension!(typeof(this)); + /* Syntax: * valType ident : specValue = defaultValue */ diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ThisDeclaration.d --- a/dmd/ThisDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ThisDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -7,10 +7,14 @@ import dmd.Type; import dmd.Id; +import dmd.DDMDExtensions; + // For the "this" parameter to member functions class ThisDeclaration : VarDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Type t) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ThisExp.d --- a/dmd/ThisExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ThisExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -27,8 +27,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class ThisExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Declaration var; this(Loc loc) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/ThrowStatement.d --- a/dmd/ThrowStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/ThrowStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.OPER; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class ThrowStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TraitsExp.d --- a/dmd/TraitsExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TraitsExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -37,6 +37,8 @@ import core.stdc.string : strcmp; +import dmd.DDMDExtensions; + /************************************************ * Delegate to be passed to overloadApply() that looks * for functions matching a trait. @@ -70,6 +72,8 @@ class TraitsExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; Objects args; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TryCatchStatement.d --- a/dmd/TryCatchStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TryCatchStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.mTY; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TryCatchStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement body_; Array catches; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TryFinallyStatement.d --- a/dmd/TryFinallyStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TryFinallyStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.codegen.Util; +import dmd.DDMDExtensions; + class TryFinallyStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement body_; Statement finalbody; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TupleDeclaration.d --- a/dmd/TupleDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TupleDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.Expression; import dmd.DsymbolExp; +import dmd.DDMDExtensions; + class TupleDeclaration : Declaration { + mixin insertMemberExtension!(typeof(this)); + Objects objects; int isexp; // 1: expression tuple diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TupleExp.d --- a/dmd/TupleExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TupleExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,6 +25,8 @@ import dmd.DYNCAST; import dmd.expression.Util; +import dmd.DDMDExtensions; + /**************************************** * Expand tuples. */ @@ -72,6 +74,8 @@ +/ class TupleExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Expressions exps; this(Loc loc, Expressions exps) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/Type.d --- a/dmd/Type.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/Type.d Tue Jun 07 23:37:34 2011 -0400 @@ -75,6 +75,8 @@ import core.memory; +import dmd.DDMDExtensions; + /* These have default values for 32 bit code, they get * adjusted for 64 bit code. */ @@ -229,6 +231,8 @@ class Type : TObject { + mixin insertMemberExtension!(typeof(this)); + TY ty; MOD mod; // modifiers MODxxxx /* pick this order of numbers so switch statements work better diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeAArray.d --- a/dmd/TypeAArray.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeAArray.d Tue Jun 07 23:37:34 2011 -0400 @@ -41,12 +41,16 @@ import dmd.backend.Classsym; import dmd.backend.mTYman; +import dmd.DDMDExtensions; + import core.stdc.stdio; import core.stdc.stdlib; version (Bug4054) import core.memory; class TypeAArray : TypeArray { + mixin insertMemberExtension!(typeof(this)); + Type index; // key type Loc loc; Scope sc; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeArray.d --- a/dmd/TypeArray.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeArray.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,6 +17,8 @@ import dmd.IntegerExp; import dmd.Global; +import dmd.DDMDExtensions; + // Allow implicit conversion of T[] to T* bool IMPLICIT_ARRAY_TO_PTR() { @@ -25,6 +27,8 @@ class TypeArray : TypeNext { + mixin insertMemberExtension!(typeof(this)); + this(TY ty, Type next) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeBasic.d --- a/dmd/TypeBasic.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeBasic.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.Port; import dmd.Complex; +import dmd.DDMDExtensions; + class TypeBasic : Type { + mixin insertMemberExtension!(typeof(this)); + string dstring; uint flags; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeClass.d --- a/dmd/TypeClass.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeClass.d Tue Jun 07 23:37:34 2011 -0400 @@ -62,8 +62,12 @@ import std.string : toStringz; +import dmd.DDMDExtensions; + class TypeClass : Type { + mixin insertMemberExtension!(typeof(this)); + ClassDeclaration sym; this(ClassDeclaration sym) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeDArray.d --- a/dmd/TypeDArray.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeDArray.d Tue Jun 07 23:37:34 2011 -0400 @@ -38,9 +38,13 @@ import core.stdc.stdio; version (Bug4054) import core.memory; +import dmd.DDMDExtensions; + // Dynamic array, no dimension class TypeDArray : TypeArray { + mixin insertMemberExtension!(typeof(this)); + this(Type t) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeDelegate.d --- a/dmd/TypeDelegate.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeDelegate.d Tue Jun 07 23:37:34 2011 -0400 @@ -32,8 +32,12 @@ import dmd.backend.Util; import dmd.backend.LIST; +import dmd.DDMDExtensions; + class TypeDelegate : TypeNext { + mixin insertMemberExtension!(typeof(this)); + // .next is a TypeFunction this(Type t) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeEnum.d --- a/dmd/TypeEnum.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeEnum.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,8 +26,12 @@ import dmd.backend.TYPE; +import dmd.DDMDExtensions; + class TypeEnum : Type { + mixin insertMemberExtension!(typeof(this)); + EnumDeclaration sym; this(EnumDeclaration sym) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeExp.d --- a/dmd/TypeExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,8 +13,12 @@ import dmd.HdrGenState; import dmd.TOK; +import dmd.DDMDExtensions; + class TypeExp : Expression { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Type type) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeFunction.d --- a/dmd/TypeFunction.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeFunction.d Tue Jun 07 23:37:34 2011 -0400 @@ -49,8 +49,12 @@ import std.stdio; +import dmd.DDMDExtensions; + class TypeFunction : TypeNext { + mixin insertMemberExtension!(typeof(this)); + // .next is the return type Parameters parameters; // function parameters diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeIdentifier.d --- a/dmd/TypeIdentifier.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeIdentifier.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ debug import dmd.Global; +import dmd.DDMDExtensions; + class TypeIdentifier : TypeQualified { + mixin insertMemberExtension!(typeof(this)); + Identifier ident; this(Loc loc, Identifier ident) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoArrayDeclaration.d --- a/dmd/TypeInfoArrayDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoArrayDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -12,8 +12,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypeInfoArrayDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoAssociativeArrayDeclaration.d --- a/dmd/TypeInfoAssociativeArrayDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoAssociativeArrayDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.backend.TYM; import dmd.backend.Util; +import dmd.DDMDExtensions; + class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoClassDeclaration.d --- a/dmd/TypeInfoClassDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoClassDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,8 +13,12 @@ import dmd.backend.TYM; import dmd.backend.Symbol; +import dmd.DDMDExtensions; + class TypeInfoClassDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoConstDeclaration.d --- a/dmd/TypeInfoConstDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoConstDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,9 +8,13 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + version(DMDV2) class TypeInfoConstDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoDeclaration.d --- a/dmd/TypeInfoDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -24,8 +24,12 @@ import core.stdc.stdio; +import dmd.DDMDExtensions; + class TypeInfoDeclaration : VarDeclaration { + mixin insertMemberExtension!(typeof(this)); + Type tinfo; this(Type tinfo, int internal) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoDelegateDeclaration.d --- a/dmd/TypeInfoDelegateDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoDelegateDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypeInfoDelegateDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoEnumDeclaration.d --- a/dmd/TypeInfoEnumDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoEnumDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import std.string : toStringz; +import dmd.DDMDExtensions; + class TypeInfoEnumDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoFunctionDeclaration.d --- a/dmd/TypeInfoFunctionDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoFunctionDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypeInfoFunctionDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoInterfaceDeclaration.d --- a/dmd/TypeInfoInterfaceDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoInterfaceDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -14,8 +14,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypeInfoInterfaceDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoInvariantDeclaration.d --- a/dmd/TypeInfoInvariantDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoInvariantDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,9 +8,13 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + version(DMDV2) class TypeInfoInvariantDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoPointerDeclaration.d --- a/dmd/TypeInfoPointerDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoPointerDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypeInfoPointerDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoSharedDeclaration.d --- a/dmd/TypeInfoSharedDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoSharedDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,9 +8,13 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + version(DMDV2) class TypeInfoSharedDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoStaticArrayDeclaration.d --- a/dmd/TypeInfoStaticArrayDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoStaticArrayDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -11,8 +11,12 @@ import dmd.backend.TYM; import dmd.backend.dt_t; +import dmd.DDMDExtensions; + class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoStructDeclaration.d --- a/dmd/TypeInfoStructDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoStructDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,8 +25,12 @@ import std.string : toStringz; +import dmd.DDMDExtensions; + class TypeInfoStructDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoTupleDeclaration.d --- a/dmd/TypeInfoTupleDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoTupleDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -15,8 +15,12 @@ import dmd.backend.Util; import dmd.codegen.Util; +import dmd.DDMDExtensions; + class TypeInfoTupleDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoTypedefDeclaration.d --- a/dmd/TypeInfoTypedefDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoTypedefDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -14,8 +14,12 @@ import std.string; +import dmd.DDMDExtensions; + class TypeInfoTypedefDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInfoWildDeclaration.d --- a/dmd/TypeInfoWildDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInfoWildDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypeInfoWildDeclaration : TypeInfoDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Type tinfo) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeInstance.d --- a/dmd/TypeInstance.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeInstance.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,10 +25,14 @@ import dmd.TY; import dmd.Util : printf; +import dmd.DDMDExtensions; + /* Similar to TypeIdentifier, but with a TemplateInstance as the root */ class TypeInstance : TypeQualified { + mixin insertMemberExtension!(typeof(this)); + TemplateInstance tempinst; this(Loc loc, TemplateInstance tempinst) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeNewArray.d --- a/dmd/TypeNewArray.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeNewArray.d Tue Jun 07 23:37:34 2011 -0400 @@ -8,10 +8,14 @@ import dmd.TypeNext; import dmd.TY; +import dmd.DDMDExtensions; + /** T[new] */ class TypeNewArray : TypeNext { + mixin insertMemberExtension!(typeof(this)); + this(Type next) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeNext.d --- a/dmd/TypeNext.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeNext.d Tue Jun 07 23:37:34 2011 -0400 @@ -10,8 +10,12 @@ import dmd.MATCH; import dmd.MOD; +import dmd.DDMDExtensions; + class TypeNext : Type { + mixin insertMemberExtension!(typeof(this)); + Type next; this(TY ty, Type next) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypePointer.d --- a/dmd/TypePointer.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypePointer.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.backend.Util; import dmd.backend.TYM; +import dmd.DDMDExtensions; + class TypePointer : TypeNext { + mixin insertMemberExtension!(typeof(this)); + this(Type t) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeQualified.d --- a/dmd/TypeQualified.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeQualified.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,8 +25,12 @@ import dmd.FuncDeclaration; import dmd.Util; +import dmd.DDMDExtensions; + class TypeQualified : Type { + mixin insertMemberExtension!(typeof(this)); + Loc loc; Array idents; // array of Identifier's representing ident.ident.ident etc. diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeReference.d --- a/dmd/TypeReference.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeReference.d Tue Jun 07 23:37:34 2011 -0400 @@ -14,8 +14,12 @@ import dmd.CppMangleState; import dmd.TY; +import dmd.DDMDExtensions; + class TypeReference : TypeNext { + mixin insertMemberExtension!(typeof(this)); + this(Type t) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeReturn.d --- a/dmd/TypeReturn.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeReturn.d Tue Jun 07 23:37:34 2011 -0400 @@ -12,8 +12,12 @@ import dmd.Identifier; import dmd.TY; +import dmd.DDMDExtensions; + class TypeReturn : TypeQualified { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeSArray.d --- a/dmd/TypeSArray.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeSArray.d Tue Jun 07 23:37:34 2011 -0400 @@ -46,9 +46,13 @@ import dmd.backend.TYM; import dmd.backend.DT; +import dmd.DDMDExtensions; + // Static array, one with a fixed dimension class TypeSArray : TypeArray { + mixin insertMemberExtension!(typeof(this)); + Expression dim; this(Type t, Expression dim) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeSlice.d --- a/dmd/TypeSlice.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeSlice.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.type.Util; +import dmd.DDMDExtensions; + class TypeSlice : TypeNext { + mixin insertMemberExtension!(typeof(this)); + Expression lwr; Expression upr; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeStruct.d --- a/dmd/TypeStruct.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeStruct.d Tue Jun 07 23:37:34 2011 -0400 @@ -60,8 +60,12 @@ import std.string : toStringz; +import dmd.DDMDExtensions; + class TypeStruct : Type { + mixin insertMemberExtension!(typeof(this)); + StructDeclaration sym; this(StructDeclaration sym) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeTuple.d --- a/dmd/TypeTuple.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeTuple.d Tue Jun 07 23:37:34 2011 -0400 @@ -19,8 +19,12 @@ import dmd.ErrorExp; import dmd.IntegerExp; +import dmd.DDMDExtensions; + class TypeTuple : Type { + mixin insertMemberExtension!(typeof(this)); + Parameters arguments; // types making up the tuple this(Parameters arguments) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeTypedef.d --- a/dmd/TypeTypedef.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeTypedef.d Tue Jun 07 23:37:34 2011 -0400 @@ -23,8 +23,12 @@ import dmd.backend.TYPE; import dmd.backend.dt_t; +import dmd.DDMDExtensions; + class TypeTypedef : Type { + mixin insertMemberExtension!(typeof(this)); + TypedefDeclaration sym; this(TypedefDeclaration sym) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeTypeof.d --- a/dmd/TypeTypeof.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeTypeof.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.Util; import dmd.TOK; +import dmd.DDMDExtensions; + class TypeTypeof : TypeQualified { + mixin insertMemberExtension!(typeof(this)); + Expression exp; this(Loc loc, Expression exp) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypedefDeclaration.d --- a/dmd/TypedefDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypedefDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -26,8 +26,12 @@ import dmd.backend.Classsym; import dmd.codegen.Util; +import dmd.DDMDExtensions; + class TypedefDeclaration : Declaration { + mixin insertMemberExtension!(typeof(this)); + Type basetype; Initializer init; int sem = 0;// 0: semantic() has not been run diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/TypeidExp.d --- a/dmd/TypeidExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/TypeidExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.CommaExp; import dmd.templates.Util; +import dmd.DDMDExtensions; + class TypeidExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Object obj; this(Loc loc, Object o) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UAddExp.d --- a/dmd/UAddExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UAddExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -9,8 +9,12 @@ import dmd.TOK; import dmd.Id; +import dmd.DDMDExtensions; + class UAddExp : UnaExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UnaExp.d --- a/dmd/UnaExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UnaExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -24,8 +24,12 @@ import dmd.Token; import dmd.expression.Util; +import dmd.DDMDExtensions; + class UnaExp : Expression { + mixin insertMemberExtension!(typeof(this)); + Expression e1; this(Loc loc, TOK op, int size, Expression e1) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UnionDeclaration.d --- a/dmd/UnionDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UnionDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -6,8 +6,12 @@ import dmd.Identifier; import dmd.Dsymbol; +import dmd.DDMDExtensions; + class UnionDeclaration : StructDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Identifier id) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UnitTestDeclaration.d --- a/dmd/UnitTestDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UnitTestDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -17,6 +17,8 @@ import dmd.Lexer; import dmd.Identifier; +import dmd.DDMDExtensions; + /******************************* * Generate unique unittest function Id so we can have multiple * instances per module. @@ -28,6 +30,8 @@ class UnitTestDeclaration : FuncDeclaration { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Loc endloc) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UnrolledLoopStatement.d --- a/dmd/UnrolledLoopStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UnrolledLoopStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.backend.block; import dmd.backend.Util; +import dmd.DDMDExtensions; + class UnrolledLoopStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statements statements; this(Loc loc, Statements s) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UshrAssignExp.d --- a/dmd/UshrAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UshrAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -18,8 +18,12 @@ import dmd.backend.OPER; +import dmd.DDMDExtensions; + class UshrAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/UshrExp.d --- a/dmd/UshrExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/UshrExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,8 +21,12 @@ import dmd.expression.Ushr; import dmd.expression.shift_optimize; +import dmd.DDMDExtensions; + class UshrExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/VarDeclaration.d --- a/dmd/VarDeclaration.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/VarDeclaration.d Tue Jun 07 23:37:34 2011 -0400 @@ -69,8 +69,12 @@ import std.stdio : writef; import std.string : toStringz; +import dmd.DDMDExtensions; + class VarDeclaration : Declaration { + mixin insertMemberExtension!(typeof(this)); + Initializer init; uint offset; bool noauto; // no auto semantics diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/VarExp.d --- a/dmd/VarExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/VarExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -25,9 +25,13 @@ import dmd.backend.dt_t; import dmd.expression.Util; +import dmd.DDMDExtensions; + //! Variable class VarExp : SymbolExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Declaration var, bool hasOverloads = false) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/VersionCondition.d --- a/dmd/VersionCondition.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/VersionCondition.d Tue Jun 07 23:37:34 2011 -0400 @@ -21,6 +21,8 @@ import std.stdio; +import dmd.DDMDExtensions; + bool findCondition(Vector!(string) ids, Identifier ident) { if (ids !is null) { @@ -37,6 +39,8 @@ class VersionCondition : DVCondition { + mixin insertMemberExtension!(typeof(this)); + static void setGlobalLevel(uint level) { global.params.versionlevel = level; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/VersionSymbol.d --- a/dmd/VersionSymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/VersionSymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,12 +13,16 @@ import dmd.String; import dmd.OutBuffer; +import dmd.DDMDExtensions; + /* VersionSymbol's happen for statements like: * version = identifier; * version = integer; */ class VersionSymbol : Dsymbol { + mixin insertMemberExtension!(typeof(this)); + uint level; this(Loc loc, Identifier ident) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/VoidInitializer.d --- a/dmd/VoidInitializer.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/VoidInitializer.d Tue Jun 07 23:37:34 2011 -0400 @@ -12,8 +12,12 @@ import dmd.backend.dt_t; import dmd.backend.Util; +import dmd.DDMDExtensions; + class VoidInitializer : Initializer { + mixin insertMemberExtension!(typeof(this)); + Type type = null; // type that this will initialize to this(Loc loc) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/VolatileStatement.d --- a/dmd/VolatileStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/VolatileStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -20,8 +20,12 @@ import dmd.backend.mTY; //import dmd.backend.BFL; +import dmd.DDMDExtensions; + class VolatileStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Statement statement; this(Loc loc, Statement statement) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/WhileStatement.d --- a/dmd/WhileStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/WhileStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -13,8 +13,12 @@ import dmd.BE; import dmd.ForStatement; +import dmd.DDMDExtensions; + class WhileStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression condition; Statement body_; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/WithScopeSymbol.d --- a/dmd/WithScopeSymbol.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/WithScopeSymbol.d Tue Jun 07 23:37:34 2011 -0400 @@ -7,8 +7,12 @@ import dmd.Identifier; import dmd.Dsymbol; +import dmd.DDMDExtensions; + class WithScopeSymbol : ScopeDsymbol { + mixin insertMemberExtension!(typeof(this)); + WithStatement withstate; this(WithStatement withstate) diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/WithStatement.d --- a/dmd/WithStatement.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/WithStatement.d Tue Jun 07 23:37:34 2011 -0400 @@ -29,8 +29,12 @@ import dmd.backend.Util; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class WithStatement : Statement { + mixin insertMemberExtension!(typeof(this)); + Expression exp; Statement body_; VarDeclaration wthis; diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/XorAssignExp.d --- a/dmd/XorAssignExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/XorAssignExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -16,8 +16,12 @@ import dmd.backend.elem; import dmd.backend.OPER; +import dmd.DDMDExtensions; + class XorAssignExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register(); diff -r 1a0c1126bc46 -r b0d41ff5e0df dmd/XorExp.d --- a/dmd/XorExp.d Tue Jun 07 21:01:03 2011 -0400 +++ b/dmd/XorExp.d Tue Jun 07 23:37:34 2011 -0400 @@ -22,8 +22,12 @@ import dmd.expression.Util; import dmd.expression.Xor; +import dmd.DDMDExtensions; + class XorExp : BinExp { + mixin insertMemberExtension!(typeof(this)); + this(Loc loc, Expression e1, Expression e2) { register();