2 // Copyright (c) 1999-2006 by Digital Mars
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
10 /* NOTE: This file has been patched from the original DMD distribution to
11 work with the GDC compiler.
13 Modified by David Friedman, December 2006
24 /********************************* EnumDeclaration ****************************/
26 EnumDeclaration::EnumDeclaration(Loc loc
, Identifier
*id
, Type
*memtype
)
30 type
= new TypeEnum(this);
31 this->memtype
= memtype
;
39 Dsymbol
*EnumDeclaration::syntaxCopy(Dsymbol
*s
)
43 t
= memtype
->syntaxCopy();
47 { ed
= (EnumDeclaration
*)s
;
51 ed
= new EnumDeclaration(loc
, ident
, t
);
52 ScopeDsymbol::syntaxCopy(ed
);
56 void EnumDeclaration::semantic(Scope
*sc
)
62 //printf("EnumDeclaration::semantic(sd = %p, '%s')\n", sc->scopesym, sc->scopesym->toChars());
63 if (symtab
) // if already done
66 memtype
= Type::tint32
;
67 parent
= sc
->scopesym
;
69 attributes
->append(sc
->attributes
);
71 attributes
= sc
->attributes
;
72 memtype
= memtype
->semantic(loc
, sc
);
74 /* Check to see if memtype is forward referenced
76 if (memtype
->ty
== Tenum
)
77 { EnumDeclaration
*sym
= (EnumDeclaration
*)memtype
->toDsymbol(sc
);
80 error("base enum %s is forward referenced", sym
->toChars());
81 memtype
= Type::tint32
;
85 if (!memtype
->isintegral())
86 { error("base type must be of integral type, not %s", memtype
->toChars());
87 memtype
= Type::tint32
;
90 t
= isAnonymous() ? memtype
: type
;
91 symtab
= new DsymbolTable();
95 if (!members
) // enum ident;
97 if (members
->dim
== 0)
98 error("enum %s must have at least one member", toChars());
100 for (i
= 0; i
< members
->dim
; i
++)
102 EnumMember
*em
= ((Dsymbol
*)members
->data
[i
])->isEnumMember();
106 /* The e->semantic(sce) can insert other symbols, such as
107 * template instances and function literals.
111 //printf("Enum member '%s'\n",em->toChars());
115 assert(e
->dyncast() == DYNCAST_EXPRESSION
);
116 e
= e
->semantic(sce
);
117 e
= e
->optimize(WANTvalue
);
118 // Need to copy it because we're going to change the type
120 e
= e
->implicitCastTo(sc
, memtype
);
121 e
= e
->optimize(WANTvalue
);
122 number
= e
->toInteger();
126 { // Default is the previous number plus 1
128 // Check for overflow
131 switch (t
->toBasetype()->ty
)
134 if (number
== 2) goto Loverflow
;
138 if (number
== 128) goto Loverflow
;
143 if (number
== 256) goto Loverflow
;
147 if (number
== 0x8000) goto Loverflow
;
152 if (number
== 0x10000) goto Loverflow
;
156 if (number
== 0x80000000) goto Loverflow
;
161 if (number
== 0x100000000LL
) goto Loverflow
;
165 if (number
== 0x8000000000000000LL
) goto Loverflow
;
169 if (number
== 0) goto Loverflow
;
173 error("overflow of enum value");
180 e
= new IntegerExp(em
->loc
, number
, t
);
184 // Add to symbol table only after evaluating 'value'
187 //sce->enclosing->insert(em);
188 for (Scope
*scx
= sce
->enclosing
; scx
; scx
= scx
->enclosing
)
192 if (!scx
->scopesym
->symtab
)
193 scx
->scopesym
->symtab
= new DsymbolTable();
194 em
->addMember(sce
, scx
->scopesym
, 1);
200 em
->addMember(sc
, this, 1);
208 else if (memtype
->isunsigned())
217 if ((sinteger_t
)number
< (sinteger_t
)minval
)
219 if ((sinteger_t
)number
> (sinteger_t
)maxval
)
225 //printf("defaultval = %lld\n", defaultval);
231 int EnumDeclaration::oneMember(Dsymbol
**ps
)
234 return Dsymbol::oneMembers(members
, ps
);
235 return Dsymbol::oneMember(ps
);
238 void EnumDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
241 buf
->writestring("enum ");
243 { buf
->writestring(ident
->toChars());
248 buf
->writestring(": ");
249 memtype
->toCBuffer(buf
, NULL
, hgs
);
260 for (i
= 0; i
< members
->dim
; i
++)
262 EnumMember
*em
= ((Dsymbol
*)members
->data
[i
])->isEnumMember();
265 //buf->writestring(" ");
266 em
->toCBuffer(buf
, hgs
);
274 Type
*EnumDeclaration::getType()
279 char *EnumDeclaration::kind()
284 /********************************* EnumMember ****************************/
286 EnumMember::EnumMember(Loc loc
, Identifier
*id
, Expression
*value
)
293 Dsymbol
*EnumMember::syntaxCopy(Dsymbol
*s
)
295 Expression
*e
= NULL
;
297 e
= value
->syntaxCopy();
301 { em
= (EnumMember
*)s
;
306 em
= new EnumMember(loc
, ident
, e
);
310 void EnumMember::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
312 buf
->writestring(ident
->toChars());
315 buf
->writestring(" = ");
316 value
->toCBuffer(buf
, hgs
);
320 char *EnumMember::kind()
322 return "enum member";